Lire en anglais

Partager via


Exemple de cookie SameSite pour ASP.NET 4.7.2 C# MVC

.NET Framework 4.7 prend en charge l’attribut SameSite , mais il respecte la norme d’origine. Le comportement corrigé a modifié la signification de SameSite.None pour émettre l’attribut avec une valeur de None, plutôt que de ne pas émettre la valeur du tout. Si vous ne souhaitez pas émettre la valeur, vous pouvez définir la SameSite propriété sur un cookie sur -1.

Écriture de l’attribut SameSite

Voici un exemple d’écriture d’un attribut SameSite sur 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);

Si vous lisez ceci dans une autre langue que l’anglais, faites-le nous savoir dans ce problème de discussion GitHub si vous souhaitez voir les commentaires de code dans votre langue maternelle.

L’attribut sameSite par défaut pour l’état de session est défini dans le paramètre « cookieSameSite » des paramètres de session dans web.config

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

Authentification MVC

L’authentification basée sur les cookies OWIN MVC utilise un gestionnaire de cookies pour permettre la modification des attributs des cookies. SameSiteCookieManager.cs est une implémentation d’une telle classe que vous pouvez copier dans vos propres projets.

Vous devez vous assurer que vos composants Microsoft.Owin sont tous mis à niveau vers la version 4.1.0 ou ultérieure. Vérifiez votre packages.config fichier pour vous assurer que tous les numéros de version correspondent, par exemple.

<?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>

Les composants d’authentification doivent ensuite être configurés pour utiliser CookieManager dans votre classe de démarrage ;

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

Un gestionnaire de cookies doit être défini sur chaque composant qui le prend en charge, notamment CookieAuthentication et OpenIdConnectAuthentication.

SystemWebCookieManager est utilisé pour éviter les problèmes connus liés à l’intégration des cookies de réponse.

Exécution de l’exemple

Si vous exécutez l’exemple de projet, chargez votre débogueur de navigateur sur la page initiale et utilisez-le pour afficher la collection de cookies du site. Pour ce faire, dans Edge et Chrome, appuyez F12 sur l’onglet Application , puis cliquez sur l’URL du site sous l’option Cookies de la Storage section.

Liste des cookies du débogueur de navigateur

Vous pouvez voir dans l’image ci-dessus que le cookie créé par l’exemple lorsque vous cliquez sur le bouton « Créer des cookies » a une valeur d’attribut SameSite de Lax, correspondant à la valeur définie dans l’exemple de code.

Intercepter les cookies que vous ne contrôlez pas

.NET 4.5.2 a introduit un nouvel événement pour intercepter l’écriture d’en-têtes, Response.AddOnSendingHeaders. Cela peut être utilisé pour intercepter les cookies avant qu’ils ne soient retournés à l’ordinateur client. Dans l’exemple, nous filons l’événement vers une méthode statique qui vérifie si le navigateur prend en charge les nouvelles modifications sameSite et, si ce n’est pas le cas, modifie les cookies pour ne pas émettre l’attribut si la nouvelle None valeur a été définie.

Consultez global.asax pour obtenir un exemple de branchement de l’événement et SameSiteCookieRewriter.cs pour obtenir un exemple de gestion de l’événement et d’ajustement de l’attribut de cookie sameSite que vous pouvez copier dans votre propre code.

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
                    }
                }
            });
        }
    }
}

Vous pouvez modifier le comportement des cookies nommés spécifiques de la même manière ; l’exemple ci-dessous ajuste le cookie d’authentification par défaut de Lax à None sur les navigateurs qui prennent en charge la None valeur, ou supprime l’attribut sameSite sur les navigateurs qui ne prennent pas en charge 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;
            }
        }
    });
}

Informations complémentaires

Chrome Mises à jour

OWIN SameSite Documentation

Documentation ASP.NET

Correctifs SameSite .NET