Share via


ASP.NET Core 2.1 MVC SameSite cookie 範例

ASP.NET Core 2.1 提供對 SameSite 屬性的內建支援,但已寫入原始標準。 修補的行為變更了 SameSite.None 的意義,以發出值為 None 的 sameSite 屬性,而不是根本不發出此值。 如果您不想發出該值,可以將 cookie 上的 SameSite 屬性設定為 -1。

除了 IFramesOpenIdConnect 整合等進階案例之外,ASP.NET Core Identity 基本上不受 SameSite cookie 影響。

使用 Identity 時,不要 新增任何 cookie 提供者或呼叫 services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)Identity 會處理此情況。

撰寫 SameSite 屬性

以下是如何在 cookie 上撰寫 SameSite 屬性的範例:

var cookieOptions = new CookieOptions
{
    // Set the secure flag, which Chrome's changes will require for SameSite none.
    // Note this will also require you to be running on HTTPS
    Secure = true,

    // Set the cookie to HTTP only which is good practice unless you really do need
    // to access it client side in scripts.
    HttpOnly = true,

    // Add the SameSite attribute, this will emit the attribute with a value of none.
    // To not emit the attribute at all set the SameSite property to (SameSiteMode)(-1).
    SameSite = SameSiteMode.None
};

// Add the cookie to the response cookie collection
Response.Cookies.Append(CookieName, "cookieValue", cookieOptions);

例如,Cookie 驗證、工作階段狀態和各種其他元件會透過 Cookie 選項設定其 sameSite 選項

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(options =>
    {
        options.Cookie.SameSite = SameSiteMode.None;
        options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
        options.Cookie.IsEssential = true;
    });

services.AddSession(options =>
{
    options.Cookie.SameSite = SameSiteMode.None;
    options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
    options.Cookie.IsEssential = true;
});

在上述程式碼中,cookie 驗證和工作階段狀態都會將其 sameSite 屬性設定為 None,並發出具有 None 值的屬性,並將 Secure 屬性設定為 true。

執行範例

如果您執行範例專案,請在初始頁面上載入瀏覽器偵錯工具,並將其用於檢視站台的 cookie 集合。 若要在 Edge 和 Chrome 中執行此動作,請按 F12,然後選取 Application 索引標籤,按一下 Storage 區段中 Cookies 選項底下的站台 URL。

Browser Debugger Cookie List

您可以從上圖看到,當您按一下 [建立 SameSite Cookie] 按鈕時,範例所建立的 cookie 具有的 SameSite 屬性值為 Lax 且符合範例程式碼中所設定的值。

攔截 cookie

為了攔截 cookie,若要根據使用者的瀏覽器代理程式支援來調整 None 值,您必須使用 CookiePolicy 中介軟體。 這必須放入 http 要求管線中寫入 cookie 的任何元件前面,並在 ConfigureServices() 內進行設定。

若要將其插入管線中,請在 Startup.csConfigure(IApplicationBuilder, IHostingEnvironment) 方法中使用 app.UseCookiePolicy()。 例如:

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

    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseCookiePolicy();
    app.UseAuthentication();
    app.UseSession();

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

然後在 ConfigureServices(IServiceCollection services) 中設定 cookie 原則,以在附加或刪除 cookie 時呼叫協助程式類別。 例如:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<CookiePolicyOptions>(options =>
    {
        options.CheckConsentNeeded = context => true;
        options.MinimumSameSitePolicy = SameSiteMode.None;
        options.OnAppendCookie = cookieContext =>
            CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
        options.OnDeleteCookie = cookieContext =>
            CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
    });
}

private void CheckSameSite(HttpContext httpContext, CookieOptions options)
{
    if (options.SameSite == SameSiteMode.None)
    {
        var userAgent = httpContext.Request.Headers["User-Agent"].ToString();
        if (SameSite.BrowserDetection.DisallowsSameSiteNone(userAgent))
        {
            options.SameSite = (SameSiteMode)(-1);
        }
    }
}

協助程式函式 CheckSameSite(HttpContext, CookieOptions)

  • 在將 cookie 附加至要求或從要求中將其刪除時呼叫。
  • 檢查 SameSite 屬性是否設定為 None
  • 如果 SameSite 設定為 None,且已知目前的使用者代理程式不支援 None 屬性值。 檢查是使用 SameSiteSupport 類別完成:
    • SameSite 屬性設定為 (SameSiteMode)(-1),以將其設定為不要發出值

以 .NET Framework 為目標

ASP.NET Core 和 System.Web (ASP.NET 4.x) 具有 SameSite 的獨立實作。 如果使用 ASP.NET Core 則不需要適用於 .NET Framework 的 SameSite KB 修補程式,System.Web SameSite 最低架構版本需求 (.NET Framework 4.7.2) 也不需要套用至 ASP.NET Core。

.NET 上的 ASP.NET Core 需要更新 NuGet 套件相依性,才能取得適當的修正程式。

若要取得適用於 .NET Framework 的 ASP.NET Core 變更,請確定您有已修補套件和版本 (2.1.14 或後續 2.1 版本) 的直接參考。

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

相關資訊

Chrome 更新ASP.NET Core SameSite 文件ASP.NET Core 2.1 SameSite 變更公告