Search code examples
c#asp.net-coreasp.net-identityopenid-connect

.Net Core Identity User not populated when using OpenIdConnect


I'm implementing OpenIdConnect into a .Net Core app, which associates an external login with a user stored in an internal (default Identity) database, and attempts to log in. The log in method reports success, but the User object isn't populated. The login process was scaffolded in, so it's all boilerplate, including the external login process.

I'd appreciate any help in understanding what I'm doing wrong.

log in succeeded

user not populated

services.AddAuthentication(options =>
        {
            options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
            options.DefaultAuthenticateScheme = "oidc";
            options.DefaultSignInScheme = IdentityConstants.ExternalScheme;
        })
            .AddCookie()
            .AddOpenIdConnect(options =>
            {
                options.Authority = oauthSettings.Location.AbsoluteUri;
                options.RequireHttpsMetadata = false;
                options.ClientId = oauthSettings.ClientID;
                options.ClientSecret = oauthSettings.ClientSecret;
                options.ResponseType = "id_token token";

                options.Scope.Add("openid");
                options.Scope.Add("profile");
                options.Scope.Add("email");
            });

//In Login.cshtml.cs
 public async Task<IActionResult> OnPostAsync(string returnUrl = null)
    {
        returnUrl = returnUrl ?? Url.Content("~/");

        ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();

        if (ModelState.IsValid)
        {
            // This doesn't count login failures towards account lockout
            // To enable password failures to trigger account lockout, set lockoutOnFailure: true
            var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: false);
            if (result.Succeeded)
            {
                _logger.LogInformation("User logged in.");
                return LocalRedirect(returnUrl);
            }
            if (result.RequiresTwoFactor)
            {
                return RedirectToPage("./LoginWith2fa", new { ReturnUrl = returnUrl, RememberMe = Input.RememberMe });
            }
            if (result.IsLockedOut)
            {
                _logger.LogWarning("User account locked out.");
                return RedirectToPage("./Lockout");
            }
            else
            {
                ModelState.AddModelError(string.Empty, "Invalid login attempt.");
                return Page();
            }
        }

        // If we got this far, something failed, redisplay form
        return Page();
    }

EDIT: I've found that when I remove the AddAuthentication method in Startup the login works, but obviously that disabled the external auth. Something about adding OpenIdConnect is breaking the login process.


Solution

  • To fix this I did the following in the startup:

    services.AddAuthentication(options =>
        {
            options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
            options.DefaultAuthenticateScheme = "oidc";
            options.DefaultSignInScheme = IdentityConstants.ExternalScheme;
        })
            .AddCookie()
            .AddOpenIdConnect(options =>
            {
                options.Authority = oauthSettings.Location.AbsoluteUri;
                options.RequireHttpsMetadata = false;
                options.ClientId = oauthSettings.ClientID;
                options.ClientSecret = oauthSettings.ClientSecret;
                options.ResponseType = "id_token token";
    
                options.Scope.Add("openid");
                options.Scope.Add("profile");
                options.Scope.Add("email");
            });
    

    So I left it to its defaults and it worked. I'm not 100% why.