ASP.NET Core 2.1 MVC SameSite cookie 示例ASP.NET Core 2.1 MVC SameSite cookie sample

本文内容

ASP.NET Core 2.1 内置了对SameSite属性的支持,但它已写入原始标准。修补后的行为更改了 SameSite.None 的含义,以发出值为 None的 sameSite 属性,而不是根本不发出值。如果要不发出该值,可以将 cookie 的 SameSite 属性设置为-1。

编写 SameSite 属性Writing the SameSite attribute

下面是如何在 cookie 上编写 SameSite 属性的示例:

  1. var cookieOptions = new CookieOptions
  2. {
  3. // Set the secure flag, which Chrome's changes will require for SameSite none.
  4. // Note this will also require you to be running on HTTPS
  5. Secure = true,
  6. // Set the cookie to HTTP only which is good practice unless you really do need
  7. // to access it client side in scripts.
  8. HttpOnly = true,
  9. // Add the SameSite attribute, this will emit the attribute with a value of none.
  10. // To not emit the attribute at all set the SameSite property to (SameSiteMode)(-1).
  11. SameSite = SameSiteMode.None
  12. };
  13. // Add the cookie to the response cookie collection
  14. Response.Cookies.Append(CookieName, "cookieValue", cookieOptions);

设置 Cookie 身份验证和会话状态 cookieSetting Cookie Authentication and Session State cookies

Cookie 身份验证、会话状态和各种其他组件通过 Cookie 选项设置其 sameSite 选项,例如

  1. services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
  2. .AddCookie(options =>
  3. {
  4. options.Cookie.SameSite = SameSiteMode.None;
  5. options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
  6. options.Cookie.IsEssential = true;
  7. });
  8. services.AddSession(options =>
  9. {
  10. options.Cookie.SameSite = SameSiteMode.None;
  11. options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
  12. options.Cookie.IsEssential = true;
  13. });

在前面的代码中,cookie 身份验证和会话状态将其 sameSite 属性设置为 None,发出具有 None 值的属性,同时将 Secure 特性设置为 true。

运行示例Run the sample

如果运行示例项目,请在初始页面上加载浏览器调试器,并使用它查看站点的 cookie 集合。若要在 Edge 和 Chrome 中进行此操作,请按 F12 选择 "Application" 选项卡,然后单击 "Storage" 部分中 "Cookies" 选项下的 "站点 URL"。

浏览器调试器 Cookie 列表

您可以从上图中看到,当您单击 "创建 SameSite Cookie" 按钮的 SameSite 属性值为 Lax,与在示例代码中设置的值匹配时,示例创建的 cookie 就会看到该示例创建的 cookie。

截获 cookieIntercepting cookies

为了截获 cookie,若要根据用户的浏览器代理中的支持来调整无值,必须使用 CookiePolicy 中间件。这必须放入 http 请求管道中,然后才能ConfigureServices()中写入 cookie 和配置的任何组件。

若要将其插入管道,请使用Startup.csConfigure(IApplicationBuilder, IHostingEnvironment) 方法中的 app.UseCookiePolicy()例如:

  1. public void Configure(IApplicationBuilder app, IHostingEnvironment env)
  2. {
  3. if (env.IsDevelopment())
  4. {
  5. app.UseDeveloperExceptionPage();
  6. }
  7. else
  8. {
  9. app.UseExceptionHandler("/Home/Error");
  10. app.UseHsts();
  11. }
  12. app.UseHttpsRedirection();
  13. app.UseStaticFiles();
  14. app.UseCookiePolicy();
  15. app.UseAuthentication();
  16. app.UseSession();
  17. app.UseMvc(routes =>
  18. {
  19. routes.MapRoute(
  20. name: "default",
  21. template: "{controller=Home}/{action=Index}/{id?}");
  22. });
  23. }

然后,在 ConfigureServices(IServiceCollection services) 配置 cookie 策略,以便在添加或删除 cookie 时调用帮助器类。例如:

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. services.Configure<CookiePolicyOptions>(options =>
  4. {
  5. options.CheckConsentNeeded = context => true;
  6. options.MinimumSameSitePolicy = SameSiteMode.None;
  7. options.OnAppendCookie = cookieContext =>
  8. CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
  9. options.OnDeleteCookie = cookieContext =>
  10. CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
  11. });
  12. }
  13. private void CheckSameSite(HttpContext httpContext, CookieOptions options)
  14. {
  15. if (options.SameSite == SameSiteMode.None)
  16. {
  17. var userAgent = httpContext.Request.Headers["User-Agent"].ToString();
  18. if (SameSite.BrowserDetection.DisallowsSameSiteNone(userAgent))
  19. {
  20. options.SameSite = (SameSiteMode)(-1);
  21. }
  22. }
  23. }

Helper 函数 CheckSameSite(HttpContext, CookieOptions)

  • 当 cookie 追加到请求或从请求中删除时调用。
  • 检查 SameSite 属性是否设置为 None
  • 如果 SameSite 设置为 None 并且已知当前用户代理不支持 none 特性值。使用SameSiteSupport类完成检查:
    • 通过将属性设置为,将 SameSite 设置为不发出该值 (SameSiteMode)(-1)

目标 .NET FrameworkTargeting .NET Framework

ASP.NET Core 和 System.web (ASP.NET 经典)具有 SameSite 的独立实现。如果使用 ASP.NET Core 或 SameSite 最低版本要求(.NET 4.7.2)适用于 ASP.NET Core,则不需要 .NET Framework 的 SameSite KB 修补程序。

.NET 上的 ASP.NET Core 要求更新 nuget 程序包依赖项以获取适当的修补程序。

若要获取的 ASP.NET Core 更改 .NET Framework 确保你有对修补的包和版本(2.1.14 或更高版本2.1)的直接引用。

  1. <PackageReference Include="Microsoft.Net.Http.Headers" Version="2.1.14" />
  2. <PackageReference Include="Microsoft.AspNetCore.CookiePolicy" Version="2.1.14" />

更多信息More Information

Chrome 更新ASP.NET Core SameSite 文档ASP.NET Core 2.1 SameSite 更改公告