I'm trying to get a user from the usermanger after External Login, using .Net-Core and IdentityServer4
public async Task<IActionResult> ExternalLoginCallback(string returnUrl = null, string remoteError = null)
{
if (remoteError != null)
{
ErrorMessage = $"Error from external provider: {remoteError}";
return RedirectToAction(nameof(Login));
}
var info = await _signInManager.GetExternalLoginInfoAsync();
if (info == null)
{
return RedirectToAction(nameof(Login));
}
// Sign in the user with this external login provider if the user already has a login.
var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false, bypassTwoFactor: true);
if (result.Succeeded)
{
var user = await _userManager.GetUserAsync(HttpContext.User);
var serviceProvider = HttpContext.RequestServices;
var context = serviceProvider.GetRequiredService<PublicAstootContext>();
var coinbaseRule = new CoinbaseRule();
await coinbaseRule.UpdateCoinbaseAccountInfo(context, user.Id, info);
//...
}
}
However, even after the login succeeds, when I attempt to get the user from the usermanger, the user is always null.
How can I get the user from the usermanger after my external login?
The call to ExternalLoginSignInAsync
does not populate HttpContext.User
- it ends up writing an authentication cookie that is read in subsequent requests when attempting to populate HttpContext.User
, but not before. In your example, the call to ExternalLoginSignInAsync
occurs within the same request as the call to GetUserAsync
, which means that HttpContext.User
will not represent an authenticated user and so no match will be found.
Instead, you can use UserManager.FindByLoginAsync
to get the correct value for user
:
var user = await _userManager.FindByLoginAsync(
info.LoginProvider, info.ProviderKey);