How to update a claim in ASP.NET Identity?
I created a Extension method to Add/Update/Read Claims based on a given ClaimsIdentity
namespace Foobar.Common.Extensions{ public static class Extensions { public static void AddUpdateClaim(this IPrincipal currentPrincipal, string key, string value) { var identity = currentPrincipal.Identity as ClaimsIdentity; if (identity == null) return; // check for existing claim and remove it var existingClaim = identity.FindFirst(key); if (existingClaim != null) identity.RemoveClaim(existingClaim); // add new claim identity.AddClaim(new Claim(key, value)); var authenticationManager = HttpContext.Current.GetOwinContext().Authentication; authenticationManager.AuthenticationResponseGrant = new AuthenticationResponseGrant(new ClaimsPrincipal(identity), new AuthenticationProperties() { IsPersistent = true }); } public static string GetClaimValue(this IPrincipal currentPrincipal, string key) { var identity = currentPrincipal.Identity as ClaimsIdentity; if (identity == null) return null; var claim = identity.Claims.FirstOrDefault(c => c.Type == key); return claim.Value; } }}
and then to use it
using Foobar.Common.Extensions;namespace Foobar.Web.Main.Controllers{ public class HomeController : Controller { public ActionResult Index() { // add/updating claims User.AddUpdateClaim("key1", "value1"); User.AddUpdateClaim("key2", "value2"); User.AddUpdateClaim("key3", "value3"); } public ActionResult Details() { // reading a claim var key2 = User.GetClaimValue("key2"); } }}
You can create a new ClaimsIdentity
and then do the claims update with such.
set { // get context of the authentication manager var authenticationManager = HttpContext.GetOwinContext().Authentication; // create a new identity from the old one var identity = new ClaimsIdentity(User.Identity); // update claim value identity.RemoveClaim(identity.FindFirst("AccountNo")); identity.AddClaim(new Claim("AccountNo", value)); // tell the authentication manager to use this new identity authenticationManager.AuthenticationResponseGrant = new AuthenticationResponseGrant( new ClaimsPrincipal(identity), new AuthenticationProperties { IsPersistent = true } );}
Another (async) approach, using Identity's UserManager and SigninManager to reflect the change in the Identity cookie (and to optionally remove claims from db table AspNetUserClaims):
// Get User and a claims-based identityApplicationUser user = await UserManager.FindByIdAsync(User.Identity.GetUserId());var Identity = new ClaimsIdentity(User.Identity);// Remove existing claim and replace with a new valueawait UserManager.RemoveClaimAsync(user.Id, Identity.FindFirst("AccountNo"));await UserManager.AddClaimAsync(user.Id, new Claim("AccountNo", value));// Re-Signin User to reflect the change in the Identity cookieawait SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);// [optional] remove claims from claims table dbo.AspNetUserClaims, if not neededvar userClaims = UserManager.GetClaims(user.Id);if (userClaims.Any()){ foreach (var item in userClaims) { UserManager.RemoveClaim(user.Id, item); }}