简介:
我正在构建标识 2.0 的自定义实现。默认情况下,框架每 30 分钟刷新一次用户的身份,从而创建一个新ClaimsIdentity
。因为我有一些自定义声明(我在登录方法中设置的(,我想在刷新时移动到新ClaimsIdentity
,所以我想出了一种从HttpContext
读取当前ClaimsIdentity
并将其作为"新"ClaimsIdentity
返回的方法。问题是刷新标识时HttpContext.Current
为 null,因此我无法将旧声明复制到新标识。
代码:
在我的Startup.cs
文件中,我有以下代码,每x分钟刷新一次用户的身份:
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))
}
});
这个RegenerateIdentity
函数在我的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;
}
问题:
第一次调用CreateIdentityAsync
(当我登录时(,HttpContext.Current
有一个值,创建了标识,一切都很好。问题是:当再次调用CreateIdentityAsync
时(因为正在刷新身份(,HttpContext.Current
null
。我不明白为什么会这样,我也无法修复它。
理论:
我关于为什么HttpContext.Current
null
的一些理论:
- 与异步和
HttpContext
未传输到新线程有关?我尝试构建自己的等待者来复制HttpContext.Current
但这不起作用。 - 框架正在积极破坏
HttpContext
以确保它摆脱一切?我无法找到任何执行此操作的代码,因此似乎不太可能。
有人对如何实现这一目标有任何建议吗?
Cookie 中间件在 IIS 管道中的身份验证阶段运行,该阶段在 HttpContext 或会话状态可用之前。所以你需要在没有它的情况下工作。