Answered by:
Accessing Enum Claim in Login.cshtml.cs page

Question
-
User1554758465 posted
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 { public class ApplicationUser : IdentityUser { public int StatusId { get; set; } public string StatusName { get; set; } public AccountStatusId AccountStatusId { get; set; } public AccountStatus AccountStatus { get; set; } } public enum AccountStatusId : int { Active = 0, InActive = 1, Expired = 2, Locked = 3 } public class AccountStatus { public AccountStatusId AccountStatusId { get; set; } public string Status { get; set; } public List<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 = new ApplicationUser { 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 { public class MyUserClaimsPrincipalFactory : UserClaimsPrincipalFactory<ApplicationUser> { public MyUserClaimsPrincipalFactory(UserManager<ApplicationUser> userManager, IOptions<IdentityOptions> optionsAccessor) : base(userManager, optionsAccessor) { } protected override async Task<ClaimsIdentity> GenerateClaimsAsync(ApplicationUser user) { var identity = await base.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 { public static class AddingEnumClaim { public static void AddEnumClaim<T>(this ClaimsIdentity identity, String type, T enumvalue) where T : struct { if (!typeof(T).IsEnum) throw new ArgumentException("AddEnumClaim must be an enum"); identity.AddClaim(new Claim(type, enumvalue.ToString())); } } }
Now all what i want is to chech the account status here in Login.cshtml.cs page, in OnPostAsync method.
public async Task<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: 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(); }
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
Monday, June 8, 2020 9:03 PM
Answers
-
User711641945 posted
Hi ShahadAlshuhail,
Check like below:
public async Task<IActionResult> OnPostAsync(string returnUrl = null) { returnUrl = returnUrl ?? Url.Content("~/"); if (ModelState.IsValid) { var user = _userManager.FindByEmailAsync(Input.Email).Result; if(user.AccountStatusId == AccountStatusId.Locked) { ModelState.AddModelError(string.Empty, "Waits for Approval"); return Page(); } if(user.AccountStatusId == AccountStatusId.Active) { var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: true); 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(); } } // This doesn't count login failures towards account lockout // To enable password failures to trigger account lockout, set lockoutOnFailure: true } // If we got this far, something failed, redisplay form return Page(); }
Best Regards,
Rena
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Tuesday, June 9, 2020 9:30 AM
All replies
-
User711641945 posted
Hi ShahadAlshuhail,
Check like below:
public async Task<IActionResult> OnPostAsync(string returnUrl = null) { returnUrl = returnUrl ?? Url.Content("~/"); if (ModelState.IsValid) { var user = _userManager.FindByEmailAsync(Input.Email).Result; if(user.AccountStatusId == AccountStatusId.Locked) { ModelState.AddModelError(string.Empty, "Waits for Approval"); return Page(); } if(user.AccountStatusId == AccountStatusId.Active) { var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: true); 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(); } } // This doesn't count login failures towards account lockout // To enable password failures to trigger account lockout, set lockoutOnFailure: true } // If we got this far, something failed, redisplay form return Page(); }
Best Regards,
Rena
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Tuesday, June 9, 2020 9:30 AM -
User1554758465 posted
Thank you so much !
Tuesday, June 9, 2020 9:39 PM