Praca z plikami cookie SameSite w programie ASP.NET Core
Autor: Rick Anderson
SameSite to wersja robocza standardu IETF zaprojektowana w celu zapewnienia ochrony przed atakami fałszerzowania żądań między witrynami (CSRF). Pierwotnie opracowany w 2016 r. projekt standardu został zaktualizowany w 2019 roku. Zaktualizowany standard nie jest zgodny z poprzednim standardem, a następujące są najbardziej zauważalne różnice:
- Pliki cookie bez nagłówka SameSite są domyślnie traktowane jako
SameSite=Lax
pliki cookie. SameSite=None
musi być używany do zezwalania na używanie między witrynami cookie .- Pliki cookie, które potwierdzają
SameSite=None
, muszą być również oznaczone jakoSecure
. - Aplikacje, które używają
<iframe>
, mogą napotkać problemy z plikiemsameSite=Lax
cookie lubsameSite=Strict
plikiem cookie, ponieważ<iframe>
są traktowane jako scenariusze obejmujące wiele witryn. - Wartość
SameSite=None
nie 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ślne przekierowania oparte na post. Przekierowania oparte na metodzie POST wyzwalają ochronę przeglądarki SameSite, więc dla tych składników jest wyłączona witryna SameSite. Większość identyfikatorów logowania OAuth nie ma wpływu na różnice w sposobie przepływu żądań.
Każdy składnik ASP.NET Core, który emituje pliki cookie, musi zdecydować, czy jest odpowiednia witryna SameSite.
SameSite i Identity
ASP.NET Core Identity nie ma wpływu na pliki cookie SameSite, z wyjątkiem zaawansowanych scenariuszy, takich jak IFrames
lub OpenIdConnect
integracji.
W przypadku korzystania z programu Identity
nie należy dodawać żadnych cookie dostawców ani dzwonić services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
do usługi , Identity
dba o to.
Przykładowy kod testowy witryny SameSite
Można pobrać i przetestować następujący przykład:
Przykład | Dokument |
---|---|
.NET Core Razor Pages | przykład ASP.NET Core 3.1 Razor Pages SameSite cookie |
Obsługa platformy .NET Core dla tego samego atrybutu Lokacja
Platforma .NET Core obsługuje wersję roboczą standardu 2019 dla witryny SameSite. Deweloperzy mogą programowo kontrolować wartość tego samego atrybutu Lokacja HttpCookie.SameSite
przy użyciu właściwości . SameSite
Ustawienie właściwości na Strict
, Lax
lub None
powoduje zapisanie tych wartości w sieci za pomocą elementu cookie. Ustawienie , aby wskazać, że nie należy wysyłać SameSiteMode.Unspecified
żadnej lokacji z parametrem cookie.
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 w usłudze SameSite
Wartości domyślne HttpContext.Response.Cookies.Append mają wartość Unspecified
, co oznacza, że do elementu nie dodano atrybutu cookie SameSite, a klient będzie używać jego domyślnego zachowania (Lax dla nowych przeglądarek, Brak dla starych). Poniższy kod pokazuje, jak zmienić cookie wartość 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ęć powyższe wartości domyślne nie zostały zmienione.
Składnik | cookie | Wartość domyślna |
---|---|---|
CookieBuilder | SameSite | Unspecified |
Session | SessionOptions.Cookie | Lax |
CookieTempDataProvider | CookieTempDataProviderOptions.Cookie | Lax |
IAntiforgery | AntiforgeryOptions.Cookie | Strict |
Cookie Uwierzytelnianie | CookieAuthenticationOptions.Cookie | Lax |
AddTwitter | TwitterOptions.StateCookie | Lax |
RemoteAuthenticationHandler<TOptions> | RemoteAuthenticationOptions.CorrelationCookie | None |
AddOpenIdConnect | OpenIdConnectOptions.NonceCookie | None |
HttpContext.Response.Cookies.Append | CookieOptions | Unspecified |
program ASP.NET Core 3.1 lub nowszy zapewnia następującą obsługę witryny SameSite:
- Ponowne definiowanie zachowania emisji
SameSiteMode.None
SameSite=None
- Dodaje nową wartość
SameSiteMode.Unspecified
, aby pominąć atrybut SameSite. - Domyślnie wszystkie interfejsy API plików cookie mają wartość
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 systemie ASP.NET Core 3.0 i nowszych wartości domyślne SameSite zostały zmienione, aby uniknąć konfliktu z niespójnymi ustawieniami domyślnymi klienta. Następujące interfejsy API zmieniły wartość domyślną z SameSiteMode.Lax
, aby -1
uniknąć emitowania atrybutu SameSite dla tych plików cookie:
- CookieOptions używany z httpContext.Response.Cookies.Append
- CookieBuilder używane jako fabryka
CookieOptions
- CookiePolicyOptions.MinimumSameSitePolicy
Historia i zmiany
Obsługa sameSite została po raz pierwszy zaimplementowana w programie ASP.NET Core w wersji 2.0 przy użyciu standardu roboczego 2016. Standard 2016 był opt-in. ASP.NET Core , domyślnie ustawiając kilka plików cookie Lax
. Po wystąpieniu kilku problemów z uwierzytelnianiem większość użycia witryny SameSite została wyłączona.
Poprawki zostały wydane w listopadzie 2019 r. w celu zaktualizowania standardu z 2016 r. do standardu 2019. Wersja robocza z 2019 r. specyfikacji SameSite:
- Nie jest do tyłu zgodny 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 asertywne
SameSite=None
w celu włączenia dostarczania między witrynami powinny być oznaczone jakoSecure
.None
jest nowym wpisem, aby zrezygnować. - Jest obsługiwany przez poprawki wydane dla ASP.NET Core 2.1, 2.2 i 3.0. program ASP.NET Core 3.1 lub nowszy ma dodatkową obsługę witryny SameSite.
- Program Chrome ma być domyślnie włączony w lutym 2020 roku. Przeglądarki zaczęły przechodzić do tego standardu w 2019 roku.
Interfejsy API, których dotyczy zmiana z wersji roboczej SameSite z 2016 r. do wersji roboczej standardu 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. nakazuje traktowanie nieznanych wartości jako SameSite=Strict
wartości. Aplikacje dostępne ze starszych przeglądarek, 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 agentów użytkowników są bardzo niestabilne i często zmieniają się. Punkt rozszerzenia umożliwia Microsoft.AspNetCore.CookiePolicy podłączanie logiki specyficznej dla agenta użytkownika.
W Program.cs
pliku dodaj kod wywołujący UseCookiePolicy przed wywołaniem UseAuthentication metody lub dowolną metodę zapisującą 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.cs
pliku 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 aplikacji SameSite None
:
if (MyUserAgentDetectionLib.DisallowsSameSiteNone(userAgent))
{
options.SameSite = SameSiteMode.Unspecified;
}
Poniższy kod przedstawia przykładową DisallowsSameSiteNone
metodę:
Ostrzeżenie
Poniższy kod jest przeznaczony tylko dla pokazu:
- Nie należy go uważać za ukończone.
- Nie jest ona obsługiwana 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 usługą SameSite
Aplikacje, które wchodzą w interakcje z witrynami zdalnymi, takimi jak za pośrednictwem logowania innej firmy, muszą:
- Przetestuj interakcję w wielu przeglądarkach.
- Zastosuj wykrywanie przeglądarki CookiePolicy i środki zaradcze omówione w tym dokumencie.
Przetestuj aplikacje internetowe przy użyciu wersji klienta, która może wyrazić zgodę na nowe zachowanie w witrynie SameSite. Chrome, Firefox i Chromium Edge mają nowe flagi funkcji, które mogą być używane do testowania. Gdy aplikacja zastosuje poprawki SameSite, 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.
Testowanie za pomocą przeglądarki Chrome
Chrome 78+ daje mylące wyniki, ponieważ ma tymczasowe środki zaradcze. Tymczasowe środki zaradcze w przeglądarce Chrome 78+ pozwalają na używanie plików cookie mniej niż dwie minuty. Chrome 76 lub 77 z włączonymi odpowiednimi flagami testowymi zapewnia dokładniejsze wyniki. Aby przetestować nowe zachowanie SameSite, przełączenie chrome://flags/#same-site-by-default-cookies
na włączone. Starsze wersje programu Chrome (75 i starsze) są zgłaszane jako nieudane z nowym None
ustawieniem. Zobacz Obsługa starszych przeglądarek w tym dokumencie.
Firma Google nie udostępnia starszych wersji chrome. Postępuj zgodnie z instrukcjami w temacie Pobierz Chromium , aby przetestować starsze wersje przeglądarki Chrome. Nie pobieraj przeglądarki Chrome z linków udostępnianych przez wyszukiwanie starszych wersji przeglądarki Chrome.
Począwszy od wersji 80.0.3975.0
Canary, tymczasowe ograniczenie ryzyka 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 ostatecznym stanie końcowym funkcji, w której usunięto środki zaradcze. Aby uzyskać więcej informacji, zobacz Chromium Projects SameSite Updates
Testowanie za pomocą przeglądarki Safari
Przeglądarka Safari 12 ściśle zaimplementowała poprzednią wersję roboczą i kończy się niepowodzeniem, gdy nowa None
wartość znajduje się w obiekcie cookie. None
jest unikany za pośrednictwem kodu wykrywania przeglądarki Obsługa starszych przeglądarek w tym dokumencie. Przetestuj identyfikatory logowania w stylu systemu operacyjnego oparte na przeglądarce Safari 12, Safari 13 i 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 zgody na testowanie nowego zachowania specyfikacji.
Testowanie za pomocą przeglądarki Firefox
Obsługa przeglądarki Firefox dla nowego standardu można przetestować w wersji 68 lub nowszej, decydując się na about:config
stronę z flagą network.cookie.sameSite.laxByDefault
funkcji . Nie odnotowano raportów 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 edge://flags/#same-site-by-default-cookies
stronie. Nie odnaleziono żadnych problemów ze zgodnością z przeglądarką Edge Chromium.
Testowanie za pomocą polecenia Electron
Electron Wersje obejmują starsze wersje Chromium. Na przykład wersja Electron używana przez aplikację Teams to Chromium 66, która wykazuje starsze zachowanie. Musisz przeprowadzić własne testy zgodności z wersją używanego Electron produktu. Zobacz Obsługa starszych przeglądarek w poniższej sekcji.
Dodatkowe zasoby
- Blog Chromium:Developers: Get Ready for New SameSite=None; Ustawienia zabezpieczeń Cookie
- SameSite cookie wyjaśnione
- Poprawki z listopada 2019 r.
Przykład | Dokument |
---|---|
.NET Core Razor Pages | przykład ASP.NET Core 3.1 Razor Pages SameSite cookie |
Można pobrać i przetestować następujący przykład:
Przykład | Dokument |
---|---|
.NET Core Razor Pages | przykład ASP.NET Core 3.1 Razor Pages SameSite cookie |
Obsługa platformy .NET Core dla tego samego atrybutu Lokacja
Program .NET Core 3.1 lub nowszy obsługuje wersję roboczą standardu 2019 dla witryny SameSite. Deweloperzy mogą programowo kontrolować wartość tego samego atrybutu Lokacja HttpCookie.SameSite
przy użyciu właściwości . Ustawienie właściwości na SameSite
Strict, Lax lub None powoduje zapisanie tych wartości w sieci za pomocą elementu cookie. Ustawienie wartości równej (SameSiteMode)(-1)
wskazuje, że w sieci nie powinien być uwzględniony żaden atrybut sameSite cookie
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 i nowsze obsługują zaktualizowane wartości SameSite i dodaje dodatkową wartość SameSiteMode.Unspecified
wyliczenia do wyliczenia SameSiteMode
.
Ta nowa wartość wskazuje, że żadna witryna nie powinna być wysyłana za pomocą elementu cookie.
Użycie interfejsu API w usłudze SameSite
Wartości domyślne HttpContext.Response.Cookies.Append mają wartość Unspecified
, co oznacza, że do elementu nie dodano atrybutu cookie SameSite, a klient będzie używać jego domyślnego zachowania (Lax dla nowych przeglądarek, Brak dla starych). Poniższy kod pokazuje, jak zmienić cookie wartość 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ęć powyższe wartości domyślne nie zostały zmienione.
Składnik | cookie | Wartość domyślna |
---|---|---|
CookieBuilder | SameSite | Unspecified |
Session | SessionOptions.Cookie | Lax |
CookieTempDataProvider | CookieTempDataProviderOptions.Cookie | Lax |
IAntiforgery | AntiforgeryOptions.Cookie | Strict |
Cookie Uwierzytelnianie | CookieAuthenticationOptions.Cookie | Lax |
AddTwitter | TwitterOptions.StateCookie | Lax |
RemoteAuthenticationHandler<TOptions> | RemoteAuthenticationOptions.CorrelationCookie | None |
AddOpenIdConnect | OpenIdConnectOptions.NonceCookie | None |
HttpContext.Response.Cookies.Append | CookieOptions | Unspecified |
program ASP.NET Core 3.1 lub nowszy zapewnia następującą obsługę witryny SameSite:
- Ponowne definiowanie zachowania emisji
SameSiteMode.None
SameSite=None
- Dodaje nową wartość
SameSiteMode.Unspecified
, aby pominąć atrybut SameSite. - Domyślnie wszystkie interfejsy API plików cookie mają wartość
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 systemie ASP.NET Core 3.0 i nowszych wartości domyślne SameSite zostały zmienione, aby uniknąć konfliktu z niespójnymi ustawieniami domyślnymi klienta. Następujące interfejsy API zmieniły wartość domyślną z SameSiteMode.Lax
, aby -1
uniknąć emitowania atrybutu SameSite dla tych plików cookie:
- CookieOptions używany z httpContext.Response.Cookies.Append
- CookieBuilder używane jako fabryka
CookieOptions
- CookiePolicyOptions.MinimumSameSitePolicy
Historia i zmiany
Obsługa sameSite została po raz pierwszy zaimplementowana w programie ASP.NET Core w wersji 2.0 przy użyciu standardu roboczego 2016. Standard 2016 był opt-in. ASP.NET Core , domyślnie ustawiając kilka plików cookie Lax
. Po wystąpieniu kilku problemów z uwierzytelnianiem większość użycia witryny SameSite została wyłączona.
Poprawki zostały wydane w listopadzie 2019 r. w celu zaktualizowania standardu z 2016 r. do standardu 2019. Wersja robocza z 2019 r. specyfikacji SameSite:
- Nie jest do tyłu zgodny 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 asertywne
SameSite=None
w celu włączenia dostarczania między witrynami powinny być oznaczone jakoSecure
.None
jest nowym wpisem, aby zrezygnować. - Jest obsługiwany przez poprawki wydane dla ASP.NET Core 2.1, 2.2 i 3.0. ASP.NET Core 3.1 ma dodatkową obsługę usługi SameSite.
- Program Chrome ma być domyślnie włączony w lutym 2020 roku. Przeglądarki zaczęły przechodzić do tego standardu w 2019 roku.
Interfejsy API, których dotyczy zmiana z wersji roboczej SameSite z 2016 r. do wersji roboczej standardu 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. nakazuje traktowanie nieznanych wartości jako SameSite=Strict
wartości. Aplikacje dostępne ze starszych przeglądarek, 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 agentów użytkowników są bardzo niestabilne i często zmieniają się. Punkt rozszerzenia umożliwia Microsoft.AspNetCore.CookiePolicy podłączanie logiki specyficznej dla agenta użytkownika.
W Startup.Configure
pliku dodaj kod wywołujący UseCookiePolicy przed wywołaniem UseAuthentication metody lub dowolną metodę zapisującą 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.ConfigureServices
pliku 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 aplikacji SameSite None
:
if (MyUserAgentDetectionLib.DisallowsSameSiteNone(userAgent))
{
options.SameSite = SameSiteMode.Unspecified;
}
Poniższy kod przedstawia przykładową DisallowsSameSiteNone
metodę:
Ostrzeżenie
Poniższy kod jest przeznaczony tylko dla pokazu:
- Nie należy go uważać za ukończone.
- Nie jest ona obsługiwana 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 usługą SameSite
Aplikacje, które wchodzą w interakcje z witrynami zdalnymi, takimi jak za pośrednictwem logowania innej firmy, muszą:
- Przetestuj interakcję w wielu przeglądarkach.
- Zastosuj wykrywanie przeglądarki CookiePolicy i środki zaradcze omówione w tym dokumencie.
Przetestuj aplikacje internetowe przy użyciu wersji klienta, która może wyrazić zgodę na nowe zachowanie w witrynie SameSite. Chrome, Firefox i Chromium Edge mają nowe flagi funkcji, które mogą być używane do testowania. Gdy aplikacja zastosuje poprawki SameSite, 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.
Testowanie za pomocą przeglądarki Chrome
Chrome 78+ daje mylące wyniki, ponieważ ma tymczasowe środki zaradcze. Tymczasowe środki zaradcze w przeglądarce Chrome 78+ pozwalają na używanie plików cookie mniej niż dwie minuty. Chrome 76 lub 77 z włączonymi odpowiednimi flagami testowymi zapewnia dokładniejsze wyniki. Aby przetestować nowe zachowanie SameSite, przełączenie chrome://flags/#same-site-by-default-cookies
na włączone. Starsze wersje programu Chrome (75 i starsze) są zgłaszane jako nieudane z nowym None
ustawieniem. Zobacz Obsługa starszych przeglądarek w tym dokumencie.
Firma Google nie udostępnia starszych wersji chrome. Postępuj zgodnie z instrukcjami w temacie Pobierz Chromium , aby przetestować starsze wersje przeglądarki Chrome. Nie pobieraj przeglądarki Chrome z linków udostępnianych przez wyszukiwanie starszych wersji przeglądarki Chrome.
Począwszy od wersji 80.0.3975.0
Canary, tymczasowe ograniczenie ryzyka 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 ostatecznym stanie końcowym funkcji, w której usunięto środki zaradcze. Aby uzyskać więcej informacji, zobacz Chromium Projects SameSite Updates
Testowanie za pomocą przeglądarki Safari
Przeglądarka Safari 12 ściśle zaimplementowała poprzednią wersję roboczą i kończy się niepowodzeniem, gdy nowa None
wartość znajduje się w obiekcie cookie. None
jest unikany za pośrednictwem kodu wykrywania przeglądarki Obsługa starszych przeglądarek w tym dokumencie. Przetestuj identyfikatory logowania w stylu systemu operacyjnego oparte na przeglądarce Safari 12, Safari 13 i 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 zgody na testowanie nowego zachowania specyfikacji.
Testowanie za pomocą przeglądarki Firefox
Obsługa przeglądarki Firefox dla nowego standardu można przetestować w wersji 68 lub nowszej, decydując się na about:config
stronę z flagą network.cookie.sameSite.laxByDefault
funkcji . Nie odnotowano raportów 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 edge://flags/#same-site-by-default-cookies
stronie. Nie odnaleziono żadnych problemów ze zgodnością z przeglądarką Edge Chromium.
Testowanie za pomocą polecenia Electron
Electron Wersje obejmują starsze wersje Chromium. Na przykład wersja Electron używana przez aplikację Teams to Chromium 66, która wykazuje starsze zachowanie. Musisz przeprowadzić własne testy zgodności z wersją używanego Electron produktu. Zobacz Obsługa starszych przeglądarek w poniższej sekcji.
Dodatkowe zasoby
- Blog Chromium:Developers: Get Ready for New SameSite=None; Ustawienia zabezpieczeń Cookie
- SameSite cookie wyjaśnione
- Poprawki z listopada 2019 r.
Przykład | Dokument |
---|---|
.NET Core Razor Pages | przykład ASP.NET Core 3.1 Razor Pages SameSite cookie |
Można pobrać i przetestować następujące przykłady:
Przykład | Dokument |
---|---|
.NET Core MVC | przykład ASP.NET Core 2.1 MVC SameSite cookie |
.NET Core Razor Pages | przykład ASP.NET Core 2.1 Razor Pages SameSite cookie |
Zmiany zachowania poprawki z grudnia
Konkretna zmiana zachowania dla programów .NET Framework i .NET Core 2.1 polega na SameSite
tym, jak właściwość interpretuje None
wartość. Przed poprawką wartość None
oznaczaną "Nie emituj atrybutu w ogóle", po poprawce oznacza to "Emituj atrybut z wartością None
". Po poprawce SameSite
wartość parametru (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 w usłudze SameSite
Wartości domyślne HttpContext.Response.Cookies.Append mają wartość Unspecified
, co oznacza, że do elementu nie dodano atrybutu cookie SameSite, a klient będzie używać jego domyślnego zachowania (Lax dla nowych przeglądarek, Brak dla starych). Poniższy kod pokazuje, jak zmienić cookie wartość 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ęć powyższe wartości domyślne nie zostały zmienione.
Składnik | cookie | Wartość domyślna |
---|---|---|
CookieBuilder | SameSite | Unspecified |
Session | SessionOptions.Cookie | Lax |
CookieTempDataProvider | CookieTempDataProviderOptions.Cookie | Lax |
IAntiforgery | AntiforgeryOptions.Cookie | Strict |
Cookie Uwierzytelnianie | CookieAuthenticationOptions.Cookie | Lax |
AddTwitter | TwitterOptions.StateCookie | Lax |
RemoteAuthenticationHandler<TOptions> | RemoteAuthenticationOptions.CorrelationCookie | None |
AddOpenIdConnect | OpenIdConnectOptions.NonceCookie | None |
HttpContext.Response.Cookies.Append | CookieOptions | Unspecified |
Historia i zmiany
Obsługa sameSite została po raz pierwszy zaimplementowana w programie ASP.NET Core w wersji 2.0 przy użyciu standardu roboczego 2016. Standard 2016 był opt-in. ASP.NET Core , domyślnie ustawiając kilka plików cookie Lax
. Po wystąpieniu kilku problemów z uwierzytelnianiem większość użycia witryny SameSite została wyłączona.
Poprawki zostały wydane w listopadzie 2019 r. w celu zaktualizowania standardu z 2016 r. do standardu 2019. Wersja robocza z 2019 r. specyfikacji SameSite:
- Nie jest do tyłu zgodny 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 asertywne
SameSite=None
w celu włączenia dostarczania między witrynami powinny być oznaczone jakoSecure
.None
jest nowym wpisem, aby zrezygnować. - Jest obsługiwany przez poprawki wydane dla ASP.NET Core 2.1, 2.2 i 3.0. ASP.NET Core 3.1 ma dodatkową obsługę usługi SameSite.
- Program Chrome ma być domyślnie włączony w lutym 2020 roku. Przeglądarki zaczęły przechodzić do tego standardu w 2019 roku.
Interfejsy API, których dotyczy zmiana z wersji roboczej SameSite z 2016 r. do wersji roboczej standardu 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. nakazuje traktowanie nieznanych wartości jako SameSite=Strict
wartości. Aplikacje dostępne ze starszych przeglądarek, 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 agentów użytkowników są bardzo niestabilne i często zmieniają się. Punkt rozszerzenia umożliwia Microsoft.AspNetCore.CookiePolicy podłączanie logiki specyficznej dla agenta użytkownika.
W Startup.Configure
pliku dodaj kod wywołujący UseCookiePolicy przed wywołaniem UseAuthentication metody lub dowolną metodę zapisującą 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.ConfigureServices
pliku 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 aplikacji SameSite None
:
if (MyUserAgentDetectionLib.DisallowsSameSiteNone(userAgent))
{
options.SameSite = SameSiteMode.Unspecified;
}
Poniższy kod przedstawia przykładową DisallowsSameSiteNone
metodę:
Ostrzeżenie
Poniższy kod jest przeznaczony tylko dla pokazu:
- Nie należy go uważać za ukończone.
- Nie jest ona obsługiwana 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 usługą SameSite
Aplikacje, które wchodzą w interakcje z witrynami zdalnymi, takimi jak za pośrednictwem logowania innej firmy, muszą:
- Przetestuj interakcję w wielu przeglądarkach.
- Zastosuj wykrywanie przeglądarki CookiePolicy i środki zaradcze omówione w tym dokumencie.
Przetestuj aplikacje internetowe przy użyciu wersji klienta, która może wyrazić zgodę na nowe zachowanie w witrynie SameSite. Chrome, Firefox i Chromium Edge mają nowe flagi funkcji, które mogą być używane do testowania. Gdy aplikacja zastosuje poprawki SameSite, 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.
Testowanie za pomocą przeglądarki Chrome
Chrome 78+ daje mylące wyniki, ponieważ ma tymczasowe środki zaradcze. Tymczasowe środki zaradcze w przeglądarce Chrome 78+ pozwalają na używanie plików cookie mniej niż dwie minuty. Chrome 76 lub 77 z włączonymi odpowiednimi flagami testowymi zapewnia dokładniejsze wyniki. Aby przetestować nowe zachowanie SameSite, przełączenie chrome://flags/#same-site-by-default-cookies
na włączone. Starsze wersje programu Chrome (75 i starsze) są zgłaszane jako nieudane z nowym None
ustawieniem. Zobacz Obsługa starszych przeglądarek w tym dokumencie.
Firma Google nie udostępnia starszych wersji chrome. Postępuj zgodnie z instrukcjami w temacie Pobierz Chromium , aby przetestować starsze wersje przeglądarki Chrome. Nie pobieraj przeglądarki Chrome z linków udostępnianych przez wyszukiwanie starszych wersji przeglądarki Chrome.
Począwszy od wersji 80.0.3975.0
Canary, tymczasowe ograniczenie ryzyka 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 ostatecznym stanie końcowym funkcji, w której usunięto środki zaradcze. Aby uzyskać więcej informacji, zobacz Chromium Projects SameSite Updates
Testowanie za pomocą przeglądarki Safari
Przeglądarka Safari 12 ściśle zaimplementowała poprzednią wersję roboczą i kończy się niepowodzeniem, gdy nowa None
wartość znajduje się w obiekcie cookie. None
jest unikany za pośrednictwem kodu wykrywania przeglądarki Obsługa starszych przeglądarek w tym dokumencie. Przetestuj identyfikatory logowania w stylu systemu operacyjnego oparte na przeglądarce Safari 12, Safari 13 i 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 zgody na testowanie nowego zachowania specyfikacji.
Testowanie za pomocą przeglądarki Firefox
Obsługa przeglądarki Firefox dla nowego standardu można przetestować w wersji 68 lub nowszej, decydując się na about:config
stronę z flagą network.cookie.sameSite.laxByDefault
funkcji . Nie odnotowano raportów 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 edge://flags/#same-site-by-default-cookies
stronie. Nie odnaleziono żadnych problemów ze zgodnością z przeglądarką Edge Chromium.
Testowanie za pomocą polecenia Electron
Electron Wersje obejmują starsze wersje Chromium. Na przykład wersja Electron używana przez aplikację Teams to Chromium 66, która wykazuje starsze zachowanie. Musisz przeprowadzić własne testy zgodności z wersją używanego Electron produktu. Zobacz Obsługa starszych przeglądarek w poniższej sekcji.
Dodatkowe zasoby
- Blog Chromium:Developers: Get Ready for New SameSite=None; Ustawienia zabezpieczeń Cookie
- SameSite cookie wyjaśnione
- Poprawki z listopada 2019 r.
Przykład | Dokument |
---|---|
.NET Core MVC | przykład ASP.NET Core 2.1 MVC SameSite cookie |
.NET Core Razor Pages | przykład ASP.NET Core 2.1 Razor Pages SameSite cookie |