ASP.NET Core 2.1 Razor Pages の SameSite cookie のサンプル
このサンプルは、ターゲットされている .NET Framework をターゲットにしています
ASP.NET Core 2.1 には SameSite 属性のサポートが組み込まれていますが、元の標準に書き込まれていました。 パッチ適用後の動作では SameSite.None
の意味が変更され、値を出力しない代わりに、None
の値を持つ SameSite 属性が出力されるようになりました。 値を出力しない場合は、cookie の SameSite
プロパティを -1 に設定できます。
ASP.NET Core Identity は、IFrames
または OpenIdConnect
統合のような高度なシナリオを除き、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 の設定
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 をクリックします。
上の画像から、"Create SameSite Cookie" ボタンをクリックしたときにサンプルによって作成された cookie の SameSite 属性値が Lax
であり、サンプル コードで設定されている値と一致していることがわかります。
Cookie のインターセプト
Cookie をインターセプトするには、ユーザーのブラウザー エージェントでのサポート合わせて None 値を調整するために、CookiePolicy
ミドルウェアを使用する必要があります。 これは、Cookie を書き込むすべてのコンポーネントの前に HTTP 要求パイプラインに配置して、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 が追加または削除されたときにヘルパー クラスを呼び出すように 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 クラスを使って実行されます。- プロパティを
(SameSiteMode)(-1)
に設定して、値を出力しないようにSameSite
を設定します
- プロパティを
.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 の変更に関するお知らせ
ASP.NET Core