Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Identity cookie loses custom claim information after a period of time

I am storing custom claims, such as the user's real name, in the ASP.NET Identity cookie to avoid unnecessary database queries on every request. At least that's what I assume this code is doing:

var identity = await user.GenerateUserIdentityAsync(UserManager);
identity.AddClaim(new Claim(ClaimTypes.GivenName, user.FirstName)));
// etc.
AuthenticationManager.SignIn(new AuthenticationProperties {IsPersistent=true}, identity);

This works fine, and I can retrieve these claims with:

private static string GetClaim(string claimType)
{
  var identity = (ClaimsPrincipal) Thread.CurrentPrincipal;
  var claim = identity.Claims.SingleOrDefault(o => o.Type == claimType);
  return claim == null ? null : claim.Value;
}

The identity.Claims property contains the following claims, as expected:

http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier: ced2d16c-cb6c-4af0-ad5a-09df14dc8207
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name: [email protected]
http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider: ASP.NET Identity
AspNet.Identity.SecurityStamp: 284c648c-9cc7-4321-b0ce-8a347cd5bcbf
http://schemas.microsoft.com/ws/2008/06/identity/claims/role: Admin
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname: My Name

The trouble is that after some time (usually several hours), my custom claims seem to disappear - in this example, givenname no longer exists in the enumeration. The user is still authenticated, and all the default claims are still there.

What's going on, and how can I fix this? The only thing I can think of is that the cookie is expiring and being re-issued behind the scenes, but I don't know why (or if) that would happen.

like image 794
James Avatar asked May 13 '14 02:05

James


People also ask

Can I store a claim as persistent in the cookie?

You can even easily define your own claims, and the default implementation will automatically store this information in the cookie as well, allowing you to access it in every request. However, sometimes you don't want to store a claim as persistent in the database, but still attach some information to a login sessions or context.

How does a cookie affect the session lifetime?

I could think of three different places where the cookie could affect the session lifetime: The expiration time of the access token, which is received from Identity Server and stored somewhere inside the payload of the cookie. The time that specifies how long the browser will keep the cookie.

What is the expiration time of a cookie?

The expiration time of the access token, which is received from Identity Server and stored somewhere inside the payload of the cookie. The time that specifies how long the browser will keep the cookie. The time that specifies how long the authentication ticket that is stored inside the cookie is valid. The first one is related to the tokens.

What information is stored in the cookie?

It also stores a few claims (pieces of information about the logged in user) directly in the cookie, such as the username or roles. You can even easily define your own claims, and the default implementation will automatically store this information in the cookie as well, allowing you to access it in every request.


1 Answers

Yes, the issue is most likely the cookie getting expired. Since you didn't add the custom claims to the user's claims in the database, they are lost on refresh since you aren't adding the claim inside the method being called. You can either add the claim via:

userManager.AddClaim(user.Id, new Claim(ClaimTypes.GivenName, user.FirstName));

or you can move this inside of the method that's called when the cookie is regenerated (by default its user.GenerateUserIdentityAsync).

        app.UseCookieAuthentication(new CookieAuthenticationOptions {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/Account/Login"),
            Provider = new CookieAuthenticationProvider {
                // Enables the application to validate the security stamp when the user logs in.
                // This is a security feature which is used when you change a password or add an external login to your account.  
                OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
                    validateInterval: TimeSpan.FromMinutes(30),
                    regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
            }
        });
like image 145
Hao Kung Avatar answered Oct 22 '22 18:10

Hao Kung