【问题标题】:.NET Core 2 CookieAuthentication ignores expiration time span.NET Core 2 CookieAuthentication 忽略过期时间跨度
【发布时间】:2018-11-13 04:52:23
【问题描述】:

我正在使用CookieAuthentication 开发一个 .NET Core 2.1 Web 应用程序。由于某种原因,在CookieAuthenticationOptions 对象上设置ExpireTimeSpanCookie.Expiration 不会影响Cookie 的生命周期。 Chrome 始终显示相同的到期日期 1969-12-31T23:59:59.000Z。所以关闭浏览器窗口后cookie就消失了。

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
   services.AddDistributedMemoryCache();

   services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
      .AddCookie(options =>
      {
         options.LoginPath = new PathString("/Account/Login/");
         options.AccessDeniedPath = new PathString("/Account/Login/");
         options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
         options.Cookie.Expiration = TimeSpan.FromDays(14);
         options.ExpireTimeSpan = TimeSpan.FromDays(14);
      });

   services.AddMvc(options =>
   {
      options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
   });

   services.AddAntiforgery(options => options.HeaderName = "X-CSRF-TOKEN");
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
   if (env.IsDevelopment())
   {
      app.UseBrowserLink();
      app.UseDeveloperExceptionPage();
   }
   else
   {
      app.UseExceptionHandler("/Error");
   }

   var provider = new FileExtensionContentTypeProvider();
   provider.Mappings[".tag"] = "riot/tag";

   app.UseStaticFiles(new StaticFileOptions()
   {
      ContentTypeProvider = provider
   });

   app.UseAuthentication();

   app.UseMvc(routes =>
   {
      routes.MapRoute(
             name: "default",
             template: "{controller=Home}/{action=Index}/{id?}");
   });
}

登录时我正在使用此代码

ClaimsPrincipal user = new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim(ClaimTypes.Name, userId.Value.ToString()) }, CookieAuthenticationDefaults.AuthenticationScheme));
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, user);

我尝试将services.AddMvc 放在services.AddAuthentication 之前,但这并没有什么不同。我也在services.AddAuthentication 之后尝试过services.ConfigureApplicationCookie,就像这个答案Cookie expiry in ASP.NET Core 2.0 with Identity

我错过了什么?

【问题讨论】:

    标签: asp.net asp.net-mvc asp.net-core asp.net-core-2.0 asp.net-authentication


    【解决方案1】:

    Chrome 中的过期日期表示浏览器中 cookie 的生命周期,而不是令牌的超时时间。当将 Identity Server 4 与 ASP.NET Identity 一起使用时,Identity Server 的 cookie 超时在这里起作用。客户端令牌过期后,用户将根据 Identity Server 重新进行身份验证,并且由于该令牌尚未过期,因此会更新客户端令牌。要在 Identity Server 上设置过期时间,您必须在 Identity Server Startup.cs 中添加 ConfigureApplicationCookiemiddleware,如下所示:

    services.AddAuthentication();
    
    services.ConfigureApplicationCookie(options =>
        {
            options.Cookie.Expiration = TimeSpan.FromDays(14);
            options.ExpireTimeSpan = TimeSpan.FromDays(14);
            options.SlidingExpiration = false;
       });
     
    services.AddMvc().SetCompatibilityVersion(Microsoft.AspNetCore.Mvc.CompatibilityVersion.Version_2_1);
    

    .net core 3.1 的更新(cooke.expiration 不再需要作为单独的选项):

    services.AddAuthentication();
    
    services.ConfigureApplicationCookie(options =>
        {
            options.ExpireTimeSpan = TimeSpan.FromDays(14);
            options.SlidingExpiration = false;
       });
     
    services.AddMvc();
    

    【讨论】:

    • 似乎是错误的答案。我收到一个错误:Cookie.Expiration 被忽略,请改用 ExpireTimeSpan
    【解决方案2】:

    使用 IsPersistent = true

    示例

    var claims = new List<Claim>
    {
        new Claim(ClaimTypes.NameIdentifier, client.Id),
        new Claim(ClaimTypes.Role, client.Role)
    };
    
    var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
    
    await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,
              new ClaimsPrincipal(identity),
              new AuthenticationProperties
              {
                  ExpiresUtc = DateTime.UtcNow.AddYears(1),
                  IsPersistent = true
              });
    

    【讨论】:

    • 如果您想禁用第三方对 cookie 的使用并防止 CSRF 攻击,我还建议添加 MinimumSameSitePolicy = SameSiteMode.Lax
    【解决方案3】:

    来自Use cookie authentication without ASP.NET Core Identity,加粗表示强调。

    身份验证票证存储在该 TimeSpan 之后 cookie 过期。 ExpireTimeSpan 添加到当前创建时间 票证的到期时间。 ExpiredTimeSpan 值始终 进入由服务器验证的加密 AuthTicket。 还可以 进入 Set-Cookie 标头,但前提是设置了 IsPersistent。 设置 IsPersistent 为 true,配置传递给的 AuthenticationProperties 异步登录。 ExpireTimeSpan 的默认值为 14 天。

    【讨论】:

      【解决方案4】:

      Identity 具有专用的 cookie 配置选项 CookieAuthenticationOptions 和 cookie Expiration 值已被决定忽略,可以在此处找到一些说明: Github issue Test reference

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-01-25
        • 1970-01-01
        • 2021-12-22
        • 1970-01-01
        • 1970-01-01
        • 2018-08-15
        相关资源
        最近更新 更多