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 awaiterHttpContext.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?
source to share