Usare i cookie SameSite in ASP.NET Core
SameSite è uno standard IETF progettato per fornire una certa protezione contro attacchi di richiesta intersito falsa (CSRF). Originariamente elaborato nel 2016, il progetto standard è stato aggiornato nel 2019. Lo standard aggiornato non è compatibile con le versioni precedenti, con le differenze più evidenti:
- I cookie senza intestazione SameSite vengono considerati come
SameSite=Lax
per impostazione predefinita. SameSite=None
deve essere utilizzato per consentire l'uso tra siti cookie .- Anche i cookie che asserzione
SameSite=None
devono essere contrassegnati comeSecure
. - Le applicazioni che usano
<iframe>
possono riscontrare problemi consameSite=Lax
osameSite=Strict
cookie perché<iframe>
vengono considerati scenari tra siti. - Il valore
SameSite=None
non è consentito dallo standard 2016 e fa sì che alcune implementazioni considerino tali cookie comeSameSite=Strict
. Vedere Supporto di browser meno recenti in questo documento.
L'impostazione SameSite=Lax
funziona per la maggior parte dei cookie dell'applicazione. Per impostazione predefinita, alcune forme di autenticazione come OpenID Connect (OIDC) e WS-Federation vengono reindirizzati basati su POST. I reindirizzamenti basati su POST attivano le protezioni del browser SameSite, quindi SameSite è disabilitato per questi componenti. La maggior parte degli account di accesso OAuth non è interessata a causa delle differenze nel flusso della richiesta.
Ogni componente ASP.NET Core che genera cookie deve decidere se SameSite è appropriato.
SameSite e Identity
ASP.NET Core Identity non è in gran parte interessato dai cookie SameSite, ad eccezione di scenari avanzati come IFrames
o OpenIdConnect
integrazione.
Quando si usa Identity
, non aggiungere cookie provider o chiamare services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
, Identity
si occupa di questo.
Codice di esempio di test SameSite
L'esempio seguente può essere scaricato e testato:
Esempio | Document |
---|---|
Pagine .NET Core Razor | Esempio samesite cookie di ASP.NET Core 3.1 Razor Pages |
Supporto di .NET Core per lo stesso attributoSite
.NET Core supporta lo standard draft 2019 per SameSite. Gli sviluppatori possono controllare a livello di codice il valore dello stesso attributoSite usando la HttpCookie.SameSite
proprietà . L'impostazione della SameSite
proprietà su Strict
, Lax
o None
comporta la scrittura di tali valori nella rete con .cookie L'impostazione su SameSiteMode.Unspecified
indica che non deve essere inviato alcun sito con .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);
}
Utilizzo dell'API con SameSite
HttpContext.Response.Cookies.Append usa Unspecified
per impostazione predefinita , ovvero nessun attributo SameSite aggiunto a cookie e il client userà il comportamento predefinito (Lax per i nuovi browser, Nessuno per quelli precedenti). Il codice seguente illustra come modificare il cookie valore SameSite in SameSiteMode.Lax
:
HttpContext.Response.Cookies.Append(
"name", "value",
new CookieOptions() { SameSite = SameSiteMode.Lax });
Tutti i componenti di base ASP.NET che generano cookie sostituiscono le impostazioni predefinite precedenti con le impostazioni appropriate per i relativi scenari. I valori predefiniti precedenti sottoposti a override non sono stati modificati.
Componente | cookie | Predefiniti |
---|---|---|
CookieBuilder | SameSite | Unspecified |
Session | SessionOptions.Cookie | Lax |
CookieTempDataProvider | CookieTempDataProviderOptions.Cookie | Lax |
IAntiforgery | AntiforgeryOptions.Cookie | Strict |
Cookie Autenticazione di | CookieAuthenticationOptions.Cookie | Lax |
AddTwitter | TwitterOptions.StateCookie | Lax |
RemoteAuthenticationHandler<TOptions> | RemoteAuthenticationOptions.CorrelationCookie | None |
AddOpenIdConnect | OpenIdConnectOptions.NonceCookie | None |
HttpContext.Response.Cookies.Append | CookieOptions | Unspecified |
ASP.NET Core 3.1 e versioni successive offre il supporto SameSite seguente:
- Ridefinisce il comportamento di
SameSiteMode.None
da generareSameSite=None
- Aggiunge un nuovo valore
SameSiteMode.Unspecified
per omettere l'attributo SameSite. - Per impostazione predefinita, tutte le API dei cookie sono
Unspecified
. Alcuni componenti che usano i cookie impostano valori più specifici per i relativi scenari. Per esempi, vedere la tabella precedente.
In ASP.NET Core 3.0 e versioni successive le impostazioni predefinite SameSite sono state modificate per evitare conflitti con impostazioni predefinite client incoerenti. Le API seguenti hanno modificato il valore predefinito da SameSiteMode.Lax
a per -1
evitare di emettere un attributo SameSite per questi cookie:
- CookieOptions utilizzato con HttpContext.Response.Cookies.Append
- CookieBuilder usato come factory per
CookieOptions
- CookiePolicyOptions.MinimumSameSitePolicy
Cronologia e modifiche
Il supporto sameSite è stato implementato per la prima volta in ASP.NET Core nella versione 2.0 usando lo standard draft 2016. Lo standard 2016 è stato consenso esplicito. ASP.NET Core acconsente esplicitamente impostando diversi cookie su Lax
per impostazione predefinita. Dopo aver riscontrato diversi problemi con l'autenticazione, la maggior parte dell'utilizzo di SameSite è stata disabilitata.
Le patch sono state rilasciate a novembre 2019 per l'aggiornamento dallo standard 2016 allo standard 2019. La bozza 2019 della specifica SameSite:
- Non è compatibile con le versioni precedenti della bozza del 2016. Per altre informazioni, vedere Supporto di browser meno recenti in questo documento.
- Specifica che i cookie vengono considerati come
SameSite=Lax
per impostazione predefinita. - Specifica i cookie che asserisce
SameSite=None
in modo esplicito per abilitare il recapito tra siti deve essere contrassegnato comeSecure
.None
è una nuova voce da rifiutare esplicitamente. - È supportato dalle patch rilasciate per ASP.NET Core 2.1, 2.2 e 3.0. ASP.NET Core 3.1 e versioni successive include supporto SameSite aggiuntivo.
- È pianificata l'abilitazione di Chrome per impostazione predefinita nel febbraio 2020. I browser hanno iniziato a passare a questo standard nel 2019.
API interessate dalla modifica dallo standard SameSite 2016 allo standard draft 2019
- Http.SameSiteMode
- CookieOptions.SameSite
- CookieBuilder.SameSite
- CookiePolicyOptions.MinimumSameSitePolicy
- Microsoft.Net.Http.Headers.SameSiteMode
- Microsoft.Net.Http.Headers.SetCookieHeaderValue.SameSite
Supporto di browser meno recenti
Lo standard SameSite 2016 impone che i valori sconosciuti debbano essere considerati come SameSite=Strict
valori. Le app a cui si accede da browser meno recenti che supportano lo standard SameSite 2016 possono interrompersi quando ottengono una proprietà SameSite con un valore .None
Le app Web devono implementare il rilevamento del browser se intendono supportare browser meno recenti. ASP.NET Core non implementa il rilevamento del browser perché i valori degli agenti utente sono altamente volatili e cambiano frequentemente. Un punto di estensione in Microsoft.AspNetCore.CookiePolicy consente il plug-in logica specifica dell'agente utente.
In Program.cs
aggiungere codice che chiama UseCookiePolicy prima di chiamare UseAuthentication o qualsiasi metodo che scrive i 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();
In Program.cs
aggiungere codice simile al codice evidenziato seguente:
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();
Nell'esempio precedente è MyUserAgentDetectionLib.DisallowsSameSiteNone
una libreria fornita dall'utente che rileva se l'agente utente non supporta SameSite None
:
if (MyUserAgentDetectionLib.DisallowsSameSiteNone(userAgent))
{
options.SameSite = SameSiteMode.Unspecified;
}
Il codice seguente illustra un metodo di esempio DisallowsSameSiteNone
:
Avviso
Il codice seguente è solo per dimostrazione:
- Non deve essere considerato completo.
- Non viene gestito o supportato.
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;
}
Testare le app per problemi SameSite
Le app che interagiscono con siti remoti, ad esempio tramite l'accesso di terze parti, devono:
- Testare l'interazione su più browser.
- Applicare il rilevamento e la mitigazione del browser CookiePolicy descritti in questo documento.
Testare le app Web usando una versione client che può acconsentire esplicitamente al nuovo comportamento SameSite. Chrome, Firefox e Chromium Edge hanno tutti nuovi flag di funzionalità di consenso esplicito che possono essere usati per i test. Dopo che l'app applica le patch SameSite, testarla con le versioni client precedenti, in particolare Safari. Per altre informazioni, vedere Supporto di browser meno recenti in questo documento.
Testare con Chrome
Chrome 78+ offre risultati fuorvianti perché ha una mitigazione temporanea sul posto. La mitigazione temporanea di Chrome 78+ consente i cookie meno di due minuti prima. Chrome 76 o 77 con i flag di test appropriati abilitati fornisce risultati più accurati. Per testare il nuovo comportamento SameSite, chrome://flags/#same-site-by-default-cookies
impostare Abilitato. Le versioni precedenti di Chrome (75 e versioni successive) vengono segnalate come non riuscita con la nuova None
impostazione. Vedere Supporto di browser meno recenti in questo documento.
Google non rende disponibili versioni chrome meno recenti. Seguire le istruzioni in Scaricare Chromium per testare le versioni precedenti di Chrome. Non scaricare Chrome dai collegamenti forniti cercando versioni precedenti di Chrome.
A partire da Canary versione 80.0.3975.0
, la mitigazione temporanea Lax+POST può essere disabilitata a scopo di test usando il nuovo flag --enable-features=SameSiteDefaultChecksMethodRigorously
per consentire il test di siti e servizi nello stato finale finale della funzionalità in cui è stata rimossa la mitigazione. Per altre informazioni, vedere The Chromium Projects SameSite Updates
Eseguire test con Safari
Safari 12 ha implementato rigorosamente la bozza precedente e ha esito negativo quando il nuovo None
valore si trova in un oggetto cookie. None
viene evitato tramite il codice di rilevamento del browser Supporto dei browser meno recenti in questo documento. Testare gli account di accesso basati sul sistema operativo basati su Safari 12, Safari 13 e WebKit usando MSAL, ADAL o qualsiasi libreria in uso. Il problema dipende dalla versione del sistema operativo sottostante. OSX Mojave (10.14) e iOS 12 sono noti per avere problemi di compatibilità con il nuovo comportamento SameSite. L'aggiornamento del sistema operativo a OSX Catalina (10.15) o iOS 13 risolve il problema. Safari non dispone attualmente di un flag di consenso esplicito per testare il nuovo comportamento della specifica.
Testare con Firefox
Il supporto di Firefox per il nuovo standard può essere testato sulla versione 68+ optando per la about:config
pagina con il flag network.cookie.sameSite.laxByDefault
di funzionalità . Non sono stati segnalati problemi di compatibilità con le versioni precedenti di Firefox.
Testare con il browser Edge
Edge supporta lo standard SameSite precedente. Edge versione 44 non presenta problemi di compatibilità noti con il nuovo standard.
Test con edge (Chromium)
I flag SameSite vengono impostati nella edge://flags/#same-site-by-default-cookies
pagina. Non sono stati rilevati problemi di compatibilità con Edge Chromium.
Test con Electron
Le versioni di Electron includono versioni precedenti di Chromium. Ad esempio, la versione di Electron usata da Teams è Chromium 66, che mostra il comportamento precedente. È necessario eseguire test di compatibilità personalizzati con la versione del Electron prodotto in uso. Vedere Supporto di browser meno recenti nella sezione seguente.
Risorse aggiuntive
- Chromium Blog:Developers: Get Ready for New SameSite=None; Impostazioni protette Cookie
- Spiegazione dei cookie SameSite
- Patch di novembre 2019
Esempio | Document |
---|---|
Pagine .NET Core Razor | Esempio samesite cookie di ASP.NET Core 3.1 Razor Pages |
L'esempio seguente può essere scaricato e testato:
Esempio | Document |
---|---|
Pagine .NET Core Razor | Esempio samesite cookie di ASP.NET Core 3.1 Razor Pages |
Supporto di .NET Core per lo stesso attributoSite
.NET Core 3.1 e versioni successive supportano lo standard draft 2019 per SameSite. Gli sviluppatori possono controllare a livello di codice il valore dello stesso attributoSite usando la HttpCookie.SameSite
proprietà . L'impostazione della SameSite
proprietà su Strict, Lax o None comporta la scrittura di tali valori nella rete con .cookie L'impostazione è uguale a (SameSiteMode)(-1)
indica che non deve essere incluso alcun attributo SameSite nella rete con il 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);
.NET Core 3.1 e versioni successive supportano i valori SameSite aggiornati e aggiunge un valore enumerazione aggiuntivo all'enumerazione SameSiteMode.Unspecified
SameSiteMode
.
Questo nuovo valore indica che non deve essere inviato alcun oggetto SameSite con .cookie
Utilizzo dell'API con SameSite
HttpContext.Response.Cookies.Append usa Unspecified
per impostazione predefinita , ovvero nessun attributo SameSite aggiunto a cookie e il client userà il comportamento predefinito (Lax per i nuovi browser, Nessuno per quelli precedenti). Il codice seguente illustra come modificare il cookie valore SameSite in SameSiteMode.Lax
:
HttpContext.Response.Cookies.Append(
"name", "value",
new CookieOptions() { SameSite = SameSiteMode.Lax });
Tutti i componenti di base ASP.NET che generano cookie sostituiscono le impostazioni predefinite precedenti con le impostazioni appropriate per i relativi scenari. I valori predefiniti precedenti sottoposti a override non sono stati modificati.
Componente | cookie | Predefiniti |
---|---|---|
CookieBuilder | SameSite | Unspecified |
Session | SessionOptions.Cookie | Lax |
CookieTempDataProvider | CookieTempDataProviderOptions.Cookie | Lax |
IAntiforgery | AntiforgeryOptions.Cookie | Strict |
Cookie Autenticazione di | CookieAuthenticationOptions.Cookie | Lax |
AddTwitter | TwitterOptions.StateCookie | Lax |
RemoteAuthenticationHandler<TOptions> | RemoteAuthenticationOptions.CorrelationCookie | None |
AddOpenIdConnect | OpenIdConnectOptions.NonceCookie | None |
HttpContext.Response.Cookies.Append | CookieOptions | Unspecified |
ASP.NET Core 3.1 e versioni successive offre il supporto SameSite seguente:
- Ridefinisce il comportamento di
SameSiteMode.None
da generareSameSite=None
- Aggiunge un nuovo valore
SameSiteMode.Unspecified
per omettere l'attributo SameSite. - Per impostazione predefinita, tutte le API dei cookie sono
Unspecified
. Alcuni componenti che usano i cookie impostano valori più specifici per i relativi scenari. Per esempi, vedere la tabella precedente.
In ASP.NET Core 3.0 e versioni successive le impostazioni predefinite SameSite sono state modificate per evitare conflitti con impostazioni predefinite client incoerenti. Le API seguenti hanno modificato il valore predefinito da SameSiteMode.Lax
a per -1
evitare di emettere un attributo SameSite per questi cookie:
- CookieOptions utilizzato con HttpContext.Response.Cookies.Append
- CookieBuilder usato come factory per
CookieOptions
- CookiePolicyOptions.MinimumSameSitePolicy
Cronologia e modifiche
Il supporto sameSite è stato implementato per la prima volta in ASP.NET Core nella versione 2.0 usando lo standard draft 2016. Lo standard 2016 è stato consenso esplicito. ASP.NET Core acconsente esplicitamente impostando diversi cookie su Lax
per impostazione predefinita. Dopo aver riscontrato diversi problemi con l'autenticazione, la maggior parte dell'utilizzo di SameSite è stata disabilitata.
Le patch sono state rilasciate a novembre 2019 per l'aggiornamento dallo standard 2016 allo standard 2019. La bozza 2019 della specifica SameSite:
- Non è compatibile con le versioni precedenti della bozza del 2016. Per altre informazioni, vedere Supporto di browser meno recenti in questo documento.
- Specifica che i cookie vengono considerati come
SameSite=Lax
per impostazione predefinita. - Specifica i cookie che asserisce
SameSite=None
in modo esplicito per abilitare il recapito tra siti deve essere contrassegnato comeSecure
.None
è una nuova voce da rifiutare esplicitamente. - È supportato dalle patch rilasciate per ASP.NET Core 2.1, 2.2 e 3.0. ASP.NET Core 3.1 include supporto SameSite aggiuntivo.
- È pianificata l'abilitazione di Chrome per impostazione predefinita nel febbraio 2020. I browser hanno iniziato a passare a questo standard nel 2019.
API interessate dalla modifica dallo standard SameSite 2016 allo standard draft 2019
- Http.SameSiteMode
- CookieOptions.SameSite
- CookieBuilder.SameSite
- CookiePolicyOptions.MinimumSameSitePolicy
- Microsoft.Net.Http.Headers.SameSiteMode
- Microsoft.Net.Http.Headers.SetCookieHeaderValue.SameSite
Supporto di browser meno recenti
Lo standard SameSite 2016 impone che i valori sconosciuti debbano essere considerati come SameSite=Strict
valori. Le app a cui si accede da browser meno recenti che supportano lo standard SameSite 2016 possono interrompersi quando ottengono una proprietà SameSite con un valore .None
Le app Web devono implementare il rilevamento del browser se intendono supportare browser meno recenti. ASP.NET Core non implementa il rilevamento del browser perché i valori degli agenti utente sono altamente volatili e cambiano frequentemente. Un punto di estensione in Microsoft.AspNetCore.CookiePolicy consente il plug-in logica specifica dell'agente utente.
In Startup.Configure
aggiungere codice che chiama UseCookiePolicy prima di chiamare UseAuthentication o qualsiasi metodo che scrive i 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();
});
}
In Startup.ConfigureServices
aggiungere codice simile al seguente:
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;
}
}
}
Nell'esempio precedente è MyUserAgentDetectionLib.DisallowsSameSiteNone
una libreria fornita dall'utente che rileva se l'agente utente non supporta SameSite None
:
if (MyUserAgentDetectionLib.DisallowsSameSiteNone(userAgent))
{
options.SameSite = SameSiteMode.Unspecified;
}
Il codice seguente illustra un metodo di esempio DisallowsSameSiteNone
:
Avviso
Il codice seguente è solo per dimostrazione:
- Non deve essere considerato completo.
- Non viene gestito o supportato.
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;
}
Testare le app per problemi SameSite
Le app che interagiscono con siti remoti, ad esempio tramite l'accesso di terze parti, devono:
- Testare l'interazione su più browser.
- Applicare il rilevamento e la mitigazione del browser CookiePolicy descritti in questo documento.
Testare le app Web usando una versione client che può acconsentire esplicitamente al nuovo comportamento SameSite. Chrome, Firefox e Chromium Edge hanno tutti nuovi flag di funzionalità di consenso esplicito che possono essere usati per i test. Dopo che l'app applica le patch SameSite, testarla con le versioni client precedenti, in particolare Safari. Per altre informazioni, vedere Supporto di browser meno recenti in questo documento.
Testare con Chrome
Chrome 78+ offre risultati fuorvianti perché ha una mitigazione temporanea sul posto. La mitigazione temporanea di Chrome 78+ consente i cookie meno di due minuti prima. Chrome 76 o 77 con i flag di test appropriati abilitati fornisce risultati più accurati. Per testare il nuovo comportamento SameSite, chrome://flags/#same-site-by-default-cookies
impostare Abilitato. Le versioni precedenti di Chrome (75 e versioni successive) vengono segnalate come non riuscita con la nuova None
impostazione. Vedere Supporto di browser meno recenti in questo documento.
Google non rende disponibili versioni chrome meno recenti. Seguire le istruzioni in Scaricare Chromium per testare le versioni precedenti di Chrome. Non scaricare Chrome dai collegamenti forniti cercando versioni precedenti di Chrome.
A partire da Canary versione 80.0.3975.0
, la mitigazione temporanea Lax+POST può essere disabilitata a scopo di test usando il nuovo flag --enable-features=SameSiteDefaultChecksMethodRigorously
per consentire il test di siti e servizi nello stato finale finale della funzionalità in cui è stata rimossa la mitigazione. Per altre informazioni, vedere The Chromium Projects SameSite Updates
Eseguire test con Safari
Safari 12 ha implementato rigorosamente la bozza precedente e ha esito negativo quando il nuovo None
valore si trova in un oggetto cookie. None
viene evitato tramite il codice di rilevamento del browser Supporto dei browser meno recenti in questo documento. Testare gli account di accesso basati sul sistema operativo basati su Safari 12, Safari 13 e WebKit usando MSAL, ADAL o qualsiasi libreria in uso. Il problema dipende dalla versione del sistema operativo sottostante. OSX Mojave (10.14) e iOS 12 sono noti per avere problemi di compatibilità con il nuovo comportamento SameSite. L'aggiornamento del sistema operativo a OSX Catalina (10.15) o iOS 13 risolve il problema. Safari non dispone attualmente di un flag di consenso esplicito per testare il nuovo comportamento della specifica.
Testare con Firefox
Il supporto di Firefox per il nuovo standard può essere testato sulla versione 68+ optando per la about:config
pagina con il flag network.cookie.sameSite.laxByDefault
di funzionalità . Non sono stati segnalati problemi di compatibilità con le versioni precedenti di Firefox.
Testare con il browser Edge
Edge supporta lo standard SameSite precedente. Edge versione 44 non presenta problemi di compatibilità noti con il nuovo standard.
Test con edge (Chromium)
I flag SameSite vengono impostati nella edge://flags/#same-site-by-default-cookies
pagina. Non sono stati rilevati problemi di compatibilità con Edge Chromium.
Test con Electron
Le versioni di Electron includono versioni precedenti di Chromium. Ad esempio, la versione di Electron usata da Teams è Chromium 66, che mostra il comportamento precedente. È necessario eseguire test di compatibilità personalizzati con la versione del Electron prodotto in uso. Vedere Supporto di browser meno recenti nella sezione seguente.
Risorse aggiuntive
- Chromium Blog:Developers: Get Ready for New SameSite=None; Impostazioni protette Cookie
- Spiegazione dei cookie SameSite
- Patch di novembre 2019
Esempio | Document |
---|---|
Pagine .NET Core Razor | Esempio samesite cookie di ASP.NET Core 3.1 Razor Pages |
È possibile scaricare e testare gli esempi seguenti:
Esempio | Document |
---|---|
.NET Core MVC | Esempio sameSite cookie di ASP.NET Core 2.1 MVC |
Pagine .NET Core Razor | Esempio SameSite cookie di ASP.NET Core 2.1 Razor Pages |
Modifiche al comportamento delle patch di dicembre
La modifica del comportamento specifica per .NET Framework e .NET Core 2.1 è il modo in cui la SameSite
proprietà interpreta il None
valore. Prima della patch un valore " None
Non generare affatto l'attributo" dopo la patch significa "Emit the attribute with a value of None
". Dopo la patch un SameSite
valore di (SameSiteMode)(-1)
fa sì che l'attributo non venga generato.
Il valore SameSite predefinito per l'autenticazione basata su form e i cookie di stato della sessione sono stati modificati da None
a Lax
.
Utilizzo dell'API con SameSite
HttpContext.Response.Cookies.Append usa Unspecified
per impostazione predefinita , ovvero nessun attributo SameSite aggiunto a cookie e il client userà il comportamento predefinito (Lax per i nuovi browser, Nessuno per quelli precedenti). Il codice seguente illustra come modificare il cookie valore SameSite in SameSiteMode.Lax
:
HttpContext.Response.Cookies.Append(
"name", "value",
new CookieOptions() { SameSite = SameSiteMode.Lax });
Tutti i componenti di base ASP.NET che generano cookie sostituiscono le impostazioni predefinite precedenti con le impostazioni appropriate per i relativi scenari. I valori predefiniti precedenti sottoposti a override non sono stati modificati.
Componente | cookie | Predefiniti |
---|---|---|
CookieBuilder | SameSite | Unspecified |
Session | SessionOptions.Cookie | Lax |
CookieTempDataProvider | CookieTempDataProviderOptions.Cookie | Lax |
IAntiforgery | AntiforgeryOptions.Cookie | Strict |
Cookie Autenticazione di | CookieAuthenticationOptions.Cookie | Lax |
AddTwitter | TwitterOptions.StateCookie | Lax |
RemoteAuthenticationHandler<TOptions> | RemoteAuthenticationOptions.CorrelationCookie | None |
AddOpenIdConnect | OpenIdConnectOptions.NonceCookie | None |
HttpContext.Response.Cookies.Append | CookieOptions | Unspecified |
Cronologia e modifiche
Il supporto sameSite è stato implementato per la prima volta in ASP.NET Core nella versione 2.0 usando lo standard draft 2016. Lo standard 2016 è stato consenso esplicito. ASP.NET Core acconsente esplicitamente impostando diversi cookie su Lax
per impostazione predefinita. Dopo aver riscontrato diversi problemi con l'autenticazione, la maggior parte dell'utilizzo di SameSite è stata disabilitata.
Le patch sono state rilasciate a novembre 2019 per l'aggiornamento dallo standard 2016 allo standard 2019. La bozza 2019 della specifica SameSite:
- Non è compatibile con le versioni precedenti della bozza del 2016. Per altre informazioni, vedere Supporto di browser meno recenti in questo documento.
- Specifica che i cookie vengono considerati come
SameSite=Lax
per impostazione predefinita. - Specifica i cookie che asserisce
SameSite=None
in modo esplicito per abilitare il recapito tra siti deve essere contrassegnato comeSecure
.None
è una nuova voce da rifiutare esplicitamente. - È supportato dalle patch rilasciate per ASP.NET Core 2.1, 2.2 e 3.0. ASP.NET Core 3.1 include supporto SameSite aggiuntivo.
- È pianificata l'abilitazione di Chrome per impostazione predefinita nel febbraio 2020. I browser hanno iniziato a passare a questo standard nel 2019.
API interessate dalla modifica dallo standard SameSite 2016 allo standard draft 2019
- Http.SameSiteMode
- CookieOptions.SameSite
- CookieBuilder.SameSite
- CookiePolicyOptions.MinimumSameSitePolicy
- Microsoft.Net.Http.Headers.SameSiteMode
- Microsoft.Net.Http.Headers.SetCookieHeaderValue.SameSite
Supporto di browser meno recenti
Lo standard SameSite 2016 impone che i valori sconosciuti debbano essere considerati come SameSite=Strict
valori. Le app a cui si accede da browser meno recenti che supportano lo standard SameSite 2016 possono interrompersi quando ottengono una proprietà SameSite con un valore .None
Le app Web devono implementare il rilevamento del browser se intendono supportare browser meno recenti. ASP.NET Core non implementa il rilevamento del browser perché i valori degli agenti utente sono altamente volatili e cambiano frequentemente. Un punto di estensione in Microsoft.AspNetCore.CookiePolicy consente il plug-in logica specifica dell'agente utente.
In Startup.Configure
aggiungere codice che chiama UseCookiePolicy prima di chiamare UseAuthentication o qualsiasi metodo che scrive i 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();
});
}
In Startup.ConfigureServices
aggiungere codice simile al seguente:
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);
}
}
}
Nell'esempio precedente è MyUserAgentDetectionLib.DisallowsSameSiteNone
una libreria fornita dall'utente che rileva se l'agente utente non supporta SameSite None
:
if (MyUserAgentDetectionLib.DisallowsSameSiteNone(userAgent))
{
options.SameSite = SameSiteMode.Unspecified;
}
Il codice seguente illustra un metodo di esempio DisallowsSameSiteNone
:
Avviso
Il codice seguente è solo per dimostrazione:
- Non deve essere considerato completo.
- Non viene gestito o supportato.
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;
}
Testare le app per problemi SameSite
Le app che interagiscono con siti remoti, ad esempio tramite l'accesso di terze parti, devono:
- Testare l'interazione su più browser.
- Applicare il rilevamento e la mitigazione del browser CookiePolicy descritti in questo documento.
Testare le app Web usando una versione client che può acconsentire esplicitamente al nuovo comportamento SameSite. Chrome, Firefox e Chromium Edge hanno tutti nuovi flag di funzionalità di consenso esplicito che possono essere usati per i test. Dopo che l'app applica le patch SameSite, testarla con le versioni client precedenti, in particolare Safari. Per altre informazioni, vedere Supporto di browser meno recenti in questo documento.
Testare con Chrome
Chrome 78+ offre risultati fuorvianti perché ha una mitigazione temporanea sul posto. La mitigazione temporanea di Chrome 78+ consente i cookie meno di due minuti prima. Chrome 76 o 77 con i flag di test appropriati abilitati fornisce risultati più accurati. Per testare il nuovo comportamento SameSite, chrome://flags/#same-site-by-default-cookies
impostare Abilitato. Le versioni precedenti di Chrome (75 e versioni successive) vengono segnalate come non riuscita con la nuova None
impostazione. Vedere Supporto di browser meno recenti in questo documento.
Google non rende disponibili versioni chrome meno recenti. Seguire le istruzioni in Scaricare Chromium per testare le versioni precedenti di Chrome. Non scaricare Chrome dai collegamenti forniti cercando versioni precedenti di Chrome.
A partire da Canary versione 80.0.3975.0
, la mitigazione temporanea Lax+POST può essere disabilitata a scopo di test usando il nuovo flag --enable-features=SameSiteDefaultChecksMethodRigorously
per consentire il test di siti e servizi nello stato finale finale della funzionalità in cui è stata rimossa la mitigazione. Per altre informazioni, vedere The Chromium Projects SameSite Updates
Eseguire test con Safari
Safari 12 ha implementato rigorosamente la bozza precedente e ha esito negativo quando il nuovo None
valore si trova in un oggetto cookie. None
viene evitato tramite il codice di rilevamento del browser Supporto dei browser meno recenti in questo documento. Testare gli account di accesso basati sul sistema operativo basati su Safari 12, Safari 13 e WebKit usando MSAL, ADAL o qualsiasi libreria in uso. Il problema dipende dalla versione del sistema operativo sottostante. OSX Mojave (10.14) e iOS 12 sono noti per avere problemi di compatibilità con il nuovo comportamento SameSite. L'aggiornamento del sistema operativo a OSX Catalina (10.15) o iOS 13 risolve il problema. Safari non dispone attualmente di un flag di consenso esplicito per testare il nuovo comportamento della specifica.
Testare con Firefox
Il supporto di Firefox per il nuovo standard può essere testato sulla versione 68+ optando per la about:config
pagina con il flag network.cookie.sameSite.laxByDefault
di funzionalità . Non sono stati segnalati problemi di compatibilità con le versioni precedenti di Firefox.
Testare con il browser Edge
Edge supporta lo standard SameSite precedente. Edge versione 44 non presenta problemi di compatibilità noti con il nuovo standard.
Test con edge (Chromium)
I flag SameSite vengono impostati nella edge://flags/#same-site-by-default-cookies
pagina. Non sono stati rilevati problemi di compatibilità con Edge Chromium.
Test con Electron
Le versioni di Electron includono versioni precedenti di Chromium. Ad esempio, la versione di Electron usata da Teams è Chromium 66, che mostra il comportamento precedente. È necessario eseguire test di compatibilità personalizzati con la versione del Electron prodotto in uso. Vedere Supporto di browser meno recenti nella sezione seguente.
Risorse aggiuntive
- Chromium Blog:Developers: Get Ready for New SameSite=None; Impostazioni protette Cookie
- Spiegazione dei cookie SameSite
- Patch di novembre 2019
Esempio | Document |
---|---|
.NET Core MVC | Esempio sameSite cookie di ASP.NET Core 2.1 MVC |
Pagine .NET Core Razor | Esempio SameSite cookie di ASP.NET Core 2.1 Razor Pages |