ASP.NET Core MVC:设置身份 cookie 过期

Posted

技术标签:

【中文标题】ASP.NET Core MVC:设置身份 cookie 过期【英文标题】:ASP.NET Core MVC: setting expiration of identity cookie 【发布时间】:2016-01-24 18:27:55 【问题描述】:

在我的 ASP.NET Core MVC 应用程序中,身份验证 cookie 的生命周期设置为“会话”,因此它会持续到我关闭浏览器。 我使用 MVC 的默认身份验证方案:

app.UseIdentity();

如何延长 cookie 的生命周期?

【问题讨论】:

【参考方案1】:

您使用的 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&lt;TUser, TRole&gt; 方法有一个重载版本,它允许使用一个 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。

【讨论】:

谢谢,我可以使用这种方法更改 cookie 的名称,但即使我设置了 ExpireTimeSpan,auth cookie 的生命周期也设置为“会话”。知道为什么吗?这是我的 Startup.cs:github.com/severisv/MyTeam/blob/master/src/MyTeam/Startup.cs 我尝试禁用 Facebook-auth。我没有使用 https。 @fiskeboss 我添加了一个关于我发现的关于这件事的编辑。 我在 Core RC1 上,但它似乎不起作用。 PasswordSignInAsync 有效,但不在响应中发送身份验证 cookie 'IsPersistent' 真的很有帮助 ;) @user1620696 SignInAsync 中的“异步”部分很重要吗?因为我正在使用登录【参考方案2】:

2.0 版有一个答案,但它对我不起作用。我必须这样做:

services.ConfigureApplicationCookie(options =>

    options.ExpireTimeSpan = TimeSpan.FromDays(30);
);

默认值为 14 天。

【讨论】:

还是不行,它设置了cookie的expires属性,但是将Expires头设置为1/1/1970。 检查 net core 5 的默认有效期为 14 天。响应服务器中的过期标头主要用于在浏览器中缓存它,因此它与 cookie 无关。【参考方案3】:

在 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 过期时间。

【讨论】:

这不再是真的了。以下是关于 v2.1 ExpireTimeSpan 的文档摘录:存储在 cookie 中的身份验证票证过期后的 TimeSpan。 ExpireTimeSpan 添加到当前时间以创建工单的到期时间。 ExpiredTimeSpan 值始终进入由服务器验证的加密 AuthTicket。它也可能进入 Set-Cookie 标头,但前提是设置了 IsPersistent。要将 IsPersistent 设置为 true,请配置传递给 SignInAsync 的 AuthenticationProperties。 ExpireTimeSpan 的默认值为 14 天。 来源:docs.microsoft.com/en-us/aspnet/core/security/authentication/…【参考方案4】:

对于 ASP.NET Core 2.0

  services.ConfigureApplicationCookie(options =>
        
            options.Cookie.Name = "CookieName";
            options.Cookie.Expiration = TimeSpan.FromDays(2);
        );

【讨论】:

我也输入了options.ExpireTimeSpan = TimeSpan.FromDays(2);——即使 MS 不断改变主意,其中一个也是正确的。 @gbjbaanb options.ExpireTimeSpan 是存储(并受保护)在 cookie 中的应用程序值,浏览器或攻击者无法访问该值;而options.Cookie.Expiration 是一个将与浏览器通信的时间跨度。两个时间戳通常必须对齐以避免意外过期。 @timmi4sa:没那么简单。在较新版本的 .Net Core 上,options.Cookie.Expiration 实际上会触发配置异常,警告不应使用它。【参考方案5】:

试试

app.UseIdentity().UseCookieAuthentication(
    new CookieAuthenticationOptions
    
        ExpireTimeSpan = TimeSpan.FromHours(1)
    
);

【讨论】:

我试过这个,还有其他选项,但似乎被忽略了。 .NET Core 3.1 中没有 app.UseIdentity()。有没有现代的等价物?【参考方案6】:

由于某种原因,我在使用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

【讨论】:

ApplicationUser 和 IdentityRole 是从哪里来的? 猜我是按照这里的说明操作的:docs.microsoft.com/de-de/aspnet/core/migration/…。大部分继承自IdentityUser

以上是关于ASP.NET Core MVC:设置身份 cookie 过期的主要内容,如果未能解决你的问题,请参考以下文章

如何先用asp.net身份框架数据库将asp.net mvc迁移到asp.net core

ASP.NET CORE MVC 身份用户和角色不起作用

JWT 身份验证 ASP.NET Core MVC 应用程序

ASP.NET Core MVC 2.x 全面教程_ASP.NET Core MVC 14. ASP.NET Core Identity 入门

ASP.Net Core - 使用 WebAPI 和 MVC 前端的 JWT 身份验证不起作用

ASP.NET Core MVC:使用 SQL Server 身份验证连接到现有数据库