Leggere in inglese

Condividi tramite


Esempio di cookie SameSite per ASP.NET 4.7.2 C# MVC

.NET Framework 4.7 include il supporto predefinito per l'attributo SameSite , ma è conforme allo standard originale. Il comportamento con patch ha modificato il significato di SameSite.None per generare l'attributo con un valore , Noneanziché generare il valore. Se si desidera non generare il valore, è possibile impostare la SameSite proprietà su un cookie su -1.

Scrittura dell'attributo SameSite

Di seguito è riportato un esempio di come scrivere un attributo SameSite in un cookie;

// Create the cookie
HttpCookie sameSiteCookie = new HttpCookie("SameSiteSample");

// Set a value for the cookieSite none.
// Note this will also require you to be running on HTTPS
sameSiteCookie.Value = "sample";

// Set the secure flag, which Chrome's changes will require for Same
sameSiteCookie.Secure = true;

// Set the cookie to HTTP only which is good practice unless you really do need
// to access it client side in scripts.
sameSiteCookie.HttpOnly = true;

// Add the SameSite attribute, this will emit the attribute with a value of none.
// To not emit the attribute at all set the SameSite property to -1.
sameSiteCookie.SameSite = SameSiteMode.None;

// Add the cookie to the response cookie collection
Response.Cookies.Add(sameSiteCookie);

Se si sta leggendo questa operazione in una lingua diversa dall'inglese, segnalarlo in questo problema di discussione su GitHub se si vogliono visualizzare i commenti del codice nella lingua nativa.

L'attributo predefinito sameSite per lo stato della sessione viene impostato nel parametro 'cookieSameSite' delle impostazioni della sessione in web.config

<system.web>
  <sessionState cookieSameSite="None">     
  </sessionState>
</system.web>

Autenticazione MVC

L'autenticazione basata su cookie OWIN MVC usa un gestore cookie per abilitare la modifica degli attributi dei cookie. SameSiteCookieManager.cs è un'implementazione di tale classe che è possibile copiare nei propri progetti.

È necessario assicurarsi che i componenti Microsoft.Owin siano tutti aggiornati alla versione 4.1.0 o successiva. Controllare il packages.config file per verificare che tutti i numeri di versione corrispondano, ad esempio.

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <!-- other packages -->
  <package id="Microsoft.Owin.Host.SystemWeb" version="4.1.0" targetFramework="net472" />
  <package id="Microsoft.Owin.Security" version="4.1.0" targetFramework="net472" />
  <package id="Microsoft.Owin.Security.Cookies" version="4.1.0" targetFramework="net472" />
  <package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net472" />
  <package id="Owin" version="1.0" targetFramework="net472" />
</packages>

I componenti di autenticazione devono quindi essere configurati per l'uso di CookieManager nella classe di avvio;

public void Configuration(IAppBuilder app)
{
    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
        CookieSameSite = SameSiteMode.None,
        CookieHttpOnly = true,
        CookieSecure = CookieSecureOption.Always,
        CookieManager = new SameSiteCookieManager(new SystemWebCookieManager())
    });
}

È necessario impostare un gestore cookie in ogni componente che lo supporta, inclusi CookieAuthentication e OpenIdConnectAuthentication.

SystemWebCookieManager viene usato per evitare problemi noti con l'integrazione dei cookie di risposta.

Esecuzione dell'esempio

Se si esegue il progetto di esempio, caricare il debugger del browser nella pagina iniziale e usarlo per visualizzare la raccolta di cookie per il sito. A tale scopo, in Edge e Chrome premere F12 quindi selezionare la Application scheda e fare clic sull'URL del sito sotto l'opzione Cookies nella Storage sezione.

Elenco cookie del debugger del browser

È possibile vedere dall'immagine precedente che il cookie creato dall'esempio quando si fa clic sul pulsante "Crea cookie" ha un valore di attributo SameSite pari Laxa , che corrisponde al valore impostato nel codice di esempio.

Intercettazione dei cookie non controllate

.NET 4.5.2 ha introdotto un nuovo evento per intercettare la scrittura di intestazioni, Response.AddOnSendingHeaders. Questa operazione può essere usata per intercettare i cookie prima che vengano restituiti al computer client. Nell'esempio si collega l'evento a un metodo statico che controlla se il browser supporta le modifiche dello stesso sito e, in caso contrario, modifica i cookie per non generare l'attributo se il nuovo None valore è stato impostato.

Vedere global.asax per un esempio di associazione dell'evento e SameSiteCookieRewriter.cs per un esempio di gestione dell'evento e modifica dell'attributo cookie sameSite che è possibile copiare nel codice.

public static void FilterSameSiteNoneForIncompatibleUserAgents(object sender)
{
    HttpApplication application = sender as HttpApplication;
    if (application != null)
    {
        var userAgent = application.Context.Request.UserAgent;
        if (SameSite.BrowserDetection.DisallowsSameSiteNone(userAgent))
        {
            HttpContext.Current.Response.AddOnSendingHeaders(context =>
            {
                var cookies = context.Response.Cookies;
                for (var i = 0; i < cookies.Count; i++)
                {
                    var cookie = cookies[i];
                    if (cookie.SameSite == SameSiteMode.None)
                    {
                        cookie.SameSite = (SameSiteMode)(-1); // Unspecified
                    }
                }
            });
        }
    }
}

È possibile modificare il comportamento specifico dei cookie denominati nello stesso modo; L'esempio seguente regola il cookie di autenticazione predefinito da Lax a None nei browser che supportano il None valore o rimuove lo stesso attributoSite nei browser che non supportano None.

public static void AdjustSpecificCookieSettings()
{
    HttpContext.Current.Response.AddOnSendingHeaders(context =>
    {
        var cookies = context.Response.Cookies;
        for (var i = 0; i < cookies.Count; i++)
        {
            var cookie = cookies[i]; 
            // Forms auth: ".ASPXAUTH"
            // Session: "ASP.NET_SessionId"
            if (string.Equals(".ASPXAUTH", cookie.Name, StringComparison.Ordinal))
            { 
                if (SameSite.BrowserDetection.DisallowsSameSiteNone(userAgent))
                {
                    cookie.SameSite = -1;
                }
                else
                {
                    cookie.SameSite = SameSiteMode.None;
                }
                cookie.Secure = true;
            }
        }
    });
}

Altre informazioni

Aggiornamenti chrome

Documentazione di OWIN SameSite

Documentazione di ASP.NET

Patch dello stesso sito .NET