How to update a claim in ASP.NET Identity?
asp.net, asp.net-mvc, asp.net-mvc-4, asp.net-web-api, c#
Solution
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);
// ?. prevents a exception if claim is null.
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");
}
}
}
Problem
I'm using OWIN authentication for my MVC5 project. This is my `SignInAsync` ``` private async Task SignInAsync(ApplicationUser user, bool isPersistent) { var AccountNo = "101"; AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie); var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie); identity.AddClaim(new Claim(ClaimTypes.UserData, AccountNo)); AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent, RedirectUri="Account/Index"}, identity); } ``` As you can see, i added `AccountNo` into the Claims list. Now, how can I update this Claim at some point in my application? So far, i have this: ``` public string AccountNo { get { var CP = ClaimsPrincipal.Current.Identities.First(); var Account= CP.Claims.FirstOrDefault(p => p.Type == ClaimTypes.UserData); return Account.Value; } set { var CP = ClaimsPrincipal.Current.Identities.First(); var AccountNo= CP.Claims.FirstOrDefault(p => p.Type == ClaimTypes.UserData).Value; CP.RemoveClaim(new Claim(ClaimTypes.UserData,AccountNo)); CP.AddClaim(new Claim(ClaimTypes.UserData, value)); } } ``` when i try to remove the claim, I get this exception: The Claim 'http://schemas.microsoft.com/ws/2008/06/identity/claims/userdata: 101' was not able to be removed. It is either not part of this Identity or it is a claim that is owned by the Principal that contains this Identity. For example, the Principal will own the claim when creating a GenericPrincipal with roles. The roles will be exposed through the Identity that is passed in the constructor, but not actually owned by the Identity. Similar logic exists for a RolePrincipal. How does one remove and update the Claim?