How do I cancel a claim using an ASP.NET identifier?

I just upgraded some of my applications to ASP.NET MVC 5. I have been using ASP.NET membership for ages and have been exploring the possibility of switching to an ASP.NET identifier.

I am creating a small test application and I have work with authentication (against the active directory and a special SQL Server schema depending on the user) and even authorization by adding role requests to ClaimsIdentity before signing the user in (apparently, the Authorize attribute not true).

It's cool that claims are stored in the authentication cookie by default. However, this creates a problem when the user information has changed (i.e., they have been added or removed from the role).

Obviously, I can collapse my own Authorize attribute, as I always did before. If I do this, I would simply skip all the applications and simply check the database roles for each request.

Is there a way to use claims in Identity ASP.NET and know when they are no longer valid? Does the infrastructure provide any solutions to this problem?

+10
asp.net-mvc asp.net-mvc-5 claims-based-identity asp.net-identity
source share
2 answers

You probably want to look at this question / answer, how can this be taken care of automatically:

What is SecurityStamp used for?

+3
source share

I recently implemented a feature set based on claims in a project. I found that Identity does not provide a mechanism for physically updating a user’s claim. With this method, MS gives the impression that you must delete the application from the user, so that when he gets access to the attributes of user authorization, he sees that the user does not have the application, and therefore it will not pass.

I had to create a separate Base Claims utility with views and a Controller to manage my user statements. For example, when I create a new user, I assign him various requirements. I also have an extended or custom Identity Manager class that I interact with to manage user requests, passwords, account lockout, adding new roles, and removing roles.

For presentation, I created custom HTML.Helper extension methods to help verify what the user has access to or not.

Some code examples are given below.

