SameSite Cookie 和適用於 .NET 的開放 Web 介面 (OWIN)
SameSite
是IETF 草案,旨在提供一些保護,以防止跨網站偽造(CSRF)攻擊。 SameSite 2019 草稿:
- 預設會將 Cookie 視為
SameSite=Lax
。 - 指出明確判斷
SameSite=None
提示以啟用跨網站傳遞的 Cookie 應標示為Secure
。
Lax
適用於大部分的應用程式 Cookie。 某些形式的驗證 (例如 OpenID Connect (OIDC) 和 WS 同盟) 預設為 POST 型重新導向。 POST 型重新導向會觸發 SameSite
瀏覽器保護,因此 SameSite
會停用這些元件。 由於要求流程的差異,大部分 的 OAuth 登入都不會受到影響。 所有其他元件預設不會設定SameSite
,並使用客戶端默認行為(舊或新)。
參數 None
會導致實作先前 2016 年草稿標準 之用戶端的相容性問題(例如 iOS 12)。 請參閱本文件中的支援舊版瀏覽器。
發出 Cookie 的每個 OWIN 元件都需要決定是否 SameSite
適當。
如需本文的 ASP.NET 4.x 版本,請參閱 在 ASP.NET 中使用 SameSite Cookie。
Microsoft.Owin
SameSite
有自己的實作:
- 這不直接相依於 中的
System.Web
。 SameSite
適用於套件、.NET 4.5 和更新版本可Microsoft.Owin
設為目標的所有版本。- 只有 SystemWebCookieManager 元件會直接與 類別互動
System.Web
HttpCookie
。
SystemWebCookieManager
取決於 .NET 4.7.2 System.Web
API 來啟用 SameSite
支援,以及要變更行為的修補程式。
使用的原因 SystemWebCookieManager
概述於 OWIN 和 System.Web 回應 Cookie 整合問題中。 SystemWebCookieManager
在上 System.Web
執行 時,建議使用 。
下列程式代碼會設定 SameSite
為 Lax
:
owinContext.Response.Cookies.Append("My Key", "My Value", new CookieOptions()
{
SameSite = SameSiteMode.Lax
});
下列 API 使用 SameSite
:
- Microsoft.Owin.SameSiteMode
- CookieOptions.SameSite
- CookieAuthenticationOptions 類別
- CookieAuthenticationOptions.CookieSameSite
- ICookieManager
- SystemWebCookieManager
- SystemWebChunkingCookieManager
- CookieAuthenticationOptions.CookieManager
- OpenIdConnectAuthenticationOptions.CookieManager
Microsoft.Owin 從未支援 SameSite
2016 年草稿標準。
SameSite 2019 草稿的支援僅適用於 Microsoft.Owin
4.1.0 和更新版本。 舊版沒有修補程式。
規格的 SameSite
2019 年草稿:
- 不回溯相容於 2016 草稿。 如需詳細資訊,請參閱本文件中的支援舊版瀏覽器。
- 指定 cookies 預設被視為
SameSite=Lax
。 - 指定明確判斷提示
SameSite=None
以啟用跨網站傳遞的 cookies 應標示為Secure
。None
是要選擇退出的新項目。 - 排定於 2020 年 2 月由 Chrome 依預設啟用。 瀏覽器於 2019 年開始移轉至此標準。
- 由 KB 文章中所述的修補程式所支援。 如需詳細資訊,請參閱 支援 .NET Framework 中 SameSite 的 KB 文章。
2016 SameSite
年標準規定未知的值必須視為 SameSite=Strict
值。 從支援 2016 SameSite
標準之舊版瀏覽器存取的應用程式,在取得 SameSite
值為 None
的屬性時可能會中斷。 如果 Web 應用程式預定要支援舊版瀏覽器,則必須實作瀏覽器偵測。 ASP.NET 不會實作瀏覽器偵測,因為User-Agents值高度變動且經常變更。 ICookieManager 中的擴充點允許插入 User-Agent 特定邏輯。
在 Startup.Configuration
中,新增如下的程式碼:
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
// … Your preexisting options …
CookieManager = new SameSiteCookieManager(
new SystemWebCookieManager())
});
// Remaining code removed for brevity.
上述程式代碼需要 .NET 4.7.2 或更新版本的 SameSite
修補程式。
下列程式代碼示範 的範例實作 SameSiteCookieManager
:
public class SameSiteCookieManager : ICookieManager
{
private readonly ICookieManager _innerManager;
public SameSiteCookieManager() : this(new CookieManager())
{
}
public SameSiteCookieManager(ICookieManager innerManager)
{
_innerManager = innerManager;
}
public void AppendResponseCookie(IOwinContext context, string key, string value,
CookieOptions options)
{
CheckSameSite(context, options);
_innerManager.AppendResponseCookie(context, key, value, options);
}
public void DeleteCookie(IOwinContext context, string key, CookieOptions options)
{
CheckSameSite(context, options);
_innerManager.DeleteCookie(context, key, options);
}
public string GetRequestCookie(IOwinContext context, string key)
{
return _innerManager.GetRequestCookie(context, key);
}
private void CheckSameSite(IOwinContext context, CookieOptions options)
{
if (options.SameSite == Microsoft.Owin.SameSiteMode.None
&& DisallowsSameSiteNone(context))
{
options.SameSite = null;
}
}
在上述範例中, DisallowsSameSiteNone
會在 方法中 CheckSameSite
呼叫 。 DisallowsSameSiteNone
是使用者方法,可偵測使用者代理程式是否不支援 SameSite
None
:
private void CheckSameSite(IOwinContext context, CookieOptions options)
{
if (options.SameSite == Microsoft.Owin.SameSiteMode.None
&& DisallowsSameSiteNone(context))
{
options.SameSite = null;
}
}
下列程式碼顯示範例 DisallowsSameSiteNone
方法:
警告
下列程式碼僅供示範之用:
- 不應將其視為完整程式碼。
- 該程式碼不受維護或支援。
public static bool DisallowsSameSiteNone(IOwinContext context)
{
var userAgent = context.Request.Headers["User-Agent"];
if (string.IsNullOrEmpty(userAgent))
{
return false;
}
// Cover all iOS based browsers here. This includes:
// - Safari on iOS 12 for iPhone, iPod Touch, iPad
// - WkWebview on iOS 12 for iPhone, iPod Touch, iPad
// - Chrome on iOS 12 for iPhone, iPod Touch, iPad
// All of which are broken by SameSite=None, because they use the iOS
// networking stack.
if (userAgent.Contains("CPU iPhone OS 12") ||
userAgent.Contains("iPad; CPU OS 12"))
{
return true;
}
// Cover Mac OS X based browsers that use the Mac OS networking stack.
// This includes:
// - Safari on Mac OS X.
// This does not include:
// - Chrome on Mac OS X
// Because they do not use the Mac OS networking stack.
if (userAgent.Contains("Macintosh; Intel Mac OS X 10_14") &&
userAgent.Contains("Version/") && userAgent.Contains("Safari"))
{
return true;
}
// Cover Chrome 50-69, because some versions are broken by SameSite=None,
// and none in this range require it.
// Note: this covers some pre-Chromium Edge versions,
// but pre-Chromium Edge does not require SameSite=None.
if (userAgent.Contains("Chrome/5") || userAgent.Contains("Chrome/6"))
{
return true;
}
return false;
}
與遠端站台互動的應用程式 (例如透過第三方登入者) 必須:
- 在多個瀏覽器上測試互動。
- 套用本檔所討論的 瀏覽器偵測和風險降低 。
使用可加入加入新 SameSite
行為的用戶端版本來測試 Web 應用程式。 Chrome、Firefox 和 Chromium Edge 都有新的選擇加入功能旗標可用於測試。 您的應用程式套 SameSite
用修補程序之後,請使用舊版用戶端版本來測試修補程式,特別是Safari。 如需詳細資訊,請參閱本文件中的支援舊版瀏覽器。
Chrome 78+ 設置了暫時性緩和措施,因此會提供誤導性的結果。 Chrome 78+ 的暫時風險降低允許存留期不到兩分鐘的 cookies。 已啟用適當測試旗標的 Chrome 76 或 77 可提供更精確的結果。 若要測試新的SameSite
行為切換chrome://flags/#same-site-by-default-cookies
為 [已啟用]。 系統回報舊版的 Chrome (75 和更低版本) 在使用新的 None
設定時會失敗。 請參閱本文件中的支援舊版瀏覽器。
Google 不提供較舊的 Chrome 版本。 請依照下載 Chromium 中的指示,對舊版 Chrome 進行測試。 請不要用搜尋舊版 Chrome 所獲得的連結來下載 Chrome。
Safari 12 嚴格實作先前的草稿,並在新 None
值位於Cookie時失敗。 透過本文件的None
支援舊版瀏覽器中的瀏覽器偵測程式碼,可避免 。 使用 MSAL 或您使用的任何連結庫,測試 Safari 12、Safari 13 和 WebKit 型 OS 樣式登入。 問題相依於基礎 OS 版本。 OSX Mojave (10.14) 和 iOS 12 已知有新 SameSite
行為的相容性問題。 將 OS 升級至 OSX Catalina 10.15 或 iOS 13,可修正這個問題。 目前 Safari 不針對測試新規格行為提供選擇加入旗標。
Firefox 對新標準的支援可在版本 68+ 上測試,方法是在具有功能旗標 network.cookie.sameSite.laxByDefault
的 about:config
分頁上選擇加入。 目前為止並未回報任何舊版 Firefox 的相容性問題。
Edge 支援舊的 SameSite
標準。 Edge 44 版與新標準間沒有任何已知的相容性問題。
SameSite
旗標是在頁面上設定的 edge://flags/#same-site-by-default-cookies
。 未發現 Edge Chromium 的相容性問題。
Electron 的版本包括舊版 Chromium。 例如,Teams 所使用的電子版本是 Chromium 66,其呈現較舊的行為。 您必須使用產品所使用的電子版本執行自己的相容性測試。 請參閱下一節中的支援舊版瀏覽器。