Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to update a claim in ASP.NET Identity?

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?

like image 800
Irshu Avatar asked Jul 05 '14 14:07

Irshu


People also ask

What are claims in asp net core identity?

Claims can be created from any user or identity data which can be issued using a trusted identity provider or ASP.NET Core identity. A claim is a name value pair that represents what the subject is, not what the subject can do.

How do I apply a claim in .NET core?

Adding claims checks Claim based authorization checks are declarative - the developer embeds them within their code, against a controller or an action within a controller, specifying claims which the current user must possess, and optionally the value the claim must hold to access the requested resource.


2 Answers

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");                   }     } } 
like image 124
Frank Fu Avatar answered Sep 29 '22 00:09

Frank Fu


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 }         ); } 
like image 43
Irshu Avatar answered Sep 28 '22 22:09

Irshu