I'm developing a web application with ASP.Net Core MVC and identity. I extend the identity table as following with Enum field type "AccountStatusId" as following:
ApplicationUser.cs
namespace RegisterTest.Models{publicclassApplicationUser:IdentityUser{publicintStatusId{get;set;}publicstringStatusName{get;set;}publicAccountStatusIdAccountStatusId{get;set;}publicAccountStatusAccountStatus{get;set;}}publicenumAccountStatusId:int{Active=0,InActive=1,Expired=2,Locked=3}publicclassAccountStatus{publicAccountStatusIdAccountStatusId{get;set;}publicstringStatus{get;set;}publicList<ApplicationUser>Statuses{get;set;}}}
and to make sure that the account is locked after successful registration i make the AccountStatusId is locked by default in Register.cshtml.cs
var user =newApplicationUser{UserName=Input.Email,Email=Input.Email,AccountStatusId=AccountStatusId.Locked};
And i did all needed configuration in OnModelCreating method in ApplicationDbContext
Now, I want to check the "AccountStatus" field but in the Login.cshtml.cs. So, if the user who trying to log in with (AccountStatus.Locked) value -> display a message "Waiting for approval".
if the value (AccountStatus.Active) -> Successful Login.
After long search, I think i have to use claim in this situation. So, I come up with the following: 1) Creating customize claim: MyUserClaimsPrincipalFactory.cs
namespace RegisterTest.Controllers{publicclassMyUserClaimsPrincipalFactory:UserClaimsPrincipalFactory<ApplicationUser>{publicMyUserClaimsPrincipalFactory(UserManager<ApplicationUser> userManager,IOptions<IdentityOptions> optionsAccessor):base(userManager, optionsAccessor){}protectedoverrideasyncTask<ClaimsIdentity>GenerateClaimsAsync(ApplicationUser user){var identity =awaitbase.GenerateClaimsAsync(user);
identity.AddEnumClaim("AccountStatus",AccountStatusId.Locked);return identity;}}}
2) Creating AddingEnumClaim class since AddClaim method just accept the string and i need it as Enum.
AddEnumClaim.cs
namespace RegisterTest.Controllers{publicstaticclassAddingEnumClaim{publicstaticvoidAddEnumClaim<T>(thisClaimsIdentity identity,String type, T enumvalue)where T :struct{if(!typeof(T).IsEnum)thrownewArgumentException("AddEnumClaim must be an enum");
identity.AddClaim(newClaim(type, enumvalue.ToString()));}}}
Now all what i want is to chech the account status here in Login.cshtml.cs page, in OnPostAsync method.
publicasyncTask<IActionResult>OnPostAsync(string returnUrl =null){
returnUrl = returnUrl ??Url.Content("~/");if(ModelState.IsValid){// This doesn't count login failures towards account lockout// To enable password failures to trigger account lockout, set lockoutOnFailure: truevar result =await _signInManager.PasswordSignInAsync(Input.Email,Input.Password,Input.RememberMe, lockoutOnFailure:false);if(result.Succeeded){
_logger.LogInformation("User logged in.");returnLocalRedirect(returnUrl);}if(result.RequiresTwoFactor){returnRedirectToPage("./LoginWith2fa",new{ReturnUrl= returnUrl,RememberMe=Input.RememberMe});}if(result.IsLockedOut){
_logger.LogWarning("User account locked out.");returnRedirectToPage("./Lockout");}else{ModelState.AddModelError(string.Empty,"Invalid login attempt.");returnPage();}}// If we got this far, something failed, redisplay formreturnPage();}
Am i in the right track or i miss understanding something? Where i can exactly check the AccountStatus for a user while logging ?
Any help is appreciated