ASP .Net Core 5.0 Database first EF Im using Identity (Assembly Microsoft.Extensions.Identity.Stores, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
I have the following class Im using
public class ApplicationUser : IdentityUser
{
public override string Id { get; set; }
public override string UserName { get; set; } = "";
public string? Organization { get; set; }
public override string Email { get; set; } = "";
public override string PasswordHash { get; set; } = "";
public DateTime LastUpdateDate { get; set; }
public override bool EmailConfirmed { get; set; }
public byte[] UserAvatar { get; set; }
public override string NormalizedUserName { get; set; }
public override string NormalizedEmail { get; set; }
public override bool LockoutEnabled { get; set; }
public override int AccessFailedCount { get; set; }
public override string? PhoneNumber { get; set; }
public override string? ConcurrencyStamp { get; set; }
public override string? SecurityStamp { get; set; }
public override DateTimeOffset? LockoutEnd { get; set; }
public override bool TwoFactorEnabled { get; set; }
public override bool PhoneNumberConfirmed { get; set; }
//public SimpleUser ThisUser { get; set; } = new SimpleUser();
}
My startup code here :
services.AddDefaultIdentity<ApplicationUser>(options => {
options.SignIn.RequireConfirmedEmail = false;
options.SignIn.RequireConfirmedAccount = false;
options.SignIn.RequireConfirmedPhoneNumber = false;
}).AddEntityFrameworkStores<TwisterDBContext>().AddDefaultTokenProviders();
My code from OnPostAsync (which was created using scafolding)
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
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
ApplicationUser thisUser = await GetThisUserById(Input.Email);
string hashPassword = EncryptPassword.HashPassword(Input.Password, thisUser.SecurityStamp);
var result = await _signInManager.PasswordSignInAsync(thisUser, hashPassword, 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();
}
Im using email id as username. Ensured Normalized username and email are set properly in the GetThisUserById function (my custom function to get the record from DB) I confirmed the hashed password both are matching. EmailConfirmed is set as true in the DB and coming in as true in the ThisUser record.
Yet, I keep getting Succeeded = false. I definitely sure Im not setting some flag somewhere...
Finally here is the screenshot of the Watch window.
CodePudding user response:
Overriding SigninManager and UserManager is a lot of work. There are so many things that needs to be implemented for it to work.
I tucked my tail and went back to default calls and with the AspNet*** tables in place, I got the data seeded and login works like a charm.