I am using ASP.NET MVC 5.1 with Owin and Claims authentication.
After the user changes its email I need to update the users claims, so I tried in the controller:
ClaimsIdentity identity = (ClaimsIdentity)User.Identity;
Claim claim = identity.FindFirst(ClaimTypes.Email);
identity.RemoveClaim(claim);
identity.AddClaim(new Claim(ClaimTypes.Email, newEmail));
IOwinContext context = new OwinContext();
context.Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie);
context.Authentication.SignIn(identity);
The Claim is changed but when I refresh the page the email claims is the original again ...
It seems the cookie is not being updated. Any idea what I am doing wrong?
And is it possible to get the value of "IsPersistent" from the identity so when I sign it again I will have the same value?
Thank You,
Miguel
I had this same problem, so just wanted to summarise my findings here. As Chris says, the basis of the answer is indeed here: How to change authentication cookies after changing UserName of current user with asp.net identity but I found that thread a bit hard to follow, and that question isn't really a direct duplicate.
To begin, get the AuthenticationManager from the current OWIN context. Once you have that, you can get the value of "isPersistent" (and other properties from the original SignIn
call), by calling the AuthenticateAsync
method. Then to update the claims of the current user identity you just need to replace the value of the AuthenticationResponseGrant
property like this:
var identity = (ClaimsIdentity)User.Identity;
// Call AddClaim, AddClaims or RemoveClaim on the user identity.
IOwinContext context = Request.GetOwinContext();
var authenticationContext =
await context.Authentication.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie);
if (authenticationContext != null)
{
authenticationManager.AuthenticationResponseGrant = new AuthenticationResponseGrant(
identity,
authenticationContext.Properties);
}
It is the final setting of the AuthenticationResponseGrant
property that actually updates the cookie.
Hope this helps other readers.
SORRY, this is an ASP.NET CORE solution I also challenged the problem with claims, but the answer was easy to find.
To refresh your cookie, you can rely on the RefreshSignInAsync() function of the SignInManager;
private readonly UserManager<ApplicationUser> _userManager;
private readonly ApplicationDbContext _context;
private readonly SignInManager<ApplicationUser> _signInManager;
public ApiClubController(UserManager<ApplicationUser> userManager, SignInManager<ApplicationUser> signInManager, ApplicationDbContext context)
{
_userManager = userManager;
_context = context;
_signInManager = signInManager;
}
Inside your function:
//GET CURRENT USER
var usr = await GetCurrentUserAsync();
//OLD CLAIM
var myClaims = await _userManager.GetClaimsAsync(usr);
var oldClaim = myClaims.Where(o => o.Type.Equals("Club")).FirstOrDefault();
if (oldClaim != null)
{
await _userManager.RemoveClaimAsync(usr, oldClaim);
}
//CREATE CLUB CLAIM
var clubClaim = new Claim("Club", "" + id);
await _userManager.AddClaimAsync(usr, clubClaim);
//RESET USER COOKIE
await _signInManager.RefreshSignInAsync(usr);
//RETURN
return Ok(company);;
NOTE: I'm using an API here, because I'm mixing up a lot with angular. If you update your identity with your API, you need to refresh your page in order to view things based on your claim
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With