Search code examples
asp.netasp.net-mvcclaims-based-identityasp.net-identity-2

Asp.net MVC when to reload claims when lost


I have added a few custom claims when logging in.

private async Task SignInAsync(ApplicationUser user, bool isPersistent)
{
    AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
    var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
        var accesses = _roleAccessRepository.GetAssignedAccess(roleId);
        foreach (var access in accesses)
        {
           identity.AddClaim(new Claim("AccessCode", access));
        }
    AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);
}

They work fine until I recently found that after certain inactivity, I assume of more than 30 minutes, these claims are lost. However the user is still logged in.

How do I reload these claims when the user is still logged in?

Update: How it occured.

I logged in to a user and then after roughly 30 minutes opened it again, and logged out of it. Instead of being logged out it refreshed my page, with no claims.


Solution

  • You are facing SecurityStampValidator in action. In the standard MVC5 template from VS2013/VS2015 there is a file App_Start\Startup.Auth.cs that has these lines:

    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))
        }
    }); 
    

    You need to look at SecurityStampValidator.OnValidateIdentity - this method regenerates cookie every 30 minutes (in default configuration). And it does not preserve claims added outside of user.GenerateUserIdentityAsync(manager).

    So you need to find ApplicationUser class and modify GenerateUserIdentityAsync(UserManager<ApplicationUser> manager) method to include your claims. And don't add claims anywhere else.