13

I have a Web Application in MVC 6 (Asp.Net One Core), and I'm using Claims based authentication. In the Login method I set the Claims:

var claims = new Claim[]
{
    new Claim("Name", content.Name),
    new Claim("Email", content.Email),
    new Claim("RoleId", content.RoleId.ToString()),
};

var ci = new ClaimsIdentity(claims, "password");
await HttpContext.Authentication.SignInAsync("Cookies", new ClaimsPrincipal(ci));

Now, if the user for example changes the email in the user profile, how can I change the e-mail value for the "Email" Claim? I have to SignOutAsync and SignInAsync again in order to update the cookie? The best solution is to save this into a classic session? There is a better solution? I'm totally wrong?

Any suggestions?

Martín
  • 2,985
  • 7
  • 24
  • 40

2 Answers2

29

Another option, instead of SignOutAsync and SignInAsync, is to use RefreshSignInAsync.

Example:

var user = await _userManager.FindByIdAsync(yourId);
await _signInManager.RefreshSignInAsync(user);

View the RefreshSignInAsync code in the SignInManager (netcore 3.1.8): https://github.com/dotnet/aspnetcore/blob/c75b3f7a2fb9fe21fd96c93c070fdfa88a2fbe97/src/Identity/Core/src/SignInManager.cs#L169

Alex
  • 727
  • 1
  • 7
  • 16
  • 1
    can this method be used to refresh a different user's claims? – liang Apr 03 '18 at 10:30
  • How can I access SignInManager object if i haven't add identity as it is not necessary for me? – DSA Apr 16 '18 at 13:53
  • @DSA you don't. The SignInManager is part of Identity. – Alex Apr 26 '18 at 00:25
  • @liang Seemingly not, [as it causes the currently logged in user to become logged in as that 'different' user](https://stackoverflow.com/q/51571852/590790). – Steven Jeuris Jul 30 '18 at 12:11
  • How do you refresh a `different` user's claim then? – liang Jul 10 '19 at 07:39
  • I saw it, it didn't answer the question. As in it didn't answer how to refresh a different user's claim. While this is probably a different question than the original, should probably start a new thread – liang Jul 10 '19 at 08:50
  • 1
    You cannot force a refresh of a different users claim. – Alex Jul 10 '19 at 14:41
6

I have to SignOutAsync and SignInAsync again in order to update the cookie?

Answer is yes.

Easiest way is you can manually sign-out and sign-in (create claims again) inside the same action method where you are updating the email.

The best solution is to save this into a classic session?

I suggest not to do that. Using session state explicitly is a bad practice in ASP.Net MVC.

Win
  • 56,078
  • 13
  • 92
  • 167
  • 1
    If I sign-out and sign-in again in order to create the claims again, the information is available in the moment or the page must be refreshed in order to update the cookie or something like that? – Martín Aug 18 '16 at 20:51
  • Old information is still attached to **Principal** object, so you do not want to perform additional process using Principal in the same request. – Win Aug 18 '16 at 20:54
  • 1
    Adding this here in case anyone runs into this: In my case I wanted to use the new claim information immediately in the same request. In order to do this, I call _userManager.GetClaimsAsync() for that user instead of reading the claims in the Principal object. The claims there are the old ones. Calling GetClaimsAsync() will give you the new ones you just set. So basically you need to 1) Call RefreshSignInAsync, 2) Call GetClaimsAsync if you want to work with the new claims immediately. – Andrew Oct 02 '18 at 03:19