【发布时间】:2016-01-24 18:27:55
【问题描述】:
在我的 ASP.NET Core MVC 应用程序中,身份验证 cookie 的生命周期设置为“会话”,因此它会持续到我关闭浏览器。 我使用 MVC 的默认身份验证方案:
app.UseIdentity();
如何延长 cookie 的生命周期?
【问题讨论】:
标签: asp.net-mvc asp.net-identity asp.net-core asp.net-core-mvc
在我的 ASP.NET Core MVC 应用程序中,身份验证 cookie 的生命周期设置为“会话”,因此它会持续到我关闭浏览器。 我使用 MVC 的默认身份验证方案:
app.UseIdentity();
如何延长 cookie 的生命周期?
【问题讨论】:
标签: asp.net-mvc asp.net-identity asp.net-core asp.net-core-mvc
您使用的 ASP.NET 身份中间件是对 UseCookieAuthentication 的一些调用的包装,其中包括管道上的 Cookie 身份验证中间件。这可以在 Identity 中间件 here on GitHub 的构建器扩展的源代码中看到。在这种情况下,配置底层 Cookie 身份验证应如何工作所需的选项封装在 IdentityOptions 上,并在设置依赖注入时进行配置。
确实,看我给你链接的源码可以看到,当你调用app.UseIdentity()时,运行如下:
var options = app.ApplicationServices.GetRequiredService<IOptions<IdentityOptions>>().Value;
app.UseCookieAuthentication(options.Cookies.ExternalCookie);
app.UseCookieAuthentication(options.Cookies.TwoFactorRememberMeCookie);
app.UseCookieAuthentication(options.Cookies.TwoFactorUserIdCookie);
app.UseCookieAuthentication(options.Cookies.ApplicationCookie);
return app;
要设置IdentityOptions 类,AddIdentity<TUser, TRole> 方法有一个重载版本,它允许使用一个 lambda 配置选项。因此,您只需要传入一个 lambda 来配置选项。在这种情况下,您只需访问选项类的Cookies 属性并根据需要配置ApplicationCookie。要更改时间跨度,您可以执行以下操作
services.AddIdentity<ApplicationUser, IdentityRole>(options => {
options.Cookies.ApplicationCookie.ExpireTimeSpan = TimeSpan.FromHours(1);
});
编辑: ExpireTimeSpan 属性仅在调用 HttpContext.Authentication.SignInAsync 时使用 AuthenticationProperties 的实例并将 IsPersistent 设置为 true。
仅使用 Cookie 身份验证中间件进行尝试,结果证明这是可行的:如果我们在没有此选项的情况下登录,我们会得到一个持续会话的 cookie,如果我们一起发送它,我们会得到一个持续我们的 cookie配置中间件时设置。
使用 ASP.NET Identity 的方法是传递 PasswordSignInAsync 的参数 isPersistent 和值 true。这最终是对HttpContext 中的SignInAsync 的调用,传入AuthenticationProperties 并将IsPersistent 设置为true。电话最终是这样的:
var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure: false);
RememberMe 用于配置我们将 IsPersistent 设置为 true 还是 false。
【讨论】:
2.0 版有一个答案,但它对我不起作用。我必须这样做:
services.ConfigureApplicationCookie(options =>
{
options.ExpireTimeSpan = TimeSpan.FromDays(30);
});
默认值为 14 天。
【讨论】:
在 ASP.NET Core 2.0 中使用 ExpireTimeSpan 属性而不是 Cookie.Expiration。
services.ConfigureApplicationCookie(options =>
{
options.Cookie.Name = "CookieName";
options.ExpireTimeSpan = TimeSpan.FromHours(24);
options.SlidingExpiration = true;
});
来自docs:
Cookie.Expiration:获取或设置 cookie 的生命周期。目前,此选项无操作,将在 ASP.NET Core 2.1+ 中过时。使用 ExpireTimeSpan 选项设置 cookie 过期时间。
【讨论】:
ExpireTimeSpan 的文档摘录:存储在 cookie 中的身份验证票证过期后的 TimeSpan。 ExpireTimeSpan 添加到当前时间以创建工单的到期时间。 ExpiredTimeSpan 值始终进入由服务器验证的加密 AuthTicket。它也可能进入 Set-Cookie 标头,但前提是设置了 IsPersistent。要将 IsPersistent 设置为 true,请配置传递给 SignInAsync 的 AuthenticationProperties。 ExpireTimeSpan 的默认值为 14 天。
对于 ASP.NET Core 2.0
services.ConfigureApplicationCookie(options =>
{
options.Cookie.Name = "CookieName";
options.Cookie.Expiration = TimeSpan.FromDays(2);
});
【讨论】:
options.ExpireTimeSpan = TimeSpan.FromDays(2);——即使 MS 不断改变主意,其中一个也是正确的。
options.ExpireTimeSpan 是存储(并受保护)在 cookie 中的应用程序值,浏览器或攻击者无法访问该值;而options.Cookie.Expiration 是一个将与浏览器通信的时间跨度。两个时间戳通常必须对齐以避免意外过期。
options.Cookie.Expiration 实际上会触发配置异常,警告不应使用它。
试试
app.UseIdentity().UseCookieAuthentication(
new CookieAuthenticationOptions
{
ExpireTimeSpan = TimeSpan.FromHours(1)
}
);
【讨论】:
由于某种原因,我在使用SignInAsync([..], true) 时遇到了问题,cookie 从未在浏览器中显示(并且正确地登录失败):
所以,我尝试将 UTC 时区差异添加到 ExpireTimeSpan 的 TimeSpan 中
services.AddIdentity<ApplicationUser, IdentityRole>(o =>
{
// add TimeSpan with 5 minutes plus timezone difference from Utc time
o.Cookies.ApplicationCookie.ExpireTimeSpan = DateTime.Now.Subtract(DateTime.UtcNow).Add( TimeSpan.FromMinutes(5) );
});
瞧!它有效,cookie 仅在浏览器中显示 +5min 过期。
PingBack 到 github.com https://github.com/aspnet/Identity/issues/766#issuecomment-253237576
【讨论】: