Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
SameSite to wersja robocza standardu IETF zaprojektowana w celu zapewnienia ochrony przed atakami fałszowania żądań między witrynami (CSRF). Pierwotnie opracowany w 2016 r. projekt standardu został zaktualizowany w 2019 roku. Zaktualizowany standard nie jest wstecznie kompatybilny z poprzednim standardem, przy czym najbardziej zauważalne różnice są następujące:
- Pliki cookie bez nagłówka SameSite są domyślnie traktowane jako
SameSite=Laxpliki cookie. -
SameSite=Nonemusi być używany do zezwalania na używanie plików cookie między witrynami. - Pliki cookie, które potwierdzają
SameSite=None, muszą być również oznaczone jakoSecure. - Aplikacje, które używają
<iframe>, mogą napotkać problemy z plikiem cookiesameSite=LaxlubsameSite=Strict, ponieważ<iframe>jest traktowane jak w scenariuszach międzywitrynowych. - Wartość
SameSite=Nonenie jest dozwolona przez standard 2016 i powoduje, że niektóre implementacje traktują takie pliki cookie jakSameSite=Strict. Zobacz Obsługa starszych przeglądarek w tym dokumencie.
To SameSite=Lax ustawienie działa w przypadku większości plików cookie aplikacji. Niektóre formy uwierzytelniania, takie jak OpenID Connect (OIDC) i WS-Federation, domyślnie używają przekierowań opartych na metodzie POST. Przekierowania oparte na metodzie POST wyzwalają ochronę przeglądarki SameSite, więc dla tych składników mechanizm SameSite jest wyłączony. Większość logowań OAuth nie jest dotknięta ze względu na różnice w sposobie przepływu żądań.
Każdy składnik ASP.NET Core, który emituje pliki cookie, musi zdecydować, czy atrybut SameSite jest odpowiedni.
SameSite i tożsamość
ASP.NET Core Identity w dużej mierze nie ma wpływu plików cookie SameSite, z wyjątkiem zaawansowanych scenariuszy, takich jak integracja z IFrames lub integracji z OpenIdConnect.
W przypadku korzystania z Identitynie dodawaj żadnych dostawców plików cookie ani nie wywołuj services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme), Identity zajmuje się tym.
Przykładowy kod testowy SameSite
Można pobrać i przetestować następujący przykład:
| Sample | Document |
|---|---|
| Strony Razor | przykładowy plik cookie ASP.NET Core 3.1 Razor Pages SameSite |
Obsługa platformy .NET dla tego samego atrybutu witryny
Platforma .NET obsługuje wersję roboczą standardu 2019 dla witryny SameSite. Deweloperzy mogą programowo kontrolować wartość atrybutu sameSite przy użyciu właściwości HttpCookie.SameSite.
SameSite Ustawienie właściwości na Strict, Laxlub None powoduje zapisanie tych wartości w sieci za pomocą pliku cookie. Ustawienie SameSiteMode.Unspecified oznacza, że wraz z plikiem cookie nie należy wysyłać atrybutu 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.
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);
}
Użycie interfejsu API z SameSite
HttpContext.Response.Cookies.Append domyślnie ma wartość Unspecified, co oznacza, że do pliku cookie nie dodano atrybutu SameSite, a klient będzie używał jego domyślnego zachowania (Lax dla nowych przeglądarek, None dla starych). Poniższy kod pokazuje, jak zmienić wartość pliku cookie SameSite na SameSiteMode.Lax:
HttpContext.Response.Cookies.Append(
"name", "value",
new CookieOptions() { SameSite = SameSiteMode.Lax });
Wszystkie składniki ASP.NET Core, które emitują pliki cookie, zastępują poprzednie wartości domyślne ustawieniami odpowiednimi dla ich scenariuszy. Przesłonięte poprzednie wartości domyślne nie zostały zmienione.
program ASP.NET Core 3.1 lub nowszy zapewnia następującą obsługę witryny SameSite:
- Redefiniuje działanie
SameSiteMode.None, aby emitowaćSameSite=None - Dodaje nową wartość
SameSiteMode.Unspecified, aby pominąć atrybut SameSite. - Domyślnie wszystkie interfejsy API plików cookie są ustawione na
Unspecified. Niektóre składniki korzystające z plików cookie ustawiają wartości bardziej specyficzne dla ich scenariuszy. Zapoznaj się z powyższą tabelą, aby zapoznać się z przykładami.
W ASP.NET Core 3.0 lub nowszych wartości domyślne SameSite zostały zmienione, aby uniknąć konfliktu z niespójnymi wartościami domyślnymi klienta. Następujące interfejsy API zmieniły wartość domyślną z SameSiteMode.Lax na -1, aby uniknąć emitowania atrybutu SameSite dla tych plików cookie:
- CookieOptions używany z httpContext.Response.Cookies.Append
-
CookieBuilder używanego jako fabryka
CookieOptions - CookiePolicyOptions.MinimumSameSitePolicy
Historia i zmiany
Obsługa SameSite została po raz pierwszy zaimplementowana w ASP.NET Core w wersji 2.0 przy użyciu roboczego standardu z 2016 r. Standard 2016 był opt-in. ASP.NET Core domyślnie wymaga wyrażenia zgody przez ustawienie kilku plików cookie w elemencie Lax. Po wystąpieniu kilku problemów z uwierzytelnianiem większość zastosowań atrybutu SameSite została wyłączona.
Łatki zostały wydane w listopadzie 2019 r. w celu zaktualizowania standardu z 2016 r. do standardu z 2019 r. Wersja robocza specyfikacji SameSite z 2019 r.:
- Nie jest zgodny wstecz z wersją roboczą z 2016 roku. Aby uzyskać więcej informacji, zobacz Obsługa starszych przeglądarek w tym dokumencie.
- Określa, że pliki cookie są domyślnie traktowane jako
SameSite=Lax. - Określa pliki cookie, które jawnie deklarują
SameSite=None, aby umożliwić przesyłanie między witrynami, powinny być oznaczone jakoSecure.Noneto nowa opcja umożliwiająca rezygnację. - Jest wspierany za pomocą poprawek wydanych dla ASP.NET Core 2.1, 2.2 i 3.0. Program ASP.NET Core 3.1 lub nowszy ma dodatkową funkcjonalność obsługi SameSite.
- Ma zostać domyślnie włączone w Chrome w lutym 2020 roku. Przeglądarki zaczęły przechodzić na ten standard w 2019 roku.
Interfejsy API, których dotyczy zmiana z wersji roboczej standardu SameSite z 2016 r. na wersję roboczą standardu SameSite z 2019 r.
- Http.SameSiteMode
- CookieOptions.SameSite
- CookieBuilder.SameSite
- CookiePolicyOptions.MinimumSameSitePolicy
- Microsoft.Net.Http.Headers.SameSiteMode
- Microsoft.Net.Http.Headers.SetCookieHeaderValue.SameSite
Obsługa starszych przeglądarek
Standard SameSite z 2016 r. nakazywał traktowanie nieznanych wartości jako wartości SameSite=Strict. Aplikacje otwierane w starszych przeglądarkach, które obsługują standard SameSite 2016, mogą ulec awarii, gdy otrzymają właściwość SameSite o wartości None. Aplikacje internetowe muszą implementować wykrywanie przeglądarki, jeśli zamierzają obsługiwać starsze przeglądarki. ASP.NET Core nie implementuje wykrywania przeglądarki, ponieważ wartości User-Agent są bardzo niestabilne i często zmieniają się. Punkt rozszerzenia w Microsoft.AspNetCore.CookiePolicy umożliwia podłączanie logiki specyficznej dla agenta użytkownika.
W Program.cspliku dodaj kod wywołujący UseCookiePolicy przed wywołaniem UseAuthentication lub dowolnej metody zapisującej pliki cookie:
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();
W Program.cspliku dodaj kod podobny do następującego wyróżnionego kodu:
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();
W poprzednim przykładzie jest to biblioteka dostarczana przez użytkownika, która wykrywa, MyUserAgentDetectionLib.DisallowsSameSiteNone czy agent użytkownika nie obsługuje atrybutu SameSite None:
if (MyUserAgentDetectionLib.DisallowsSameSiteNone(userAgent))
{
options.SameSite = SameSiteMode.Unspecified;
}
Poniższy kod przedstawia przykładową DisallowsSameSiteNone metodę:
Warning
Poniższy kod jest przeznaczony tylko dla pokazu:
- Nie należy tego uważać za kompletne.
- Nie jest ona utrzymywana ani obsługiwana.
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;
}
Testowanie aplikacji pod kątem problemów z atrybutem SameSite
Aplikacje, które wchodzą w interakcje ze zdalnymi witrynami, na przykład poprzez logowanie zewnętrzne, muszą:
- Przetestuj interakcję w wielu przeglądarkach.
- Zastosuj omówione w tym dokumencie wykrywanie i łagodzenie CookiePolicy w przeglądarce.
Przetestuj aplikacje internetowe przy użyciu wersji klienta, która może włączyć nowe działanie SameSite. Chrome, Firefox i Chromium Edge mają nowe flagi funkcji wymagające włączenia, które mogą być używane do testowania. Po zastosowaniu poprawek SameSite w aplikacji przetestuj ją ze starszymi wersjami klienta, zwłaszcza w przeglądarce Safari. Aby uzyskać więcej informacji, zobacz Obsługa starszych przeglądarek w tym dokumencie.
Testuj w przeglądarce Chrome
Chrome 78+ daje mylące wyniki, ponieważ ma wdrożone tymczasowe obejście. Tymczasowe środki zaradcze w przeglądarce Chrome 78+ pozwalają na pliki cookie młodsze niż dwie minuty. Chrome 76 lub 77 z włączonymi odpowiednimi flagami testowymi zapewnia dokładniejsze wyniki. Aby przetestować nowe zachowanie SameSite, przełącz chrome://flags/#same-site-by-default-cookies na Włączone. Starsze wersje programu Chrome (75 i starsze) zgłasza się, że nie działają przy nowym ustawieniu None. Zobacz Obsługa starszych przeglądarek w tym dokumencie.
Firma Google nie udostępnia starszych wersji chrome. Postępuj zgodnie z instrukcjami na stronie Pobierz Chromium, aby przetestować starsze wersje przeglądarki Chrome. Nie pobieraj przeglądarki Chrome z linków znalezionych podczas wyszukiwania starszych wersji przeglądarki Chrome.
Począwszy od wersji Canary 80.0.3975.0, tymczasowy mechanizm łagodzący Lax+POST można wyłączyć na potrzeby testowania przy użyciu nowej flagi --enable-features=SameSiteDefaultChecksMethodRigorously, aby umożliwić testowanie witryn i usług w docelowym końcowym stanie funkcji, po usunięciu tego mechanizmu łagodzącego. Aby uzyskać więcej informacji, zobacz Chromium Projects SameSite Updates
Testuj w przeglądarce Safari
Przeglądarka Safari 12 ściśle zaimplementowała poprzednią wersję roboczą i kończy się niepowodzeniem, gdy nowa None wartość znajduje się w pliku cookie.
None jest omijane dzięki kodowi wykrywania przeglądarki Obsługa starszych przeglądarek w tym dokumencie. Przetestuj logowania w stylu systemowym w Safari 12, Safari 13 oraz przeglądarkach opartych na WebKit, przy użyciu bibliotek MSAL, ADAL lub dowolnej używanej biblioteki. Problem jest zależny od bazowej wersji systemu operacyjnego. OSX Mojave (10.14) i iOS 12 są znane z problemów ze zgodnością z nowym zachowaniem SameSite. Uaktualnienie systemu operacyjnego do systemu OSX Catalina (10.15) lub iOS 13 rozwiązuje problem. Przeglądarka Safari nie ma obecnie flagi opt-in do testowania nowego zachowania specyfikacji.
Testuj w przeglądarce Firefox
Obsługę przeglądarki Firefox dla nowego standardu można przetestować w wersji 68 lub nowszej, na stronie about:config za pomocą flagi funkcji network.cookie.sameSite.laxByDefault. Nie było zgłoszeń dotyczących problemów ze zgodnością ze starszymi wersjami przeglądarki Firefox.
Testowanie za pomocą przeglądarki Edge
Przeglądarka Edge obsługuje stary standard SameSite. Przeglądarka Edge w wersji 44 nie ma żadnych znanych problemów ze zgodnością z nowym standardem.
Testowanie za pomocą przeglądarki Edge (Chromium)
Flagi SameSite są ustawiane na stronie edge://flags/#same-site-by-default-cookies. Nie odnaleziono żadnych problemów ze zgodnością z przeglądarką Edge Chromium.
Testowanie za pomocą elektronu
Wersje Electron obejmują starsze wersje Chromium. Na przykład wersja Electron używana przez Teams to Chromium 66, która wykazuje starsze zachowanie. Musisz przeprowadzić własne testy zgodności z wersją używanej przez produkt Electron. Zobacz Obsługa starszych przeglądarek w poniższej sekcji.
Dodatkowe zasoby
- Blog Chromium: Deweloperzy: Przygotujcie się na nowe ustawienia SameSite=None; bezpiecznych ciasteczek
- Wyjaśnienie plików cookie SameSite
- Poprawki z listopada 2019 r.
| Sample | Document |
|---|---|
| Strony Razor | przykładowy plik cookie ASP.NET Core 3.1 Razor Pages SameSite |
Można pobrać i przetestować następujący przykład:
| Sample | Document |
|---|---|
| Strony Razor | przykładowy plik cookie ASP.NET Core 3.1 Razor Pages SameSite |
Obsługa platformy .NET Core dla atrybutu SameSite
Program .NET Core 3.1 lub nowszy obsługuje wersję roboczą standardu 2019 dla witryny SameSite. Deweloperzy mogą programowo kontrolować wartość atrybutu sameSite przy użyciu właściwości HttpCookie.SameSite. Ustawienie właściwości SameSite na Strict, Lax lub None powoduje zapisaniem tych wartości w pliku cookie przesyłanym przez sieć. Ustawienie go na (SameSiteMode)(-1) oznacza, że nie należy dołączać do pliku cookie atrybutu 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
// SameSite = (SameSiteMode)(-1)
SameSite = SameSiteMode.None
};
// Add the cookie to the response cookie collection
Response.Cookies.Append("MyCookie", "cookieValue", cookieOptions);
Platforma .NET Core 3.1 lub nowsza obsługuje zaktualizowane wartości SameSite i dodaje nową wartość SameSiteMode.Unspecified do wyliczenia SameSiteMode.
Ta nowa wartość wskazuje, że z plikiem cookie nie należy wysyłać sameSite.
Użycie interfejsu API z SameSite
HttpContext.Response.Cookies.Append domyślnie ma wartość Unspecified, co oznacza, że do pliku cookie nie dodano atrybutu SameSite, a klient będzie używał jego domyślnego zachowania (Lax dla nowych przeglądarek, None dla starych). Poniższy kod pokazuje, jak zmienić wartość pliku cookie SameSite na SameSiteMode.Lax:
HttpContext.Response.Cookies.Append(
"name", "value",
new CookieOptions() { SameSite = SameSiteMode.Lax });
Wszystkie składniki ASP.NET Core, które emitują pliki cookie, zastępują poprzednie wartości domyślne ustawieniami odpowiednimi dla ich scenariuszy. Przesłonięte poprzednie wartości domyślne nie zostały zmienione.
program ASP.NET Core 3.1 lub nowszy zapewnia następującą obsługę witryny SameSite:
- Redefiniuje działanie
SameSiteMode.None, aby emitowaćSameSite=None - Dodaje nową wartość
SameSiteMode.Unspecified, aby pominąć atrybut SameSite. - Domyślnie wszystkie interfejsy API plików cookie są ustawione na
Unspecified. Niektóre składniki korzystające z plików cookie ustawiają wartości bardziej specyficzne dla ich scenariuszy. Zapoznaj się z powyższą tabelą, aby zapoznać się z przykładami.
W ASP.NET Core 3.0 lub nowszych wartości domyślne SameSite zostały zmienione, aby uniknąć konfliktu z niespójnymi wartościami domyślnymi klienta. Następujące interfejsy API zmieniły wartość domyślną z SameSiteMode.Lax na -1, aby uniknąć emitowania atrybutu SameSite dla tych plików cookie:
- CookieOptions używany z httpContext.Response.Cookies.Append
-
CookieBuilder używanego jako fabryka
CookieOptions - CookiePolicyOptions.MinimumSameSitePolicy
Historia i zmiany
Obsługa SameSite została po raz pierwszy zaimplementowana w ASP.NET Core w wersji 2.0 przy użyciu roboczego standardu z 2016 r. Standard 2016 był opt-in. ASP.NET Core domyślnie wymaga wyrażenia zgody przez ustawienie kilku plików cookie w elemencie Lax. Po wystąpieniu kilku problemów z uwierzytelnianiem większość zastosowań atrybutu SameSite została wyłączona.
Łatki zostały wydane w listopadzie 2019 r. w celu zaktualizowania standardu z 2016 r. do standardu z 2019 r. Wersja robocza specyfikacji SameSite z 2019 r.:
- Nie jest zgodny wstecz z wersją roboczą z 2016 roku. Aby uzyskać więcej informacji, zobacz Obsługa starszych przeglądarek w tym dokumencie.
- Określa, że pliki cookie są domyślnie traktowane jako
SameSite=Lax. - Określa pliki cookie, które jawnie deklarują
SameSite=None, aby umożliwić przesyłanie między witrynami, powinny być oznaczone jakoSecure.Noneto nowa opcja umożliwiająca rezygnację. - Jest wspierany za pomocą poprawek wydanych dla ASP.NET Core 2.1, 2.2 i 3.0. ASP.NET Core 3.1 ma dodatkową obsługę SameSite.
- Ma zostać domyślnie włączone w Chrome w lutym 2020 roku. Przeglądarki zaczęły przechodzić na ten standard w 2019 roku.
Interfejsy API, których dotyczy zmiana z wersji roboczej standardu SameSite z 2016 r. na wersję roboczą standardu SameSite z 2019 r.
- Http.SameSiteMode
- CookieOptions.SameSite
- CookieBuilder.SameSite
- CookiePolicyOptions.MinimumSameSitePolicy
- Microsoft.Net.Http.Headers.SameSiteMode
- Microsoft.Net.Http.Headers.SetCookieHeaderValue.SameSite
Obsługa starszych przeglądarek
Standard SameSite z 2016 r. nakazywał traktowanie nieznanych wartości jako wartości SameSite=Strict. Aplikacje otwierane w starszych przeglądarkach, które obsługują standard SameSite 2016, mogą ulec awarii, gdy otrzymają właściwość SameSite o wartości None. Aplikacje internetowe muszą implementować wykrywanie przeglądarki, jeśli zamierzają obsługiwać starsze przeglądarki. ASP.NET Core nie implementuje wykrywania przeglądarki, ponieważ wartości User-Agent są bardzo niestabilne i często zmieniają się. Punkt rozszerzenia w Microsoft.AspNetCore.CookiePolicy umożliwia podłączanie logiki specyficznej dla agenta użytkownika.
W Startup.Configurepliku dodaj kod wywołujący UseCookiePolicy przed wywołaniem UseAuthentication lub dowolnej metody zapisującej pliki cookie:
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();
});
}
W Startup.ConfigureServicespliku dodaj kod podobny do następującego:
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;
}
}
}
W poprzednim przykładzie jest to biblioteka dostarczana przez użytkownika, która wykrywa, MyUserAgentDetectionLib.DisallowsSameSiteNone czy agent użytkownika nie obsługuje atrybutu SameSite None:
if (MyUserAgentDetectionLib.DisallowsSameSiteNone(userAgent))
{
options.SameSite = SameSiteMode.Unspecified;
}
Poniższy kod przedstawia przykładową DisallowsSameSiteNone metodę:
Warning
Poniższy kod jest przeznaczony tylko dla pokazu:
- Nie należy tego uważać za kompletne.
- Nie jest ona utrzymywana ani obsługiwana.
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;
}
Testowanie aplikacji pod kątem problemów z atrybutem SameSite
Aplikacje, które wchodzą w interakcje ze zdalnymi witrynami, na przykład poprzez logowanie zewnętrzne, muszą:
- Przetestuj interakcję w wielu przeglądarkach.
- Zastosuj omówione w tym dokumencie wykrywanie i łagodzenie CookiePolicy w przeglądarce.
Przetestuj aplikacje internetowe przy użyciu wersji klienta, która może włączyć nowe działanie SameSite. Chrome, Firefox i Chromium Edge mają nowe flagi funkcji wymagające włączenia, które mogą być używane do testowania. Po zastosowaniu poprawek SameSite w aplikacji przetestuj ją ze starszymi wersjami klienta, zwłaszcza w przeglądarce Safari. Aby uzyskać więcej informacji, zobacz Obsługa starszych przeglądarek w tym dokumencie.
Testuj w przeglądarce Chrome
Chrome 78+ daje mylące wyniki, ponieważ ma wdrożone tymczasowe obejście. Tymczasowe środki zaradcze w przeglądarce Chrome 78+ pozwalają na pliki cookie młodsze niż dwie minuty. Chrome 76 lub 77 z włączonymi odpowiednimi flagami testowymi zapewnia dokładniejsze wyniki. Aby przetestować nowe zachowanie SameSite, przełącz chrome://flags/#same-site-by-default-cookies na Włączone. Starsze wersje programu Chrome (75 i starsze) zgłasza się, że nie działają przy nowym ustawieniu None. Zobacz Obsługa starszych przeglądarek w tym dokumencie.
Firma Google nie udostępnia starszych wersji chrome. Postępuj zgodnie z instrukcjami na stronie Pobierz Chromium, aby przetestować starsze wersje przeglądarki Chrome. Nie pobieraj przeglądarki Chrome z linków znalezionych podczas wyszukiwania starszych wersji przeglądarki Chrome.
Począwszy od wersji Canary 80.0.3975.0, tymczasowy mechanizm łagodzący Lax+POST można wyłączyć na potrzeby testowania przy użyciu nowej flagi --enable-features=SameSiteDefaultChecksMethodRigorously, aby umożliwić testowanie witryn i usług w docelowym końcowym stanie funkcji, po usunięciu tego mechanizmu łagodzącego. Aby uzyskać więcej informacji, zobacz Chromium Projects SameSite Updates
Testuj w przeglądarce Safari
Przeglądarka Safari 12 ściśle zaimplementowała poprzednią wersję roboczą i kończy się niepowodzeniem, gdy nowa None wartość znajduje się w pliku cookie.
None jest omijane dzięki kodowi wykrywania przeglądarki Obsługa starszych przeglądarek w tym dokumencie. Przetestuj logowania w stylu systemowym w Safari 12, Safari 13 oraz przeglądarkach opartych na WebKit, przy użyciu bibliotek MSAL, ADAL lub dowolnej używanej biblioteki. Problem jest zależny od bazowej wersji systemu operacyjnego. OSX Mojave (10.14) i iOS 12 są znane z problemów ze zgodnością z nowym zachowaniem SameSite. Uaktualnienie systemu operacyjnego do systemu OSX Catalina (10.15) lub iOS 13 rozwiązuje problem. Przeglądarka Safari nie ma obecnie flagi opt-in do testowania nowego zachowania specyfikacji.
Testuj w przeglądarce Firefox
Obsługę przeglądarki Firefox dla nowego standardu można przetestować w wersji 68 lub nowszej, na stronie about:config za pomocą flagi funkcji network.cookie.sameSite.laxByDefault. Nie było zgłoszeń dotyczących problemów ze zgodnością ze starszymi wersjami przeglądarki Firefox.
Testowanie za pomocą przeglądarki Edge
Przeglądarka Edge obsługuje stary standard SameSite. Przeglądarka Edge w wersji 44 nie ma żadnych znanych problemów ze zgodnością z nowym standardem.
Testowanie za pomocą przeglądarki Edge (Chromium)
Flagi SameSite są ustawiane na stronie edge://flags/#same-site-by-default-cookies. Nie odnaleziono żadnych problemów ze zgodnością z przeglądarką Edge Chromium.
Testowanie za pomocą elektronu
Wersje Electron obejmują starsze wersje Chromium. Na przykład wersja Electron używana przez Teams to Chromium 66, która wykazuje starsze zachowanie. Musisz przeprowadzić własne testy zgodności z wersją używanej przez produkt Electron. Zobacz Obsługa starszych przeglądarek w poniższej sekcji.
Dodatkowe zasoby
- Blog Chromium: Deweloperzy: Przygotujcie się na nowe ustawienia SameSite=None; bezpiecznych ciasteczek
- Wyjaśnienie plików cookie SameSite
- Poprawki z listopada 2019 r.
| Sample | Document |
|---|---|
| Strony Razor | przykładowy plik cookie ASP.NET Core 3.1 Razor Pages SameSite |
Można pobrać i przetestować następujące przykłady:
| Sample | Document |
|---|---|
| MVC | Przykład pliku cookie SameSite w ASP.NET Core 2.1 MVC |
| Strony Razor | przykład ASP.NET Core 2.1 Razor Pages dotyczący plików cookie SameSite |
Zmiany zachowania poprawki z grudnia
Konkretna zmiana zachowania dla platform .NET Framework i .NET Core 2.1 polega na tym, jak właściwość SameSite interpretuje wartość None. Przed poprawką wartość None oznaczała „Nie emituj atrybutu w ogóle”, po poprawce oznacza to „Emituj atrybut z wartością None”. Po poprawce wartość SameSite wynosząca (SameSiteMode)(-1) powoduje, że atrybut nie jest emitowany.
Domyślna wartość SameSite dla plików cookie uwierzytelniania formularzy i stanu sesji została zmieniona z None na Lax.
Użycie interfejsu API z SameSite
HttpContext.Response.Cookies.Append domyślnie ma wartość Unspecified, co oznacza, że do pliku cookie nie dodano atrybutu SameSite, a klient będzie używał jego domyślnego zachowania (Lax dla nowych przeglądarek, None dla starych). Poniższy kod pokazuje, jak zmienić wartość pliku cookie SameSite na SameSiteMode.Lax:
HttpContext.Response.Cookies.Append(
"name", "value",
new CookieOptions() { SameSite = SameSiteMode.Lax });
Wszystkie składniki ASP.NET Core, które emitują pliki cookie, zastępują poprzednie wartości domyślne ustawieniami odpowiednimi dla ich scenariuszy. Przesłonięte poprzednie wartości domyślne nie zostały zmienione.
Historia i zmiany
Obsługa SameSite została po raz pierwszy zaimplementowana w ASP.NET Core w wersji 2.0 przy użyciu roboczego standardu z 2016 r. Standard 2016 był opt-in. ASP.NET Core domyślnie wymaga wyrażenia zgody przez ustawienie kilku plików cookie w elemencie Lax. Po wystąpieniu kilku problemów z uwierzytelnianiem większość zastosowań atrybutu SameSite została wyłączona.
Łatki zostały wydane w listopadzie 2019 r. w celu zaktualizowania standardu z 2016 r. do standardu z 2019 r. Wersja robocza specyfikacji SameSite z 2019 r.:
- Nie jest zgodny wstecz z wersją roboczą z 2016 roku. Aby uzyskać więcej informacji, zobacz Obsługa starszych przeglądarek w tym dokumencie.
- Określa, że pliki cookie są domyślnie traktowane jako
SameSite=Lax. - Określa pliki cookie, które jawnie deklarują
SameSite=None, aby umożliwić przesyłanie między witrynami, powinny być oznaczone jakoSecure.Noneto nowa opcja umożliwiająca rezygnację. - Jest wspierany za pomocą poprawek wydanych dla ASP.NET Core 2.1, 2.2 i 3.0. ASP.NET Core 3.1 ma dodatkową obsługę SameSite.
- Ma zostać domyślnie włączone w Chrome w lutym 2020 roku. Przeglądarki zaczęły przechodzić na ten standard w 2019 roku.
Interfejsy API, których dotyczy zmiana z wersji roboczej standardu SameSite z 2016 r. na wersję roboczą standardu SameSite z 2019 r.
- Http.SameSiteMode
- CookieOptions.SameSite
- CookieBuilder.SameSite
- CookiePolicyOptions.MinimumSameSitePolicy
- Microsoft.Net.Http.Headers.SameSiteMode
- Microsoft.Net.Http.Headers.SetCookieHeaderValue.SameSite
Obsługa starszych przeglądarek
Standard SameSite z 2016 r. nakazywał traktowanie nieznanych wartości jako wartości SameSite=Strict. Aplikacje otwierane w starszych przeglądarkach, które obsługują standard SameSite 2016, mogą ulec awarii, gdy otrzymają właściwość SameSite o wartości None. Aplikacje internetowe muszą implementować wykrywanie przeglądarki, jeśli zamierzają obsługiwać starsze przeglądarki. ASP.NET Core nie implementuje wykrywania przeglądarki, ponieważ wartości User-Agent są bardzo niestabilne i często zmieniają się. Punkt rozszerzenia w Microsoft.AspNetCore.CookiePolicy umożliwia podłączanie logiki specyficznej dla agenta użytkownika.
W Startup.Configurepliku dodaj kod wywołujący UseCookiePolicy przed wywołaniem UseAuthentication lub dowolnej metody zapisującej pliki cookie:
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();
});
}
W Startup.ConfigureServicespliku dodaj kod podobny do następującego:
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);
}
}
}
W poprzednim przykładzie jest to biblioteka dostarczana przez użytkownika, która wykrywa, MyUserAgentDetectionLib.DisallowsSameSiteNone czy agent użytkownika nie obsługuje atrybutu SameSite None:
if (MyUserAgentDetectionLib.DisallowsSameSiteNone(userAgent))
{
options.SameSite = SameSiteMode.Unspecified;
}
Poniższy kod przedstawia przykładową DisallowsSameSiteNone metodę:
Warning
Poniższy kod jest przeznaczony tylko dla pokazu:
- Nie należy tego uważać za kompletne.
- Nie jest ona utrzymywana ani obsługiwana.
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;
}
Testowanie aplikacji pod kątem problemów z atrybutem SameSite
Aplikacje, które wchodzą w interakcje ze zdalnymi witrynami, na przykład poprzez logowanie zewnętrzne, muszą:
- Przetestuj interakcję w wielu przeglądarkach.
- Zastosuj omówione w tym dokumencie wykrywanie i łagodzenie CookiePolicy w przeglądarce.
Przetestuj aplikacje internetowe przy użyciu wersji klienta, która może włączyć nowe działanie SameSite. Chrome, Firefox i Chromium Edge mają nowe flagi funkcji wymagające włączenia, które mogą być używane do testowania. Po zastosowaniu poprawek SameSite w aplikacji przetestuj ją ze starszymi wersjami klienta, zwłaszcza w przeglądarce Safari. Aby uzyskać więcej informacji, zobacz Obsługa starszych przeglądarek w tym dokumencie.
Testuj w przeglądarce Chrome
Chrome 78+ daje mylące wyniki, ponieważ ma wdrożone tymczasowe obejście. Tymczasowe środki zaradcze w przeglądarce Chrome 78+ pozwalają na pliki cookie młodsze niż dwie minuty. Chrome 76 lub 77 z włączonymi odpowiednimi flagami testowymi zapewnia dokładniejsze wyniki. Aby przetestować nowe zachowanie SameSite, przełącz chrome://flags/#same-site-by-default-cookies na Włączone. Starsze wersje programu Chrome (75 i starsze) zgłasza się, że nie działają przy nowym ustawieniu None. Zobacz Obsługa starszych przeglądarek w tym dokumencie.
Firma Google nie udostępnia starszych wersji chrome. Postępuj zgodnie z instrukcjami na stronie Pobierz Chromium, aby przetestować starsze wersje przeglądarki Chrome. Nie pobieraj przeglądarki Chrome z linków znalezionych podczas wyszukiwania starszych wersji przeglądarki Chrome.
Począwszy od wersji Canary 80.0.3975.0, tymczasowy mechanizm łagodzący Lax+POST można wyłączyć na potrzeby testowania przy użyciu nowej flagi --enable-features=SameSiteDefaultChecksMethodRigorously, aby umożliwić testowanie witryn i usług w docelowym końcowym stanie funkcji, po usunięciu tego mechanizmu łagodzącego. Aby uzyskać więcej informacji, zobacz Chromium Projects SameSite Updates
Testuj w przeglądarce Safari
Przeglądarka Safari 12 ściśle zaimplementowała poprzednią wersję roboczą i kończy się niepowodzeniem, gdy nowa None wartość znajduje się w pliku cookie.
None jest omijane dzięki kodowi wykrywania przeglądarki Obsługa starszych przeglądarek w tym dokumencie. Przetestuj logowania w stylu systemowym w Safari 12, Safari 13 oraz przeglądarkach opartych na WebKit, przy użyciu bibliotek MSAL, ADAL lub dowolnej używanej biblioteki. Problem jest zależny od bazowej wersji systemu operacyjnego. OSX Mojave (10.14) i iOS 12 są znane z problemów ze zgodnością z nowym zachowaniem SameSite. Uaktualnienie systemu operacyjnego do systemu OSX Catalina (10.15) lub iOS 13 rozwiązuje problem. Przeglądarka Safari nie ma obecnie flagi opt-in do testowania nowego zachowania specyfikacji.
Testuj w przeglądarce Firefox
Obsługę przeglądarki Firefox dla nowego standardu można przetestować w wersji 68 lub nowszej, na stronie about:config za pomocą flagi funkcji network.cookie.sameSite.laxByDefault. Nie było zgłoszeń dotyczących problemów ze zgodnością ze starszymi wersjami przeglądarki Firefox.
Testowanie za pomocą przeglądarki Edge
Przeglądarka Edge obsługuje stary standard SameSite. Przeglądarka Edge w wersji 44 nie ma żadnych znanych problemów ze zgodnością z nowym standardem.
Testowanie za pomocą przeglądarki Edge (Chromium)
Flagi SameSite są ustawiane na stronie edge://flags/#same-site-by-default-cookies. Nie odnaleziono żadnych problemów ze zgodnością z przeglądarką Edge Chromium.
Testowanie za pomocą elektronu
Wersje Electron obejmują starsze wersje Chromium. Na przykład wersja Electron używana przez Teams to Chromium 66, która wykazuje starsze zachowanie. Musisz przeprowadzić własne testy zgodności z wersją używanej przez produkt Electron. Zobacz Obsługa starszych przeglądarek w poniższej sekcji.
Dodatkowe zasoby
- Blog Chromium: Deweloperzy: Przygotujcie się na nowe ustawienia SameSite=None; bezpiecznych ciasteczek
- Wyjaśnienie plików cookie SameSite
- Poprawki z listopada 2019 r.
| Sample | Document |
|---|---|
| MVC | Przykład pliku cookie SameSite w ASP.NET Core 2.1 MVC |
| Strony Razor | przykład ASP.NET Core 2.1 Razor Pages dotyczący plików cookie SameSite |