在 ASP.NET Core 2 中使用 Cookie 身份验证(带有或不带有Identity
)时,可能会发生用户的电子邮件或姓名被更改,甚至在 cookie 的生命周期内帐户被删除的情况。这就是文档指出应该验证 cookie 的原因。文档中的示例注释为
此处描述的方法会在每个请求上触发。这可能会导致应用程序的性能大幅下降。
所以我想知道验证 cookie 主体的最佳模式是什么。我所做的Startup.cs
是订阅该OnValidatePrincipal
事件并检查主体的有效性,例如每 5 分钟通过LastValidatedOn
向 cookie 附加一个声明,如下所示:
services.ConfigureApplicationCookie(options =>
{
// other cookie options go here
options.Events.OnValidatePrincipal = async context =>
{
const string claimType = "LastValidatedOn";
const int reValidateAfterMinutes = 5;
if (!(context.Principal?.Identity is ClaimsIdentity claimIdentity)) return;
if (!context.Principal.HasClaim(c => c.Type == claimType) ||
DateTimeOffset.Now.UtcDateTime.Subtract(new DateTime(long.Parse(context.Principal.Claims.First(c => c.Type == claimType).Value))) > TimeSpan.FromMinutes(reValidateAfterMinutes))
{
var mgr = context.HttpContext.RequestServices.GetRequiredService<SignInManager<ApplicationUser>>();
var user = await mgr.UserManager.FindByNameAsync(claimIdentity.Name);
if (user != null && claimIdentity.Claims.FirstOrDefault(c => c.Type == "AspNet.Identity.SecurityStamp")?.Value == await mgr.UserManager.GetSecurityStampAsync(user))
{
claimIdentity.FindAll(claimType).ToList().ForEach(c => claimIdentity.TryRemoveClaim(c));
claimIdentity.AddClaim(new Claim(claimType, DateTimeOffset.Now.UtcDateTime.Ticks.ToString(), typeof(long).ToString()));
context.ShouldRenew = true;
}
else
{
context.RejectPrincipal();
await mgr.SignOutAsync();
}
}
};
});