Condividi tramite


Usare i cookie SameSite in ASP.NET Core

Di Rick Anderson

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 come Secure.
  • Le applicazioni che usano <iframe> possono riscontrare problemi con sameSite=Lax o sameSite=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 come SameSite=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, Laxo 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 Unspecifiedper 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 generare SameSite=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:

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 come Secure. 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

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.csaggiungere 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.csaggiungere 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.laxByDefaultdi 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

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 Unspecifiedper 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 generare SameSite=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:

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 come Secure. 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

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.Configureaggiungere 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.ConfigureServicesaggiungere 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.laxByDefaultdi 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

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 Unspecifiedper 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 come Secure. 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

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.Configureaggiungere 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.ConfigureServicesaggiungere 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.laxByDefaultdi 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

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