HttpContext.Current is null during RegenerateIdentity

Introduction:

I am creating a custom Identity 2.0 implementation. By default, the environment updates the user ID every 30 minutes, creating a new one ClaimsIdentity

. Since I have some custom requirements (which I set in my login methods) that I want to move to the new one ClaimsIdentity

after the upgrade, I came up with an approach that reads the current one ClaimsIdentity

from HttpContext

and returns that as "new" ClaimsIdentity

. The problem is that it HttpContext.Current

is null when the identity is updated, so I cannot copy my old claims to the new identity.

Code:

In my Startup.cs

file, I have this code that updates the user id every x minutes:

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
    Provider = new CookieAuthenticationProvider
    {
        OnValidateIdentity = SecurityStampValidatorExtensions.OnValidateIdentity(
            validateInterval: TimeSpan.FromMinutes(0.5),
            regenerateIdentity: (manager, user) => manager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie))
    }
});

      

This function RegenerateIdentity

calls this method in mine UserManager

:

public async override Task<ClaimsIdentity> CreateIdentityAsync(ApplicationUser user, string authenticationType)
{
    ClaimsIdentity claimsIdentity;
    if (HttpContext.Current != null && 
        HttpContext.Current.User != null && 
        HttpContext.Current.User.Identity != null && 
        HttpContext.Current.User.Identity.IsAuthenticated)
    {
        // Just return the existing ClaimsIdentity so we don't lose our custom claims
        claimsIdentity = (ClaimsIdentity)HttpContext.Current.User.Identity;

        // TODO refresh some claims from the database

        return claimsIdentity;
    }

    // Create a new ClaimsIdentity if none exists
    claimsIdentity = await ClaimsIdentityFactory.CreateAsync(this, user, authenticationType);
    claimsIdentity.AddClaim(new Claim(Constants.DefaultSecurityStampClaimType, await GetSecurityStampAsync(user.Id)));

    return claimsIdentity;
}

      

Problem:

The first time it is called CreateIdentityAsync

(at login), HttpContext.Current

it matters, a personality is created, and all is well. The problem is that when CreateIdentityAsync

called again (because the identity is updated), HttpContext.Current

is null

. I don't understand why this is the case and I have not been able to fix it.

Theory:

Some of my theories on why HttpContext.Current

there are null

:

  • Is there something to do with async and HttpContext

    not get carried over to a new thread? I tried to create my own copy-over awaiter HttpContext.Current

    , but it didn't work.
  • HttpContext

    is actively destroyed by the framework to make sure it gets rid of everything? I haven't been able to find any code that does this, so it seems unlikely.

Does anyone have any suggestions on how to do this?

+3


source to share


1 answer


The cookie middleware runs during the authentication phase in the IIS pipeline, which is made available prior to the HttpContext or session state. Therefore, you will need to work without it.



0


source







All Articles