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.
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.
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.