Search code examples
c#asp.net-coreasp.net-core-identity

Get User From Usermanger After Login


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?


Solution

  • 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);