Exemple cookie MVC SameSite ASP.NET Core 2.1

ASP.NET Core 2.1 prend en charge l’attribut SameSite, mais il a été écrit dans la norme d’origine. Le comportement corrigé a modifié la signification de SameSite.None pour émettre l’attribut SameSite avec la valeur None, plutôt que de n’émettre aucune valeur. Si vous ne souhaitez pas émettre la valeur, vous pouvez définir la propriété SameSite sur un cookie sur -1.

ASP.NET Core Identity n’est en grande partie pas affecté par les cookies SameSite, à l’exception des scénarios avancés tels que l’intégration IFrames ou OpenIdConnect.

Lorsque vous utilisez Identity, n’ajoutez pas de fournisseurs cookie et n’appelez pas services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme), Identity s’en charge.

Écriture de l’attribut SameSite

Le code suivant est un exemple d’écriture d’un attribut SameSite sur un 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 the SameSite property to (SameSiteMode)(-1).
    SameSite = SameSiteMode.None
};

// Add the cookie to the response cookie collection
Response.Cookies.Append(CookieName, "cookieValue", cookieOptions);

L’authentification Cookie, l’état de session et divers autres composants définissent leurs options de SameSite via des options deCookie, par exemple

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(options =>
    {
        options.Cookie.SameSite = SameSiteMode.None;
        options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
        options.Cookie.IsEssential = true;
    });

services.AddSession(options =>
{
    options.Cookie.SameSite = SameSiteMode.None;
    options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
    options.Cookie.IsEssential = true;
});

Dans le code précédent, l’authentification cookie et l’état de session définissent leur attribut SameSite sur None, en émettant l’attribut avec une valeur None, et définissent également l’attribut Secure sur true.

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 sur F12 puis sélectionnez l’onglet Application et cliquez sur l’URL du site sous l’option Cookies de la section Storage.

Browser Debugger Cookie List

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

Interception des cookies

Pour intercepter des cookies, afin d’ajuster la valeur aucune en fonction de sa prise en charge dans l’agent de navigateur de l’utilisateur, vous devez utiliser l’intergiciel CookiePolicy. Il doit être placé dans le pipeline de requête http avant tous les composants qui écrivent des cookies et configurés dans ConfigureServices().

Pour l’insérer dans le pipeline, utilisez app.UseCookiePolicy() dans la méthode Configure(IApplicationBuilder, IHostingEnvironment) du fichier Startup.cs. Par exemple :

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
       app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseCookiePolicy();
    app.UseAuthentication();
    app.UseSession();

    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });
}

Ensuite, dans ConfigureServices(IServiceCollection services), configurez la stratégie de cookie pour appeler une classe d’assistance quand des cookies sont ajoutés ou supprimés. Par exemple :

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<CookiePolicyOptions>(options =>
    {
        options.CheckConsentNeeded = context => true;
        options.MinimumSameSitePolicy = SameSiteMode.None;
        options.OnAppendCookie = cookieContext =>
            CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
        options.OnDeleteCookie = cookieContext =>
            CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
    });
}

private void CheckSameSite(HttpContext httpContext, CookieOptions options)
{
    if (options.SameSite == SameSiteMode.None)
    {
        var userAgent = httpContext.Request.Headers["User-Agent"].ToString();
        if (SameSite.BrowserDetection.DisallowsSameSiteNone(userAgent))
        {
            options.SameSite = (SameSiteMode)(-1);
        }
    }
}

La fonction d’assistance CheckSameSite(HttpContext, CookieOptions) :

  • Est appelé lorsque les cookies sont ajoutés à la requête ou supprimés de la requête.
  • Vérifie si la propriété SameSite est définie sur None.
  • Si SameSite est défini sur None et que l’agent utilisateur actuel est connu pour ne pas prendre en charge la valeur d’attribut aucune. La vérification est effectuée à l’aide de la classe SameSiteSupport :
    • Définit SameSite pour qu’il n’émette pas la valeur en définissant la propriété sur (SameSiteMode)(-1)

Cibler .NET Framework

ASP.NET Core et System.Web (ASP.NET 4.x) ont des implémentations indépendantes de SameSite. Les correctifs de la base de connaissances SameSite pour .NET Framework ne sont pas requis si vous utilisez ASP.NET Core et la version minimale requise de l’infrastructure SameSite System.Web (.NET Framework 4.7.2) ne s’applique pas non plus à ASP.NET Core.

ASP.NET Core sur .NET nécessite la mise à jour des dépendances de package NuGet afin d’obtenir les correctifs appropriés.

Pour obtenir les modifications ASP.NET Core pour .NET Framework, vérifiez que vous disposez d’une référence directe aux packages et versions corrigés (version 2.1.14 ou ultérieures à 2.1).

<PackageReference Include="Microsoft.Net.Http.Headers" Version="2.1.14" />
<PackageReference Include="Microsoft.AspNetCore.CookiePolicy" Version="2.1.14" />

Informations complémentaires

Mises à jour ChromeDocumentation ASP.NET Core SameSiteAnnonce de modification ASP.NET Core 2.1 SameSite