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 , None
anziché generare il valore. Se si desidera non generare il valore, è possibile impostare la SameSite
proprietà su un cookie su -1.
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>
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.
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.
È 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 Lax
a , che corrisponde al valore impostato nel codice di esempio.
.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;
}
}
});
}