Ejemplo cookie de SameSite de MVC de ASP.NET Core 2.1

ASP.NET Core 2.1 tiene compatibilidad integrada con el atributo SameSite, pero se escribió en el estándar original. El comportamiento revisado cambió el significado de SameSite.None para emitir el atributo sameSite con un valor de None, en lugar de no emitir el valor en absoluto. Si no desea emitir el valor, puede establecer la propiedad SameSite en una cookie a -1.

ASP.NET Core Identity no se ve afectado en gran medida por las cookies de SameSite excepto en escenarios avanzados como la integración de IFrames o OpenIdConnect.

Al usar Identity, no agregue ningún proveedor de cookie o llame a services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme), Identity se encarga de ello.

Escritura del atributo SameSite

A continuación se muestra un ejemplo de cómo escribir un atributo SameSite en 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);

Autenticación de Cookie, estado de sesión y otros componentes establecen sus opciones de sameSite a través de opciones de Cookie, por ejemplo

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

En el código anterior, tanto la autenticación de cookie como el estado de sesión establecen su atributo de sameSite en None, emiten el atributo con un valor None y también establecen el atributo Secure en true.

Ejecución del ejemplo

Si ejecuta el proyecto de ejemplo, cargue el depurador del explorador en la página inicial y úselo para ver la colección de cookie del sitio. Para ello, en Edge y Chrome, presione F12, seleccione la pestaña Application y haga clic en la dirección URL del sitio en la opción Cookies de la sección Storage.

Depurador de explorador Cookie Lista

Puede ver en la imagen anterior que la cookie creada por el ejemplo al hacer clic en el botón "Crear Cookie de SameSite" tiene un valor de atributo SameSite de Lax, que coincide con el valor establecido en el código de ejemplo.

Interceptación de cookies

Para interceptar cookies y ajustar el valor none según su compatibilidad con el agente del explorador del usuario, debes usar el middleware CookiePolicy. Debe colocarse en la canalización de solicitudes http antes de los componentes que escriben cookies y se configuran dentro de ConfigureServices().

Para insertarlo en la canalización, use app.UseCookiePolicy() en el método Configure(IApplicationBuilder, IHostingEnvironment) de Startup.cs. Por ejemplo:

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

A continuación, en ConfigureServices(IServiceCollection services) configura la directiva de cookie para llamar a una clase auxiliar cuando se anexan o eliminan cookies. Por ejemplo:

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 función auxiliar CheckSameSite(HttpContext, CookieOptions):

  • Se llama cuando se anexan cookies a la solicitud o se eliminan de la solicitud.
  • Comprueba si la propiedad SameSite está establecida en None.
  • Si SameSite se establece en None y se sabe que el agente de usuario actual no admite el valor de atributo none. La comprobación se realiza mediante la clase SameSiteSupport:
    • Establece SameSite para no emitir el valor estableciendo la propiedad en (SameSiteMode)(-1)

Destino de .NET Framework

ASP.NET Core y System.Web (ASP.NET 4.x) tienen implementaciones independientes de SameSite. Las revisiones de KB de SameSite para .NET Framework no son necesarias si se usa ASP.NET Core ni se aplica el requisito de versión mínima del marco System.Web SameSite (.NET Framework 4.7.2) a ASP.NET Core.

ASP.NET Core en .NET requiere actualizar las dependencias del paquete NuGet para obtener las correcciones adecuadas.

Para obtener los cambios de ASP.NET Core para .NET Framework, asegúrese de que tiene una referencia directa a los paquetes y versiones revisados (2.1.14 o versiones posteriores de 2.1).

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

Más información

Actualizaciones de Chrome UpdatesDocumentación de SameSite de ASP.NET CoreAnuncio de cambios en SameSite de ASP.NET Core 2.1