【问题标题】:ASP.NET Core MVC: setting expiration of identity cookieASP.NET Core MVC:设置身份 cookie 过期
【发布时间】: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


    【解决方案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 天。
    【解决方案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

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-30
    • 1970-01-01
    • 2019-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多