Search code examples
asp.net-mvcasp.net-mvc-4claims-based-identityasp.net-identity-2

Invalidate ClaimsPrincipal after it has been modified


I am using ASP.NET MVC, Identity2.

I have added "FirstName" Custom ClaimPrincipal:

public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser, long> manager)
{
    var userIdentity = await manager.CreateIdentityAsync(
                           this,
                           DefaultAuthenticationTypes.ApplicationCookie);

    // Add custom user claims here
    userIdentity.AddClaim(new Claim("FirstName", FirstName));

    return userIdentity;
}

If I update the value of "FirstName", I need to logout and log back in, for the "FirstName" Claim to be updated. Is it possible to invalidate "FirstName" Claim, so it's value is forced to be refreshed?


I have seen this question, which shows how to update the value of Claims, I was wondering if there is easier way to just invalidate them.


Solution

  • When looking at MS built-in template, I noticed that they alway makes a call to SignInManager.SignInAsync, after changing user credentials (e.g. password, 2 Factor Authentication, etc).

    I also noticed that the Claims are updated once the user logs out and logs back in... so after changing "FirstName" which is stored in a Claim, I called SignInManager.SignInAsync to re-signin the User... this way, the Claims are updated:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> UpdateFirstName(string firstName)
    {
        var user = await UserManager.FindByIdAsync(User.Identity.GetUserId<long>());
        user.FirstName = firstName;
    
        // update FirstName which is stored in a Claim
        var result = await UserManager.UpdateAsync(user);
    
        if (result.Succeeded)
        {
            // re-signin the user, to refresh the Claims
            await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
    
            // you need to redirect after calling SignInAsync, so claims are refreshed
            return RedirectToAction("Index"); 
        }
    
        // add some error message...
        return View();
    }
    

    Note: As shown in the question, I am storing the Claims in Cookie.