ASP.NET Core 3.1 Razor Pages SameSite cookie 範例
ASP.NET Core 3.0 提供對 SameSite 屬性的內建支援,包括用來隱藏寫入屬性之 Unspecified
的 SameSiteMode
屬性值。
ASP.NET Core Identity 在很大程度上不受 SameSite cookies 影響,除了 IFrames
或 OpenIdConnect
整合等進階案例。
使用 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.Unspecified.
SameSite = SameSiteMode.None
};
// Add the cookie to the response cookie collection
Response.Cookies.Append(CookieName, "cookieValue", cookieOptions);
設定 Cookie 驗證和工作階段狀態 cookies
例如,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。
您可以從上圖看到,當您按一下 [建立 SameSite Cookie] 按鈕時,範例所建立的 cookie 具有的 SameSite 屬性值為 Lax
且符合範例程式碼中所設定的值。
攔截 cookies
為了攔截 cookies,若要根據使用者的瀏覽器代理程式支援來調整 None 值,您必須使用 CookiePolicy
中介軟體。 這必須放入 HTTP 要求管線中寫入 cookies 的任何元件 前面 ,並在 ConfigureServices()
內進行設定。
若要將其插入管線中,請在 Startup.cs 的 Configure(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 原則,以在附加或刪除 cookies 時呼叫協助程式類別,如下所示:
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.Unspecified;
}
}
}
協助程式函式 CheckSameSite(HttpContext, CookieOptions)
:
- 在將 cookies 附加至要求或從要求中將其刪除時呼叫。
- 檢查
SameSite
屬性是否設定為None
。 - 如果
SameSite
設定為None
,且已知目前的使用者代理程式不支援 None 屬性值。 檢查是使用 SameSiteSupport 類別完成:- 將
SameSite
屬性設定為(SameSiteMode)(-1)
,以將其設定為不要發出值
- 將