且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

使用 ASP.NET Core 2.1/3+ Identity 验证身份验证 cookie

更新时间:2022-12-06 17:14:22

@MarkG 为我指明了正确的方向,谢谢.仔细查看源代码后 对于 SecurityStampValidatorIdentity 事情对我来说变得很清楚.实际上,我在问题中发布的示例代码是不必要的,因为 ASP.NET Core Identity 以更好的方式提供了开箱即用的功能.

@MarkG pointed me into the right direction, thanks. After having a closer look at the source code for SecurityStampValidator and Identity things became clear to me. Actually, the sample code I posted with my question is unnecessary, because ASP.NET Core Identity brings the feature in a better fashion out-of-the-box.

因为我还没有找到这样的摘要,也许它对其他人也有帮助.

As I didn't find a summary like this yet, maybe it will be helpful to others, too.

...但还是很高兴知道...

... but still good to know...

services.ConfigureApplicationCookie(options =>
{
    options.Cookie.Expiration = TimeSpan.FromDays(30);
    options.ExpireTimeSpan = TimeSpan.FromDays(30);
    options.SlidingExpiration = true;
});

ExpireTimeSpan

默认为 TimeSpan.FromDays(14)

身份验证票的签发时间是 cookie (CookieValidatePrincipalContext.Properties.IssuedUtc) 的一部分.当 cookie 被发送回服务器时,当前时间减去发布时间必须大于ExpireTimeSpan.如果不是,用户将被注销而无需进一步调查.在实践中,设置ExpireTimeSpan,主要是与SlidingExpiration 设置为true 一起使用.这是一种确保用户积极使用应用程序的方法,而不是例如让设备无人看管.负 TimeSpans 将立即注销用户(但不是 TimeSpan.Zero).

The issue time of the authentication ticket is part of the cookie (CookieValidatePrincipalContext.Properties.IssuedUtc). When the cookie is sent back to the server, the current time minus the issue time must be greater than ExpireTimeSpan. If it is not, the user will be signed out without further investigation. In practice, setting the ExpireTimeSpan, mostly goes together with SlidingExpiration set to true. This is a means to ensure that the user is actively working with the app, and did not e.g. leave the device back unattended. Negative TimeSpans will sign the user off immediately (but not TimeSpan.Zero).

services.AddOptions();
services.Configure<SecurityStampValidatorOptions>(options =>
{
    // This is the key to control how often validation takes place
    options.ValidationInterval = TimeSpan.FromMinutes(5);
});

验证间隔

默认为 TimeSpan.FromMinutes(30)

这决定了验证 cookie 的有效性将根据持久存储进行检查的时间跨度.它是通过为服务器的每个请求调用SecurityStampValidator来完成的.如果当前时间减去 cookie 的发布时间小于或等于 ValidationInterval,将调用 ValidateSecurityStampAsync.这意味着ValidationInterval = TimeSpan.Zero 导致为每个请求调用 ValidateSecurityStampAsync.

This determines the time span after which the validity of the authentication cookie will be checked against persistent storage. It is accomplished by calling the SecurityStampValidator for every request to the server. If the current time minus the cookie's issue time is less or equal to ValidationInterval, a call to ValidateSecurityStampAsync will occur. This means ValidationInterval = TimeSpan.Zero leads to calling the ValidateSecurityStampAsync for each request.

注意 UserManager 必须支持获取安全戳,否则会失败.对于自定义用户管理器或用户存储,两者都必须正确实现 IUserSecurityStampStore.

Note UserManager must support getting security stamps or it will fail. For a custom user manager or user store, both must properly implement IUserSecurityStampStore<TUser>.

需要注意的是:services.AddIdentity() 还为身份验证 cookie 设置默认值.如果您在 services.ConfigureApplicationCookie() 之后添加它,这将覆盖之前的设置.我在上述之前调用了 services.Configure().

The thing to be aware of is: services. AddIdentity() also sets defaults for the authentication cookie. If you add it after services.ConfigureApplicationCookie() this will override the previous settings. I called services.Configure<SecurityStampValidatorOptions>() after the previous ones above.

再次感谢@MarkG 为我们指明方向.

Thanks again to @MarkG for showing the way.