Identity Manager Class

 public class IdentityManager { private RoleManager<IdentityRole> _roleManager; private UserManager<ApplicationUser> _userManager; private ApplicationDbContext _dbContext; private ApplicationSignInManager _signInManager; private DpapiDataProtectionProvider protectionProvider; public IdentityManager() { _dbContext = new ApplicationDbContext(); _roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(_dbContext)); _userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(_dbContext)); protectionProvider = new DpapiDataProtectionProvider("Demo"); _userManager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(protectionProvider.Create("ResetTokens")); } public IdentityManager(ApplicationSignInManager signmanager) { _dbContext = new ApplicationDbContext(); _signInManager = signmanager; _roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(_dbContext)); _userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(_dbContext)); protectionProvider = new DpapiDataProtectionProvider("Demo"); _userManager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(protectionProvider.Create("ResetTokens")); } public ApplicationSignInManager SignInManager { get { return _signInManager; } private set { _signInManager = value; } } public bool CreateNewUserRole(string role) { if (!RoleExist(role)) { var result = _roleManager.Create(new IdentityRole(role)); return result.Succeeded; } return false; } public bool DeleteUserRole(string role) { if (!RoleExist(role)) return true; var result = _roleManager.Delete(new IdentityRole(role)); return result.Succeeded; } public IdentityResult DeleteMemberShipUser(ApplicationUser user) { return _userManager.Delete(user); } public bool DeleteAllUtilityUsers(int utilityid) { try { var users = _dbContext.Users.Where(u => u.UtilityId == utilityid).ToList(); foreach (var user in users) { DeleteMemberShipUser(user); } } catch (Exception) { return false; } return true; } public bool RoleExist(string role) { return _roleManager.RoleExists(role); } public IdentityResult ChangePassword(ApplicationUser user, string token, string newpassword) { _userManager.UserValidator = new UserValidator<ApplicationUser>(_userManager) { AllowOnlyAlphanumericUserNames = false, RequireUniqueEmail = true }; return _userManager.ResetPassword(user.Id, token, newpassword); } public ApplicationUser GetUserByIdentityUserId(string userId) { return _userManager.FindById(userId); } public IdentityResult CreateNewUser(ApplicationUser user, string password) { _userManager.UserValidator = new UserValidator<ApplicationUser>(_userManager) { AllowOnlyAlphanumericUserNames = false, RequireUniqueEmail = true }; _userManager.PasswordValidator = new PasswordValidator { RequiredLength = 6, RequireNonLetterOrDigit = false, RequireDigit = false, RequireLowercase = false, RequireUppercase = false, }; // Configure user lockout defaults _userManager.UserLockoutEnabledByDefault = false; _userManager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5); _userManager.MaxFailedAccessAttemptsBeforeLockout = 5; var result = _userManager.Create(user, password); return result; } public IdentityResult UpdateUser(ApplicationUser user) { return _userManager.Update(user); } public bool AddUserToRole(string userId, string roleName) { var result = _userManager.AddToRole(userId, roleName); return result.Succeeded; } public bool RemoveUserFromRole(string userId, string role) { var result = _userManager.RemoveFromRole(userId, role); return result.Succeeded; } public IList<string> GetUserRoles(string userid) { return _userManager.GetRoles(userid); } public string GetUserRole(string userid) { return _userManager.GetRoles(userid).FirstOrDefault(); } public IdentityRole GetRoleByRoleName(string roleName) { return _roleManager.Roles.First(i => i.Name == roleName); } public string GetUserRoleId(string userId) { var userRole = GetUserRole(userId); if (string.IsNullOrWhiteSpace(userRole)) return null; var role = GetRoleByRoleName(userRole); return role.Id; } public IdentityResult CreateNewSystemRole(IdentityRole role) { return !RoleExist(role.Name) ? _roleManager.Create(role) : new IdentityResult(new List<string> { "Role Already Exists" }); } public List<IdentityRole> GetAllRoles() { return _roleManager.Roles.ToList(); } public bool IsUserInRole(string role, string userName) { var user = _userManager.FindByName(userName); return _userManager.IsInRole(user.Id, role); } public ApplicationUser GetUserByUserName(string username) { return _userManager.FindByName(username); } public string GenerateResetToken(string userid) { return _userManager.GeneratePasswordResetToken(userid); } public IdentityResult SetLockStatus(string userid, bool lockstatus) { return _userManager.SetLockoutEnabled(userid, lockstatus); } public IdentityResult AddUserClaim(string userId, Claim claim) { return _userManager.AddClaim(userId, claim); } public void AddRoleClaim(string roleId, string claimType, string claimValue, int utilityid, string description) { try { _userManager.UserValidator = new UserValidator<ApplicationUser>(_userManager) { AllowOnlyAlphanumericUserNames = false, RequireUniqueEmail = true }; var roleClaim = new AspNetRoleClaims() { RoleId = roleId, ClaimType = claimType, ClaimValue = claimValue, UtilityId = utilityid, Description = description }; _dbContext.AspNetRoleClaims.Add(roleClaim); _dbContext.SaveChanges(); } catch (Exception ex) { throw new IdentityNotMappedException(ex.Message, ex); } } public IList<Claim> GetUserClaims(string userId) { return _userManager.GetClaims(userId); } public IdentityResult RemoveUserClaim(string userId, string claimType) { _userManager.UserValidator = new UserValidator<ApplicationUser>(_userManager) { AllowOnlyAlphanumericUserNames = false, RequireUniqueEmail = true }; var claim = _userManager.GetClaims(userId).FirstOrDefault(t => t.Type == claimType); if (claim == null) return IdentityResult.Success; return _userManager.RemoveClaim(userId, claim); } public void DeleteRole(string id) { var language = new LanguageCodeLookup(); var aspNetRoles = _dbContext.Roles.FirstOrDefault(r => r.Id == id); if (aspNetRoles == null) throw new Exception(language.RoleDoesNotExist); if (aspNetRoles.Name == "Utility Administrator" || aspNetRoles.Name == "Content Manager" || aspNetRoles.Name == "System Administrator" || aspNetRoles.Name == "Customer Accounts Manager") throw new Exception(language.CannotDeleteDefaultRoles); if (aspNetRoles.Users.Count > 0) throw new Exception(language.CannotDeleteRolesWithUsers); _dbContext.Roles.Remove(aspNetRoles); _dbContext.SaveChanges(); } public IdentityRole GetRole(string id) { return _dbContext.Roles.FirstOrDefault(r => r.Id == id); } } 

User statements Authorize Attribute

 public class ClaimsAuthorizeAttribute : AuthorizeAttribute { private readonly string _claimType; public ClaimsAuthorizeAttribute(string type) { _claimType = type; } public override void OnAuthorization(AuthorizationContext filterContext) { var user = (ClaimsPrincipal)HttpContext.Current.User; if (user.HasClaim(_claimType, "True")) { base.OnAuthorization(filterContext); } else { HandleUnauthorizedRequest(filterContext, _claimType + " Not Allowed "); } } protected void HandleUnauthorizedRequest(AuthorizationContext filterContext, string message) { filterContext.Result = new RedirectToRouteResult( new RouteValueDictionary { { "action", "ClaimNotAuthorized" }, { "controller", "Home" }, {"errorMessage", message } }); } public static bool AuthorizedFor(string claimType) { var user = (ClaimsPrincipal)HttpContext.Current.User; return user.HasClaim(claimType, "True"); } } 

Application for use

 [ClaimsAuthorize(ClaimsData.EditCustomer)] public ActionResult Index(string customerNo = "", int filterID = 0, int filterStatusID = 0) 

View razor usage

 public static bool AuthorizedFor(this HtmlHelper htmlHelper, string claimType) { if (!string.IsNullOrEmpty(claimType)) { var user = (ClaimsPrincipal)System.Web.HttpContext.Current.User; return user.HasClaim(claimType, "True"); } return false; } 

HTML string rendering if claims passed

 public static MvcHtmlString RenderToastrHiddenInputs(this HtmlHelper htmlHelper, object success, object info, object warning, object error, string claimType) { if (AuthorizedFor(htmlHelper, claimType)) { var html = string.Format(@" <input type='hidden' id='success' value='{0}' /> <input type='hidden' id='info' value='{1}' /> <input type='hidden' id='warning' value='{2}' /> <input type='hidden' id='error' value='{3}' />", success, info, warning, error); return new MvcHtmlString(html); } return null; } 

Hope all this makes sense :)

0
source share

All Articles