Arbeiten mit SameSite-Cookies in ASP.NET Core.
Von Rick Anderson
SameSite ist ein IETF-Entwurfsstandard, der einen gewissen Schutz vor Angriffen durch siteübergreifende Anforderungsfälschung (Cross-Site Request Forgery, CSRF) bieten soll. Ursprünglich wurde der Entwurfsstandard in 2016 entworfen und in 2019 aktualisiert. Der aktualisierte Standard ist nicht abwärtskompatibel mit dem vorherigen Standard, wobei die folgenden Unterschiede am deutlichsten sind:
- Cookies ohne SameSite-Header werden standardmäßig als
SameSite=Lax
behandelt. SameSite=None
muss verwendet werden, um eine siteübergreifende cookie-Verwendung zu ermöglichen.- Cookies, die
SameSite=None
bestätigen, müssen auch alsSecure
markiert werden. - Bei Anwendungen, die
<iframe>
verwenden, kann es zu Problemen mitsameSite=Lax
odersameSite=Strict
s kommen, da<iframe>
als Site-übergreifende Szenarien behandelt wird. - Der Wert
SameSite=None
ist nach dem Standard von 2016 nicht zulässig und führt dazu, dass einige Implementierungen solche Cookies alsSameSite=Strict
behandeln. Weitere Informationen finden Sie unter Unterstützung älterer Browser in diesem Dokument.
Die Einstellung SameSite=Lax
funktioniert für die meisten Anwendungs-Cookies. Einige Formen der Authentifizierung wie OpenID Connect (OIDC) und Webdiensteverbund verwenden standardmäßig POST-basierte Umleitungen. Die POST-basierten Umleitungen lösen die SameSite-Browserschutzmaßnahmen aus, sodass SameSite für diese Komponenten deaktiviert ist. Die meisten OAuth-Anmeldungen sind davon nicht betroffen, da die Anforderungen unterschiedlich verlaufen.
Jede ASP.NET Core-Komponente, die Cookies ausgibt, muss entscheiden, ob SameSite angemessen ist.
SameSite und Identity
ASP.NET Core Identity ist von SameSite-Cookies weitgehend unbeeinflusst, außer bei erweiterten Szenarien wie der Integration von IFrames
oder OpenIdConnect
.
Wenn Sie Identity
verwenden, fügen Sie keinecookie-Anbieter hinzu und rufen services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
nicht auf. Identity
übernimmt dies.
SameSite-Testbeispielcode
Das folgende Beispiel kann heruntergeladen und getestet werden:
Beispiel | Dokument |
---|---|
.NET Core Razor Pages | ASP.NET Core 3.1 Razor Pages: Beispiel für SameSite-cookies |
.NET Core-Unterstützung für das sameSite-Attribut
.NET Core unterstützt den Entwurfsstandard von 2019 für SameSite. Entwickler können den Wert des sameSite-Attributs mithilfe der Eigenschaft HttpCookie.SameSite
programmgesteuert steuern. Wenn Sie die Eigenschaft SameSite
auf Strict
, Lax
oder None
festlegen, werden diese Werte mit dem cookie in das Netzwerk geschrieben. Das Festlegen auf SameSiteMode.Unspecified
bedeutet, dass kein sameSite-Attribut mit dem cookie gesendet werden soll.
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.
SameSite = SameSiteMode.None
// The client should follow its default cookie policy.
// SameSite = SameSiteMode.Unspecified
};
// Add the cookie to the response cookie collection
Response.Cookies.Append("MyCookie", "cookieValue", cookieOptions);
}
API-Verwendung mit SameSite
HttpContext.Response.Cookies.Append ist standardmäßig auf Unspecified
festgelegt, d. h. es wird kein SameSite-Attribut an das cookie angefügt und der Client verwendet sein Standardverhalten („Lax“ für neue Browser, „None“ für alte). Der folgende Code zeigt, wie Sie den cookie SameSite-Wert in SameSiteMode.Lax
ändern:
HttpContext.Response.Cookies.Append(
"name", "value",
new CookieOptions() { SameSite = SameSiteMode.Lax });
Alle ASP.NET Core-Komponenten, die Cookies ausgeben, überschreiben die vorangehenden Standardwerte mit Einstellungen, die für ihre Szenarien geeignet sind. Die außer Kraft gesetzten vorangehenden Standardwerte haben sich nicht geändert.
ASP.NET Core 3.1 und höher bietet die folgende SameSite-Unterstützung:
- Definiert das Verhalten von
SameSiteMode.None
neu, umSameSite=None
auszugeben. - Fügt einen neuen
SameSiteMode.Unspecified
-Wert hinzu, um das SameSite-Attribut auszulassen. - Alle Cookies-APIs sind standardmäßig
Unspecified
. Einige Komponenten, die Cookies verwenden, legen Werte fest, die spezifischer für ihre Szenarien sind. Beispiele finden Sie in der obigen Tabelle.
In ASP.NET Core 3.0 und höher wurden die SameSite-Standardwerte geändert, um Konflikte mit inkonsistenten Clientstandardwerten zu vermeiden. Die folgenden APIs haben den Standard von SameSiteMode.Lax
in -1
geändert, um zu vermeiden, dass ein SameSite-Attribut für diese Cookies ausgegeben wird:
- CookieOptions verwendet mit HttpContext.Response.Cookies.Append
- CookieBuilder wurde als Factory für
CookieOptions
verwendet - CookiePolicyOptions.MinimumSameSitePolicy
Verlauf und Änderungen
Die SameSite-Unterstützung wurde erstmals in ASP.NET Core 2.0 mithilfe des Entwurfsstandards von 2016 implementiert. Der Standard von 2016 wurde abonniert. ASP.NET Core wurde abonniert, indem mehrere Cookies standardmäßig auf Lax
festgelegt wurden. Nachdem mehrere Probleme mit der Authentifizierung aufgetreten waren, wurde der Großteil der SameSite-Nutzung deaktiviert.
Patches wurden im November 2019 veröffentlicht, um vom Standard von 2016 auf den Standard von 2019 zu aktualisieren. Der Entwurf von 2019 der SameSite-Spezifikation:
- Er ist nicht abwärtskompatibel mit dem Entwurf von 2016. Weitere Informationen finden Sie unter Unterstützung älterer Browser in diesem Dokument.
- Gibt an, dass Cookies standardmäßig als
SameSite=Lax
behandelt werden. - Gibt an, dass Cookies, die explizit
SameSite=None
bestätigen, um eine Site-übergreifende Zustellung zu ermöglichen, alsSecure
markiert werden sollen.None
ist ein neuer Eintrag zum Kündigen des Abonnements. - Wird von Patches für ASP.NET Core 2.1, 2.2 und 3.0 unterstützt. ASP.NET Core 3.1 und höher bietet zusätzliche Unterstützung für SameSite.
- Wurde von Chrome standardmäßig im Februar 2020 aktiviert. Die Browser werden seit 2019 auf diesen Standard umgestellt.
APIs, die von der Änderung des SameSite-Entwurfsstandards von 2016 zum Entwurfsstandard von 2019 betroffen sind
- Http.SameSiteMode
- CookieOptions.SameSite
- CookieBuilder.SameSite
- CookiePolicyOptions.MinimumSameSitePolicy
- Microsoft.Net.Http.Headers.SameSiteMode
- Microsoft.Net.Http.Headers.SetCookieHeaderValue.SameSite
Unterstützung älterer Browser
Der SameSite-Standard von 2016 schreibt vor, dass unbekannte Werte als SameSite=Strict
-Werte behandelt werden müssen. Apps, auf die von älteren Browsern aus zugegriffen wird, die den SameSite-Standard von 2016 unterstützen, können unterbrochen werden, wenn sie eine SameSite-Eigenschaft mit einem Wert von None
erhalten. Web-Apps müssen eine Browsererkennung implementieren, wenn sie ältere Browser unterstützen wollen. ASP.NET Core implementiert keine Browsererkennung, da die Werte von Benutzer-Agents sehr veränderlich sind und sich häufig ändern. Ein Erweiterungspunkt in Microsoft.AspNetCore.CookiePolicy ermöglicht die Integration von Logik, die für Benutzer-Agents spezifisch ist.
Fügen Sie in Program.cs
Code hinzu, der UseCookiePolicy aufruft, bevor Sie UseAuthentication oder irgendeine Methode aufrufen, die Cookies schreibt:
var builder = WebApplication.CreateBuilder(args);
builder.Services.Configure<CookiePolicyOptions>(options =>
{
options.MinimumSameSitePolicy = SameSiteMode.Unspecified;
options.OnAppendCookie = cookieContext =>
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
options.OnDeleteCookie = cookieContext =>
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
});
void CheckSameSite(HttpContext httpContext, CookieOptions options)
{
if (options.SameSite == SameSiteMode.None)
{
var userAgent = httpContext.Request.Headers["User-Agent"].ToString();
if (MyUserAgentDetectionLib.DisallowsSameSiteNone(userAgent))
{
options.SameSite = SameSiteMode.Unspecified;
}
}
}
builder.Services.AddRazorPages();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseCookiePolicy();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
Fügen Sie in Program.cs
einen Code ähnlich dem folgenden hervorgehobenen Code ein:
var builder = WebApplication.CreateBuilder(args);
builder.Services.Configure<CookiePolicyOptions>(options =>
{
options.MinimumSameSitePolicy = SameSiteMode.Unspecified;
options.OnAppendCookie = cookieContext =>
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
options.OnDeleteCookie = cookieContext =>
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
});
void CheckSameSite(HttpContext httpContext, CookieOptions options)
{
if (options.SameSite == SameSiteMode.None)
{
var userAgent = httpContext.Request.Headers["User-Agent"].ToString();
if (MyUserAgentDetectionLib.DisallowsSameSiteNone(userAgent))
{
options.SameSite = SameSiteMode.Unspecified;
}
}
}
builder.Services.AddRazorPages();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseCookiePolicy();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
Im vorangehenden Beispiel ist MyUserAgentDetectionLib.DisallowsSameSiteNone
eine vom Benutzer bereitgestellte Bibliothek, die erkennt, ob der Benutzer-Agent SameSite None
nicht unterstützt:
if (MyUserAgentDetectionLib.DisallowsSameSiteNone(userAgent))
{
options.SameSite = SameSiteMode.Unspecified;
}
Der folgende Code zeigt ein Beispiel für eine DisallowsSameSiteNone
-Methode:
Warnung
Der folgende Code dient nur zur Demonstration:
- Er sollte nicht als vollständig betrachtet werden.
- Er wird nicht verwaltet oder unterstützt.
public static bool DisallowsSameSiteNone(string userAgent)
{
// Check if a null or empty string has been passed in, since this
// will cause further interrogation of the useragent to fail.
if (String.IsNullOrWhiteSpace(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;
}
Testen von Apps für SameSite-Probleme
Apps, die mit Remotestandorten interagieren, z. B. über die Anmeldung über Drittanbieter, müssen folgende Aktionen ausführen:
- Testen Sie die Interaktion auf mehreren Browsern.
- Wenden Sie die Erkennung und Entschärfung für den Richtlinienbrowser an, die in diesem Dokument beschrieben werden.
Testen Sie Web-Apps mithilfe einer Clientversion, die das neue SameSite-Verhalten abonnieren kann. Chrome, Firefox und Chromium Edge verfügen über neue Featureflags, die für Tests verwendet werden können. Nachdem Ihre App die SameSite-Patches angewendet hat, testen Sie sie mit älteren Clientversionen, insbesondere Safari. Weitere Informationen finden Sie unter Unterstützung älterer Browser in diesem Dokument.
Testen mit Chrome
Chrome 78+ liefert irreführende Ergebnisse, da es eine vorübergehende Risikominderung aufweist. Die temporäre Risikominderung von Chrome 78+ gestattet Cookies, die weniger als zwei Minuten alt sind. Chrome 76 oder 77 mit den entsprechenden aktivierten Testflags liefert genauere Ergebnisse. Um das neue SameSite-Verhalten zu testen, schalten Sie chrome://flags/#same-site-by-default-cookies
auf Aktiviert um. Bei älteren Versionen von Chrome (75 und niedriger) wird gemeldet, dass mit der neuen None
-Einstellung ein Fehler auftritt. Weitere Informationen finden Sie unter Unterstützung älterer Browser in diesem Dokument.
Google stellt keine älteren Chrome-Versionen zur Verfügung. Befolgen Sie die Anweisungen unter Herunterladen von Chromium, um ältere Versionen von Chrome zu testen. Laden Sie Chrome nicht über Links herunter, die bei der Suche nach älteren Versionen von Chrome bereitgestellt werden.
Ab der Canary-Version 80.0.3975.0
kann die temporäre Lax+POST-Entschärfung mithilfe des neuen --enable-features=SameSiteDefaultChecksMethodRigorously
-Flags zu Testzwecken deaktiviert werden, um das Testen von Websites und Diensten im möglichen Endzustand des Features zu ermöglichen, in dem die Entschärfung entfernt wurde. Weitere Informationen finden Sie unter „The Chromium Projects“ SameSite Updates.
Testen mit Safari
Safari 12 hat den vorherigen Entwurf strikt umgesetzt und weist einen Fehler auf, wenn sich der neue None
-Wert in einem cookie befindet. None
wird über den Browsererkennungscode vermieden: Unterstützung älterer Browser in diesem Dokument. Testen Sie Anmeldungen im Stil von Safari 12, Safari 13 und WebKit-basierten Betriebssystemen mithilfe von MSAL, ADAL oder der von Ihnen verwendeten Bibliothek. Das Problem hängt von der zugrunde liegenden Betriebssystemversion ab. Bei OSX Mojave (10.14) und iOS 12 sind Kompatibilitätsprobleme mit dem neuen SameSite-Verhalten bekannt. Das Problem lässt sich mit einem Upgrade des Betriebssystems auf OSX Catalina (10.15) bzw. iOS 13 beheben. Safari verfügt derzeit nicht über ein Aktivierungsflag zum Testen des neuen Spezifikationsverhaltens.
Testen mit Firefox
Die Firefox-Unterstützung für den neuen Standard kann in Version 68+ getestet werden, indem Sie sich auf der Seite about:config
mit dem Featureflag network.cookie.sameSite.laxByDefault
anmelden. Es liegen keine Berichte über Kompatibilitätsprobleme mit älteren Versionen von Firefox vor.
Testen mit dem Edge-Browser
Edge unterstützt den alten SameSite-Standard. Die Edge-Version 44 weist keine bekannten Kompatibilitätsprobleme mit dem neuen Standard auf.
Testen mit Edge (Chromium)
SameSite-Flags werden auf der Seite edge://flags/#same-site-by-default-cookies
festgelegt. Es wurden keine Kompatibilitätsprobleme mit Edge Chromium festgestellt.
Testen mit Electron
Die Versionen von Electron umfassen ältere Versionen von Chromium. Die von Teams verwendete Version von Electron ist z. B. Chromium 66, die das ältere Verhalten aufweist. Sie müssen Ihre eigenen Kompatibilitätstests mit der Version von Electron durchführen, die in Ihrem Produkt verwendet wird. Weitere Informationen finden Sie unter Unterstützung älterer Browser im folgenden Abschnitt.
Zusätzliche Ressourcen
- Chromium-Blog:Entwickler: Vorbereiten auf neues SameSite=None; Sichere Cookie-Einstellungen
- Erläuterung von SameSite-Cookies
- Patches von November 2019
Beispiel | Dokument |
---|---|
.NET Core Razor Pages | ASP.NET Core 3.1 Razor Pages: Beispiel für SameSite-cookies |
Das folgende Beispiel kann heruntergeladen und getestet werden:
Beispiel | Dokument |
---|---|
.NET Core Razor Pages | ASP.NET Core 3.1 Razor Pages: Beispiel für SameSite-cookies |
.NET Core-Unterstützung für das sameSite-Attribut
.NET Core 3.1 und höher unterstützt den Entwurfsstandard von 2019 für SameSite. Entwickler können den Wert des sameSite-Attributs mithilfe der Eigenschaft HttpCookie.SameSite
programmgesteuert steuern. Wenn Sie die Eigenschaft SameSite
auf „Strict“, „Lax“ oder „None“ festlegen, werden diese Werte mit dem cookie in das Netzwerk geschrieben. Das Festlegen auf (SameSiteMode)(-1)
bedeutet, dass kein sameSite-Attribut im Netzwerk mit dem cookie einbezogen werden soll.
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
// SameSite = (SameSiteMode)(-1)
SameSite = SameSiteMode.None
};
// Add the cookie to the response cookie collection
Response.Cookies.Append("MyCookie", "cookieValue", cookieOptions);
.NET Core 3.1 und spätere Versionen unterstützen die aktualisierten SameSite-Werte und fügen einen zusätzlichen Enumerationswert, SameSiteMode.Unspecified
, zur SameSiteMode
-Enumeration hinzu.
Dieser neue Wert zeigt an, dass kein sameSite-Attribut mit dem cookie gesendet werden sollte.
API-Verwendung mit SameSite
HttpContext.Response.Cookies.Append ist standardmäßig auf Unspecified
festgelegt, d. h. es wird kein SameSite-Attribut an das cookie angefügt und der Client verwendet sein Standardverhalten („Lax“ für neue Browser, „None“ für alte). Der folgende Code zeigt, wie Sie den cookie SameSite-Wert in SameSiteMode.Lax
ändern:
HttpContext.Response.Cookies.Append(
"name", "value",
new CookieOptions() { SameSite = SameSiteMode.Lax });
Alle ASP.NET Core-Komponenten, die Cookies ausgeben, überschreiben die vorangehenden Standardwerte mit Einstellungen, die für ihre Szenarien geeignet sind. Die außer Kraft gesetzten vorangehenden Standardwerte haben sich nicht geändert.
ASP.NET Core 3.1 und höher bietet die folgende SameSite-Unterstützung:
- Definiert das Verhalten von
SameSiteMode.None
neu, umSameSite=None
auszugeben. - Fügt einen neuen
SameSiteMode.Unspecified
-Wert hinzu, um das SameSite-Attribut auszulassen. - Alle Cookies-APIs sind standardmäßig
Unspecified
. Einige Komponenten, die Cookies verwenden, legen Werte fest, die spezifischer für ihre Szenarien sind. Beispiele finden Sie in der obigen Tabelle.
In ASP.NET Core 3.0 und höher wurden die SameSite-Standardwerte geändert, um Konflikte mit inkonsistenten Clientstandardwerten zu vermeiden. Die folgenden APIs haben den Standard von SameSiteMode.Lax
in -1
geändert, um zu vermeiden, dass ein SameSite-Attribut für diese Cookies ausgegeben wird:
- CookieOptions verwendet mit HttpContext.Response.Cookies.Append
- CookieBuilder wurde als Factory für
CookieOptions
verwendet - CookiePolicyOptions.MinimumSameSitePolicy
Verlauf und Änderungen
Die SameSite-Unterstützung wurde erstmals in ASP.NET Core 2.0 mithilfe des Entwurfsstandards von 2016 implementiert. Der Standard von 2016 wurde abonniert. ASP.NET Core wurde abonniert, indem mehrere Cookies standardmäßig auf Lax
festgelegt wurden. Nachdem mehrere Probleme mit der Authentifizierung aufgetreten waren, wurde der Großteil der SameSite-Nutzung deaktiviert.
Patches wurden im November 2019 veröffentlicht, um vom Standard von 2016 auf den Standard von 2019 zu aktualisieren. Der Entwurf von 2019 der SameSite-Spezifikation:
- Er ist nicht abwärtskompatibel mit dem Entwurf von 2016. Weitere Informationen finden Sie unter Unterstützung älterer Browser in diesem Dokument.
- Gibt an, dass Cookies standardmäßig als
SameSite=Lax
behandelt werden. - Gibt an, dass Cookies, die explizit
SameSite=None
bestätigen, um eine Site-übergreifende Zustellung zu ermöglichen, alsSecure
markiert werden sollen.None
ist ein neuer Eintrag zum Kündigen des Abonnements. - Wird von Patches für ASP.NET Core 2.1, 2.2 und 3.0 unterstützt. ASP.NET Core 3.1 bietet zusätzliche Unterstützung für SameSite.
- Wurde von Chrome standardmäßig im Februar 2020 aktiviert. Die Browser werden seit 2019 auf diesen Standard umgestellt.
APIs, die von der Änderung des SameSite-Entwurfsstandards von 2016 zum Entwurfsstandard von 2019 betroffen sind
- Http.SameSiteMode
- CookieOptions.SameSite
- CookieBuilder.SameSite
- CookiePolicyOptions.MinimumSameSitePolicy
- Microsoft.Net.Http.Headers.SameSiteMode
- Microsoft.Net.Http.Headers.SetCookieHeaderValue.SameSite
Unterstützung älterer Browser
Der SameSite-Standard von 2016 schreibt vor, dass unbekannte Werte als SameSite=Strict
-Werte behandelt werden müssen. Apps, auf die von älteren Browsern aus zugegriffen wird, die den SameSite-Standard von 2016 unterstützen, können unterbrochen werden, wenn sie eine SameSite-Eigenschaft mit einem Wert von None
erhalten. Web-Apps müssen eine Browsererkennung implementieren, wenn sie ältere Browser unterstützen wollen. ASP.NET Core implementiert keine Browsererkennung, da die Werte von Benutzer-Agents sehr veränderlich sind und sich häufig ändern. Ein Erweiterungspunkt in Microsoft.AspNetCore.CookiePolicy ermöglicht die Integration von Logik, die für Benutzer-Agents spezifisch ist.
Fügen Sie in Startup.Configure
Code hinzu, der UseCookiePolicy aufruft, bevor Sie UseAuthentication oder irgendeine Methode aufrufen, die Cookies schreibt:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseCookiePolicy();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
Fügen Sie in Startup.ConfigureServices
einen Code ähnlich dem folgenden hinzu:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
options.MinimumSameSitePolicy = SameSiteMode.Unspecified;
options.OnAppendCookie = cookieContext =>
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
options.OnDeleteCookie = cookieContext =>
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
});
services.AddRazorPages();
}
private void CheckSameSite(HttpContext httpContext, CookieOptions options)
{
if (options.SameSite == SameSiteMode.None)
{
var userAgent = httpContext.Request.Headers["User-Agent"].ToString();
if (MyUserAgentDetectionLib.DisallowsSameSiteNone(userAgent))
{
options.SameSite = SameSiteMode.Unspecified;
}
}
}
Im vorangehenden Beispiel ist MyUserAgentDetectionLib.DisallowsSameSiteNone
eine vom Benutzer bereitgestellte Bibliothek, die erkennt, ob der Benutzer-Agent SameSite None
nicht unterstützt:
if (MyUserAgentDetectionLib.DisallowsSameSiteNone(userAgent))
{
options.SameSite = SameSiteMode.Unspecified;
}
Der folgende Code zeigt ein Beispiel für eine DisallowsSameSiteNone
-Methode:
Warnung
Der folgende Code dient nur zur Demonstration:
- Er sollte nicht als vollständig betrachtet werden.
- Er wird nicht verwaltet oder unterstützt.
public static bool DisallowsSameSiteNone(string userAgent)
{
// Check if a null or empty string has been passed in, since this
// will cause further interrogation of the useragent to fail.
if (String.IsNullOrWhiteSpace(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;
}
Testen von Apps für SameSite-Probleme
Apps, die mit Remotestandorten interagieren, z. B. über die Anmeldung über Drittanbieter, müssen folgende Aktionen ausführen:
- Testen Sie die Interaktion auf mehreren Browsern.
- Wenden Sie die Erkennung und Entschärfung für den Richtlinienbrowser an, die in diesem Dokument beschrieben werden.
Testen Sie Web-Apps mithilfe einer Clientversion, die das neue SameSite-Verhalten abonnieren kann. Chrome, Firefox und Chromium Edge verfügen über neue Featureflags, die für Tests verwendet werden können. Nachdem Ihre App die SameSite-Patches angewendet hat, testen Sie sie mit älteren Clientversionen, insbesondere Safari. Weitere Informationen finden Sie unter Unterstützung älterer Browser in diesem Dokument.
Testen mit Chrome
Chrome 78+ liefert irreführende Ergebnisse, da es eine vorübergehende Risikominderung aufweist. Die temporäre Risikominderung von Chrome 78+ gestattet Cookies, die weniger als zwei Minuten alt sind. Chrome 76 oder 77 mit den entsprechenden aktivierten Testflags liefert genauere Ergebnisse. Um das neue SameSite-Verhalten zu testen, schalten Sie chrome://flags/#same-site-by-default-cookies
auf Aktiviert um. Bei älteren Versionen von Chrome (75 und niedriger) wird gemeldet, dass mit der neuen None
-Einstellung ein Fehler auftritt. Weitere Informationen finden Sie unter Unterstützung älterer Browser in diesem Dokument.
Google stellt keine älteren Chrome-Versionen zur Verfügung. Befolgen Sie die Anweisungen unter Herunterladen von Chromium, um ältere Versionen von Chrome zu testen. Laden Sie Chrome nicht über Links herunter, die bei der Suche nach älteren Versionen von Chrome bereitgestellt werden.
Ab der Canary-Version 80.0.3975.0
kann die temporäre Lax+POST-Entschärfung mithilfe des neuen --enable-features=SameSiteDefaultChecksMethodRigorously
-Flags zu Testzwecken deaktiviert werden, um das Testen von Websites und Diensten im möglichen Endzustand des Features zu ermöglichen, in dem die Entschärfung entfernt wurde. Weitere Informationen finden Sie unter „The Chromium Projects“ SameSite Updates.
Testen mit Safari
Safari 12 hat den vorherigen Entwurf strikt umgesetzt und weist einen Fehler auf, wenn sich der neue None
-Wert in einem cookie befindet. None
wird über den Browsererkennungscode vermieden: Unterstützung älterer Browser in diesem Dokument. Testen Sie Anmeldungen im Stil von Safari 12, Safari 13 und WebKit-basierten Betriebssystemen mithilfe von MSAL, ADAL oder der von Ihnen verwendeten Bibliothek. Das Problem hängt von der zugrunde liegenden Betriebssystemversion ab. Bei OSX Mojave (10.14) und iOS 12 sind Kompatibilitätsprobleme mit dem neuen SameSite-Verhalten bekannt. Das Problem lässt sich mit einem Upgrade des Betriebssystems auf OSX Catalina (10.15) bzw. iOS 13 beheben. Safari verfügt derzeit nicht über ein Aktivierungsflag zum Testen des neuen Spezifikationsverhaltens.
Testen mit Firefox
Die Firefox-Unterstützung für den neuen Standard kann in Version 68+ getestet werden, indem Sie sich auf der Seite about:config
mit dem Featureflag network.cookie.sameSite.laxByDefault
anmelden. Es liegen keine Berichte über Kompatibilitätsprobleme mit älteren Versionen von Firefox vor.
Testen mit dem Edge-Browser
Edge unterstützt den alten SameSite-Standard. Die Edge-Version 44 weist keine bekannten Kompatibilitätsprobleme mit dem neuen Standard auf.
Testen mit Edge (Chromium)
SameSite-Flags werden auf der Seite edge://flags/#same-site-by-default-cookies
festgelegt. Es wurden keine Kompatibilitätsprobleme mit Edge Chromium festgestellt.
Testen mit Electron
Die Versionen von Electron umfassen ältere Versionen von Chromium. Die von Teams verwendete Version von Electron ist z. B. Chromium 66, die das ältere Verhalten aufweist. Sie müssen Ihre eigenen Kompatibilitätstests mit der Version von Electron durchführen, die in Ihrem Produkt verwendet wird. Weitere Informationen finden Sie unter Unterstützung älterer Browser im folgenden Abschnitt.
Zusätzliche Ressourcen
- Chromium-Blog:Entwickler: Vorbereiten auf neues SameSite=None; Sichere Cookie-Einstellungen
- Erläuterung von SameSite-Cookies
- Patches von November 2019
Beispiel | Dokument |
---|---|
.NET Core Razor Pages | ASP.NET Core 3.1 Razor Pages: Beispiel für SameSite-cookies |
Die folgenden Beispiele können heruntergeladen und getestet werden:
Beispiel | Dokument |
---|---|
.NET Core MVC | ASP.NET Core 2.1 MVC SameSite-cookie-Beispiel |
.NET Core Razor Pages | ASP.NET Core 2.1 Razor Pages: Beispiel für SameSite-cookies |
Behavior Changes durch den Dezember-Patch
Die spezifische Behavior Change für .NET Framework und .NET Core 2.1 besteht darin, wie die Eigenschaft SameSite
den None
-Wert interpretiert. Vor dem Patch bedeutete ein Wert von None
„Das Attribut überhaupt nicht ausgeben“, nach dem Patch bedeutet es „Das Attribut mit einem Wert von None
ausgeben“. Nach dem Patch bewirkt ein SameSite
-Wert von (SameSiteMode)(-1)
, dass das Attribut nicht ausgegeben wird.
Der SameSite-Standardwert für die Formularauthentifizierung und für Sitzungszustands-Cookies wurde von None
in Lax
geändert.
API-Verwendung mit SameSite
HttpContext.Response.Cookies.Append ist standardmäßig auf Unspecified
festgelegt, d. h. es wird kein SameSite-Attribut an das cookie angefügt und der Client verwendet sein Standardverhalten („Lax“ für neue Browser, „None“ für alte). Der folgende Code zeigt, wie Sie den cookie SameSite-Wert in SameSiteMode.Lax
ändern:
HttpContext.Response.Cookies.Append(
"name", "value",
new CookieOptions() { SameSite = SameSiteMode.Lax });
Alle ASP.NET Core-Komponenten, die Cookies ausgeben, überschreiben die vorangehenden Standardwerte mit Einstellungen, die für ihre Szenarien geeignet sind. Die außer Kraft gesetzten vorangehenden Standardwerte haben sich nicht geändert.
Verlauf und Änderungen
Die SameSite-Unterstützung wurde erstmals in ASP.NET Core 2.0 mithilfe des Entwurfsstandards von 2016 implementiert. Der Standard von 2016 wurde abonniert. ASP.NET Core wurde abonniert, indem mehrere Cookies standardmäßig auf Lax
festgelegt wurden. Nachdem mehrere Probleme mit der Authentifizierung aufgetreten waren, wurde der Großteil der SameSite-Nutzung deaktiviert.
Patches wurden im November 2019 veröffentlicht, um vom Standard von 2016 auf den Standard von 2019 zu aktualisieren. Der Entwurf von 2019 der SameSite-Spezifikation:
- Er ist nicht abwärtskompatibel mit dem Entwurf von 2016. Weitere Informationen finden Sie unter Unterstützung älterer Browser in diesem Dokument.
- Gibt an, dass Cookies standardmäßig als
SameSite=Lax
behandelt werden. - Gibt an, dass Cookies, die explizit
SameSite=None
bestätigen, um eine Site-übergreifende Zustellung zu ermöglichen, alsSecure
markiert werden sollen.None
ist ein neuer Eintrag zum Kündigen des Abonnements. - Wird von Patches für ASP.NET Core 2.1, 2.2 und 3.0 unterstützt. ASP.NET Core 3.1 bietet zusätzliche Unterstützung für SameSite.
- Wurde von Chrome standardmäßig im Februar 2020 aktiviert. Die Browser werden seit 2019 auf diesen Standard umgestellt.
APIs, die von der Änderung des SameSite-Entwurfsstandards von 2016 zum Entwurfsstandard von 2019 betroffen sind
- Http.SameSiteMode
- CookieOptions.SameSite
- CookieBuilder.SameSite
- CookiePolicyOptions.MinimumSameSitePolicy
- Microsoft.Net.Http.Headers.SameSiteMode
- Microsoft.Net.Http.Headers.SetCookieHeaderValue.SameSite
Unterstützung älterer Browser
Der SameSite-Standard von 2016 schreibt vor, dass unbekannte Werte als SameSite=Strict
-Werte behandelt werden müssen. Apps, auf die von älteren Browsern aus zugegriffen wird, die den SameSite-Standard von 2016 unterstützen, können unterbrochen werden, wenn sie eine SameSite-Eigenschaft mit einem Wert von None
erhalten. Web-Apps müssen eine Browsererkennung implementieren, wenn sie ältere Browser unterstützen wollen. ASP.NET Core implementiert keine Browsererkennung, da die Werte von Benutzer-Agents sehr veränderlich sind und sich häufig ändern. Ein Erweiterungspunkt in Microsoft.AspNetCore.CookiePolicy ermöglicht die Integration von Logik, die für Benutzer-Agents spezifisch ist.
Fügen Sie in Startup.Configure
Code hinzu, der UseCookiePolicy aufruft, bevor Sie UseAuthentication oder irgendeine Methode aufrufen, die Cookies schreibt:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseCookiePolicy();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
Fügen Sie in Startup.ConfigureServices
einen Code ähnlich dem folgenden hinzu:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
options.MinimumSameSitePolicy = (SameSiteMode)(-1);
options.OnAppendCookie = cookieContext =>
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
options.OnDeleteCookie = cookieContext =>
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
});
services.AddRazorPages();
}
private void CheckSameSite(HttpContext httpContext, CookieOptions options)
{
if (options.SameSite == SameSiteMode.None)
{
var userAgent = httpContext.Request.Headers["User-Agent"].ToString();
if (MyUserAgentDetectionLib.DisallowsSameSiteNone(userAgent))
{
options.SameSite = (SameSiteMode)(-1);
}
}
}
Im vorangehenden Beispiel ist MyUserAgentDetectionLib.DisallowsSameSiteNone
eine vom Benutzer bereitgestellte Bibliothek, die erkennt, ob der Benutzer-Agent SameSite None
nicht unterstützt:
if (MyUserAgentDetectionLib.DisallowsSameSiteNone(userAgent))
{
options.SameSite = SameSiteMode.Unspecified;
}
Der folgende Code zeigt ein Beispiel für eine DisallowsSameSiteNone
-Methode:
Warnung
Der folgende Code dient nur zur Demonstration:
- Er sollte nicht als vollständig betrachtet werden.
- Er wird nicht verwaltet oder unterstützt.
public static bool DisallowsSameSiteNone(string userAgent)
{
// Check if a null or empty string has been passed in, since this
// will cause further interrogation of the useragent to fail.
if (String.IsNullOrWhiteSpace(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;
}
Testen von Apps für SameSite-Probleme
Apps, die mit Remotestandorten interagieren, z. B. über die Anmeldung über Drittanbieter, müssen folgende Aktionen ausführen:
- Testen Sie die Interaktion auf mehreren Browsern.
- Wenden Sie die Erkennung und Entschärfung für den Richtlinienbrowser an, die in diesem Dokument beschrieben werden.
Testen Sie Web-Apps mithilfe einer Clientversion, die das neue SameSite-Verhalten abonnieren kann. Chrome, Firefox und Chromium Edge verfügen über neue Featureflags, die für Tests verwendet werden können. Nachdem Ihre App die SameSite-Patches angewendet hat, testen Sie sie mit älteren Clientversionen, insbesondere Safari. Weitere Informationen finden Sie unter Unterstützung älterer Browser in diesem Dokument.
Testen mit Chrome
Chrome 78+ liefert irreführende Ergebnisse, da es eine vorübergehende Risikominderung aufweist. Die temporäre Risikominderung von Chrome 78+ gestattet Cookies, die weniger als zwei Minuten alt sind. Chrome 76 oder 77 mit den entsprechenden aktivierten Testflags liefert genauere Ergebnisse. Um das neue SameSite-Verhalten zu testen, schalten Sie chrome://flags/#same-site-by-default-cookies
auf Aktiviert um. Bei älteren Versionen von Chrome (75 und niedriger) wird gemeldet, dass mit der neuen None
-Einstellung ein Fehler auftritt. Weitere Informationen finden Sie unter Unterstützung älterer Browser in diesem Dokument.
Google stellt keine älteren Chrome-Versionen zur Verfügung. Befolgen Sie die Anweisungen unter Herunterladen von Chromium, um ältere Versionen von Chrome zu testen. Laden Sie Chrome nicht über Links herunter, die bei der Suche nach älteren Versionen von Chrome bereitgestellt werden.
Ab der Canary-Version 80.0.3975.0
kann die temporäre Lax+POST-Entschärfung mithilfe des neuen --enable-features=SameSiteDefaultChecksMethodRigorously
-Flags zu Testzwecken deaktiviert werden, um das Testen von Websites und Diensten im möglichen Endzustand des Features zu ermöglichen, in dem die Entschärfung entfernt wurde. Weitere Informationen finden Sie unter „The Chromium Projects“ SameSite Updates.
Testen mit Safari
Safari 12 hat den vorherigen Entwurf strikt umgesetzt und weist einen Fehler auf, wenn sich der neue None
-Wert in einem cookie befindet. None
wird über den Browsererkennungscode vermieden: Unterstützung älterer Browser in diesem Dokument. Testen Sie Anmeldungen im Stil von Safari 12, Safari 13 und WebKit-basierten Betriebssystemen mithilfe von MSAL, ADAL oder der von Ihnen verwendeten Bibliothek. Das Problem hängt von der zugrunde liegenden Betriebssystemversion ab. Bei OSX Mojave (10.14) und iOS 12 sind Kompatibilitätsprobleme mit dem neuen SameSite-Verhalten bekannt. Das Problem lässt sich mit einem Upgrade des Betriebssystems auf OSX Catalina (10.15) bzw. iOS 13 beheben. Safari verfügt derzeit nicht über ein Aktivierungsflag zum Testen des neuen Spezifikationsverhaltens.
Testen mit Firefox
Die Firefox-Unterstützung für den neuen Standard kann in Version 68+ getestet werden, indem Sie sich auf der Seite about:config
mit dem Featureflag network.cookie.sameSite.laxByDefault
anmelden. Es liegen keine Berichte über Kompatibilitätsprobleme mit älteren Versionen von Firefox vor.
Testen mit dem Edge-Browser
Edge unterstützt den alten SameSite-Standard. Die Edge-Version 44 weist keine bekannten Kompatibilitätsprobleme mit dem neuen Standard auf.
Testen mit Edge (Chromium)
SameSite-Flags werden auf der Seite edge://flags/#same-site-by-default-cookies
festgelegt. Es wurden keine Kompatibilitätsprobleme mit Edge Chromium festgestellt.
Testen mit Electron
Die Versionen von Electron umfassen ältere Versionen von Chromium. Die von Teams verwendete Version von Electron ist z. B. Chromium 66, die das ältere Verhalten aufweist. Sie müssen Ihre eigenen Kompatibilitätstests mit der Version von Electron durchführen, die in Ihrem Produkt verwendet wird. Weitere Informationen finden Sie unter Unterstützung älterer Browser im folgenden Abschnitt.
Zusätzliche Ressourcen
- Chromium-Blog:Entwickler: Vorbereiten auf neues SameSite=None; Sichere Cookie-Einstellungen
- Erläuterung von SameSite-Cookies
- Patches von November 2019
Beispiel | Dokument |
---|---|
.NET Core MVC | ASP.NET Core 2.1 MVC SameSite-cookie-Beispiel |
.NET Core Razor Pages | ASP.NET Core 2.1 Razor Pages: Beispiel für SameSite-cookies |