ASP.NET 4.7.2 C# WebForms の SameSite Cookie サンプル
.NET Framework 4.7 には SameSite 属性のサポートが組み込まれていますが、元の標準に準拠しています。
修正プログラムが適用された動作では、値をまったく出力するのではなく、 の値None
を持つ属性を出力する の意味SameSite.None
が変更されました。 値を出力しない場合は、Cookie の プロパティを SameSite
-1 に設定できます。
SameSite 属性の書き込み
Cookie に SameSite 属性を記述する方法の例を次に示します。
// Create the cookie
HttpCookie sameSiteCookie = new HttpCookie("SameSiteSample");
// Set a value for the cookie
sameSiteCookie.Value = "sample";
// Set the secure flag, which Chrome's changes will require for SameSite none.
// Note this will also require you to be running on HTTPS
sameSiteCookie.Secure = true;
// Set the cookie to HTTP only which is good practice unless you really do need
// to access it client side in scripts.
sameSiteCookie.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 -1.
sameSiteCookie.SameSite = SameSiteMode.None;
// Add the cookie to the response cookie collection
Response.Cookies.Add(sameSiteCookie);
英語以外の言語でこれを読んでいる場合は、ネイティブ言語でコード コメントを表示する場合は、この GitHub ディスカッションの問題 でお知らせください。
フォーム認証 Cookie の既定の sameSite 属性は、 の cookieSameSite
フォーム認証設定の パラメーターで設定されます。 web.config
<system.web>
<authentication mode="Forms">
<forms name=".ASPXAUTH" loginUrl="~/" cookieSameSite="None" requireSSL="true">
</forms>
</authentication>
</system.web>
セッション状態の既定の sameSite 属性は、 のセッション設定の 'cookieSameSite' パラメーターにも設定されます web.config
<system.web>
<sessionState cookieSameSite="None">
</sessionState>
</system.web>
.NET への 2019 年 11 月の更新プログラムでは、フォーム認証とセッション lax
の既定の設定が最も互換性のある設定と同様に変更されましたが、ページを iframe に埋め込む場合は、この設定を None に戻し、次に示す インターセプト コードを追加して、ブラウザーの機能に応じて動作を調整 none
する必要があります。
サンプルの実行
サンプル プロジェクトを実行すると、最初のページでブラウザー デバッガーが読み込まれて、それを使用してサイトの Cookie コレクションが表示されます。
Edge と Chrome でこれを行うには、F12
キーを押してから Application
タブを選び、Storage
セクションの Cookies
オプションの下にあるサイト URL をクリックします。
上の図から、[Cookie の作成] ボタンをクリックしたときにサンプルによって作成された Cookie の SameSite Lax
属性値が の値であり、 サンプル コードで設定された値と一致していることがわかります。
制御しない Cookie のインターセプト
.NET 4.5.2 では、 Response.AddOnSendingHeaders
ヘッダーの書き込みをインターセプトするための新しいイベント が導入されました。 これは、クライアント コンピューターに返される前に Cookie をインターセプトするために使用できます。 このサンプルでは、ブラウザーが新しい sameSite の変更をサポートしているかどうかを確認する静的メソッドにイベントを接続し、サポートされていない場合は、新しい None
値が設定されている場合に属性を出力しないように Cookie を変更します。
イベントの処理と Cookie sameSite
属性の調整の例については、イベントのフックの例については global.asax と SameSiteCookieRewriter.cs を参照してください。
public static void FilterSameSiteNoneForIncompatibleUserAgents(object sender)
{
HttpApplication application = sender as HttpApplication;
if (application != null)
{
var userAgent = application.Context.Request.UserAgent;
if (SameSite.BrowserDetection.DisallowsSameSiteNone(userAgent))
{
HttpContext.Current.Response.AddOnSendingHeaders(context =>
{
var cookies = context.Response.Cookies;
for (var i = 0; i < cookies.Count; i++)
{
var cookie = cookies[i];
if (cookie.SameSite == SameSiteMode.None)
{
cookie.SameSite = (SameSiteMode)(-1); // Unspecified
}
}
});
}
}
}
特定の名前付き Cookie の動作は、ほとんど同じ方法で変更できます。次のサンプルでは、値をサポートするブラウザーで既定の認証 Cookie を から Lax
にNone
調整するか、 をサポートNone
None
していないブラウザーで sameSite 属性を削除します。
public static void AdjustSpecificCookieSettings()
{
HttpContext.Current.Response.AddOnSendingHeaders(context =>
{
var cookies = context.Response.Cookies;
for (var i = 0; i < cookies.Count; i++)
{
var cookie = cookies[i];
// Forms auth: ".ASPXAUTH"
// Session: "ASP.NET_SessionId"
if (string.Equals(".ASPXAUTH", cookie.Name, StringComparison.Ordinal))
{
if (SameSite.BrowserDetection.DisallowsSameSiteNone(userAgent))
{
cookie.SameSite = -1;
}
else
{
cookie.SameSite = SameSiteMode.None;
}
cookie.Secure = true;
}
}
});
}