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。
將 API 與 SameSite 搭配使用
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 草稿。 如需詳細資訊,請參閱本文件中的支援舊版瀏覽器。
- 指定預設會將
SameSite=Lax
Cookie 視為 。 - 指定明確判斷
SameSite=None
提示以啟用跨網站傳遞的 Cookie 應標示為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 問題
與遠端站台互動的應用程式 (例如透過第三方登入者) 必須:
- 在多個瀏覽器上測試互動。
- 套用本檔所討論的 瀏覽器偵測和風險降低 。
使用可加入加入新 SameSite
行為的用戶端版本來測試 Web 應用程式。 Chrome、Firefox 和 Chromium Edge 都有新的選擇加入功能旗標可用於測試。 您的應用程式套 SameSite
用修補程序之後,請使用舊版用戶端版本來測試修補程式,特別是Safari。 如需詳細資訊,請參閱本文件中的支援舊版瀏覽器。
使用 Chrome 進行測試
Chrome 78+ 設置了暫時性緩和措施,因此會提供誤導性的結果。 Chrome 78+ 暫存風險降低允許不到兩分鐘的 Cookie。 已啟用適當測試旗標的 Chrome 76 或 77 可提供更精確的結果。 若要測試新的SameSite
行為切換chrome://flags/#same-site-by-default-cookies
為 [已啟用]。 系統回報舊版的 Chrome (75 和更低版本) 在使用新的 None
設定時會失敗。 請參閱本文件中的支援舊版瀏覽器。
Google 不提供較舊的 Chrome 版本。 請依照下載 Chromium 中的指示,對舊版 Chrome 進行測試。 請不要用搜尋舊版 Chrome 所獲得的連結來下載 Chrome。
使用 Safari 進行測試
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 進行測試
Firefox 對新標準的支援可在版本 68+ 上測試,方法是在具有功能旗標 network.cookie.sameSite.laxByDefault
的 about:config
分頁上選擇加入。 目前為止並未回報任何舊版 Firefox 的相容性問題。
使用 Edge 瀏覽器進行測試
Edge 支援舊的 SameSite
標準。 Edge 44 版與新標準間沒有任何已知的相容性問題。
使用 Edge (Chromium) 進行測試
SameSite
旗標是在頁面上設定的 edge://flags/#same-site-by-default-cookies
。 未發現 Edge Chromium 的相容性問題。
使用電子進行測試
Electron 的版本包括舊版 Chromium。 例如,Teams 所使用的電子版本是 Chromium 66,其呈現較舊的行為。 您必須使用產品所使用的電子版本執行自己的相容性測試。 請參閱下一節中的支援舊版瀏覽器。