Delen via


Werken met SameSite-cookies in ASP.NET Core

Door Rick Anderson

SameSite is een IETF-conceptstandaard die is ontworpen om enige bescherming te bieden tegen csrF-aanvallen (cross-site request forgery). Oorspronkelijk opgesteld in 2016 werd de ontwerpstandaard in 2019 bijgewerkt. De bijgewerkte standaard is niet achterwaarts compatibel met de vorige standaard, waarbij het volgende de meest merkbare verschillen zijn:

  • Cookies zonder SameSite-header worden standaard behandeld SameSite=Lax .
  • SameSite=None moet worden gebruikt om gebruik tussen sites cookie toe te staan.
  • Cookies die SameSite=None claimen, moeten ook als Secure worden gemarkeerd.
  • Toepassingen die gebruikmaken van <iframe> kunnen problemen ondervinden met sameSite=Lax- of sameSite=Strict-cookies, omdat <iframe> wordt behandeld als scenario's voor meerdere sites.
  • De waarde SameSite=None is niet toegestaan volgens de standaard 2016 en zorgt ervoor dat sommige implementaties dergelijke cookies behandelen, zoals SameSite=Strict. Zie Ondersteuning van oudere browsers in dit document.

De SameSite=Lax instelling werkt voor de meeste toepassingscookies. Sommige vormen van verificatie, zoals OpenID Connect (OIDC) en WS-Federation , worden standaard ingesteld op POST-gebaseerde omleidingen. De op POST gebaseerde omleidingen activeren de beveiliging van de SameSite-browser, dus SameSite is uitgeschakeld voor deze onderdelen. De meeste OAuth-aanmeldingen worden niet beïnvloed vanwege verschillen in de manier waarop de aanvraag stroomt.

Elk ASP.NET Core-onderdeel dat cookies verzendt, moet beslissen of SameSite geschikt is.

SameSite en Identity

ASP.NET Core Identity wordt grotendeels niet beïnvloed door SameSite-cookies , met uitzondering van geavanceerde scenario's zoals IFrames of OpenIdConnect integratie.

Wanneer u Identity gebruikt, voeg geen providers toe of maak geen oproepen naar , cookie regelt dat.

SameSite-testvoorbeeldcode

Het volgende voorbeeld kan worden gedownload en getest:

Sample Document
Razor pagina's voorbeeld van ASP.NET Core 3.1 Razor Pages SameSite cookie

.NET-ondersteuning voor hetzelfde sitekenmerk

.NET ondersteunt de conceptstandaard 2019 voor SameSite. Ontwikkelaars kunnen programmatisch de waarde van hetzelfde Site-kenmerk beheren met behulp van de HttpCookie.SameSite eigenschap. Wanneer u de SameSite eigenschap instelt op Strict, Lax, of None, resulteert dat erin dat deze waarden op het netwerk worden geschreven met de cookie. Instellen op SameSiteMode.Unspecified geeft aan dat er geen sameSite moet worden verzonden met de 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.
        SameSite = SameSiteMode.None

        // The client should follow its default cookie policy.
        // SameSite = SameSiteMode.Unspecified
    };

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

API-gebruik met SameSite

HttpContext.Response.Cookies.Append is Unspecifiedstandaard ingesteld op, wat betekent dat er geen SameSite-kenmerk wordt toegevoegd aan de cookie site en dat de client het standaardgedrag gebruikt (Lax voor nieuwe browsers, Geen voor oude). De volgende code laat zien hoe u de cookie SameSite-waarde wijzigt in SameSiteMode.Lax:

HttpContext.Response.Cookies.Append(
                     "name", "value",
                     new CookieOptions() { SameSite = SameSiteMode.Lax });

Alle ASP.NET Kernonderdelen die cookies verzenden, overschrijven de voorgaande standaardwaarden met instellingen die geschikt zijn voor hun scenario's. De overschreven voorgaande standaardwaarden zijn niet gewijzigd.

Component cookie Default
CookieBuilder SameSite Unspecified
Session SessionOptions.Cookie Lax
CookieTempDataProvider CookieTempDataProviderOptions.Cookie Lax
IAntiforgery AntiforgeryOptions.Cookie Strict
Cookie Authenticatie CookieAuthenticationOptions.Cookie Lax
AddTwitter TwitterOptions.StateCookie Lax
RemoteAuthenticationHandler<TOptions> RemoteAuthenticationOptions.CorrelationCookie None
AddOpenIdConnect OpenIdConnectOptions.NonceCookie None
HttpContext.Response.Cookies.Append CookieOptions Unspecified

ASP.NET Core 3.1 of hoger biedt de volgende Ondersteuning voor SameSite:

  • Herdefinieert het gedrag van SameSiteMode.None om SameSite=None uit te zenden
  • Voegt een nieuwe waarde SameSiteMode.Unspecified toe om het kenmerk SameSite weg te laten.
  • Alle cookies-API's zijn standaard ingesteld op Unspecified. Sommige onderdelen die cookies gebruiken, stellen waarden specifieker in voor hun scenario's. Zie de bovenstaande tabel voor voorbeelden.

In ASP.NET Core 3.0 of hoger zijn de standaardinstellingen van SameSite gewijzigd om conflicteren met inconsistente clientstandaarden te voorkomen. De volgende API's hebben de standaardinstelling gewijzigd van SameSiteMode.Lax naar -1 om te voorkomen dat er een SameSite-kenmerk voor deze cookies wordt verzonden:

Geschiedenis en wijzigingen

SameSite-ondersteuning is voor het eerst geïmplementeerd in ASP.NET Core in 2.0 met behulp van de conceptstandaard 2016. De standaard van 2016 was opt-in. ASP.NET Core heeft ervoor gekozen door standaard verschillende cookies op Lax in te stellen. Nadat er verschillende problemen met verificatie zijn optreedt, is het meeste SameSite-gebruik uitgeschakeld.

Patches zijn uitgegeven in november 2019 om bij te werken van de standaard 2016 naar de standaard 2019. Het 2019-concept van de SameSite-specificatie:

  • Is niet achterwaarts compatibel met de conceptversie van 2016. Zie Ondersteunende oudere browsers in dit document voor meer informatie.
  • Cookies worden standaard behandeld als SameSite=Lax.
  • Geeft de cookies aan die expliciet SameSite=None aangeven om cross-site levering in te schakelen en moeten worden gemarkeerd als Secure. None is een nieuwe vermelding om u af te melden.
  • Wordt ondersteund door patches die zijn uitgegeven voor ASP.NET Core 2.1, 2.2 en 3.0. ASP.NET Core 3.1 of hoger heeft extra Ondersteuning voor SameSite.
  • Is standaard ingeschakeld door Chrome in februari 2020. Browsers zijn in 2019 overgegaan naar deze standaard.

API's die worden beïnvloed door de wijziging van de conceptstandaard 2016 SameSite naar de conceptstandaard 2019

Oudere browsers ondersteunen

De SameSite-standaard van 2016 heeft tot gevolg dat onbekende waarden moeten worden behandeld als SameSite=Strict waarden. Apps die worden geopend vanuit oudere browsers die de SameSite-standaard van 2016 ondersteunen, kunnen niet goed functioneren wanneer ze een SameSite-eigenschap met een waarde van None ontvangen. Web-apps moeten browserdetectie implementeren als ze oudere browsers willen ondersteunen. ASP.NET Core implementeert geen browserdetectie omdat User-Agents waarden zeer vluchtig zijn en regelmatig worden gewijzigd. Met een uitbreidingspunt in Microsoft.AspNetCore.CookiePolicy wordt het mogelijk om User-Agent specifieke logica aan te sluiten.

Voeg in Program.cs code toe die UseCookiePolicy aanroept voordat UseAuthentication of een methode die cookies schrijft wordt aangeroepen.

var builder = WebApplication.CreateBuilder(args);

builder.Services.Configure<CookiePolicyOptions>(options =>
{
    options.MinimumSameSitePolicy = SameSiteMode.Unspecified;
    options.OnAppendCookie = cookieContext =>
        CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
    options.OnDeleteCookie = cookieContext =>
        CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
});

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

    builder.Services.AddRazorPages();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseCookiePolicy();
app.UseAuthorization();

app.MapRazorPages();

app.Run();

Voeg Program.cscode toe die vergelijkbaar is met de volgende gemarkeerde code:

var builder = WebApplication.CreateBuilder(args);

builder.Services.Configure<CookiePolicyOptions>(options =>
{
    options.MinimumSameSitePolicy = SameSiteMode.Unspecified;
    options.OnAppendCookie = cookieContext =>
        CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
    options.OnDeleteCookie = cookieContext =>
        CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
});

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

    builder.Services.AddRazorPages();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseCookiePolicy();
app.UseAuthorization();

app.MapRazorPages();

app.Run();

In het voorgaande voorbeeld MyUserAgentDetectionLib.DisallowsSameSiteNone is een door de gebruiker opgegeven bibliotheek die detecteert of de gebruikersagent geen ondersteuning biedt voor SameSite None:

if (MyUserAgentDetectionLib.DisallowsSameSiteNone(userAgent))
{
    options.SameSite = SameSiteMode.Unspecified;
}

De volgende code toont een voorbeeldmethode DisallowsSameSiteNone :

Warning

De volgende code is alleen bedoeld voor demonstratie:

  • Deze mag niet als volledig worden beschouwd.
  • Het wordt niet onderhouden of ondersteund.
public static bool DisallowsSameSiteNone(string userAgent)
{
    // Check if a null or empty string has been passed in, since this
    // will cause further interrogation of the useragent to fail.
     if (String.IsNullOrWhiteSpace(userAgent))
        return false;
    
    // Cover all iOS based browsers here. This includes:
    // - Safari on iOS 12 for iPhone, iPod Touch, iPad
    // - WkWebview on iOS 12 for iPhone, iPod Touch, iPad
    // - Chrome on iOS 12 for iPhone, iPod Touch, iPad
    // All of which are broken by SameSite=None, because they use the iOS networking
    // stack.
    if (userAgent.Contains("CPU iPhone OS 12") ||
        userAgent.Contains("iPad; CPU OS 12"))
    {
        return true;
    }

    // Cover Mac OS X based browsers that use the Mac OS networking stack. 
    // This includes:
    // - Safari on Mac OS X.
    // This does not include:
    // - Chrome on Mac OS X
    // Because they do not use the Mac OS networking stack.
    if (userAgent.Contains("Macintosh; Intel Mac OS X 10_14") &&
        userAgent.Contains("Version/") && userAgent.Contains("Safari"))
    {
        return true;
    }

    // Cover Chrome 50-69, because some versions are broken by SameSite=None, 
    // and none in this range require it.
    // Note: this covers some pre-Chromium Edge versions, 
    // but pre-Chromium Edge does not require SameSite=None.
    if (userAgent.Contains("Chrome/5") || userAgent.Contains("Chrome/6"))
    {
        return true;
    }

    return false;
}

Apps testen voor Problemen met SameSite

Apps die communiceren met externe sites, zoals via aanmelding van derden, moeten:

Test web-apps met behulp van een clientversie die zich kan aanmelden voor het nieuwe SameSite-gedrag. Chrome, Firefox en Chromium Edge hebben allemaal nieuwe opt-in functievlagmen die kunnen worden gebruikt voor het testen. Nadat uw app de SameSite-patches heeft toegepast, test u deze met oudere clientversies, met name Safari. Zie Ondersteunende oudere browsers in dit document voor meer informatie.

Testen met Chrome

Chrome 78+ geeft misleidende resultaten omdat er een tijdelijke mitigatie is. De Chrome 78+ tijdelijke beperking staat cookies toe die minder dan twee minuten oud zijn. Chrome 76 of 77 met de juiste testvlagmen ingeschakeld biedt nauwkeurigere resultaten. Om het nieuwe SameSite-gedrag te testen, schakelt u chrome://flags/#same-site-by-default-cookies naar Ingeschakeld. Er wordt gerapporteerd dat oudere versies van Chrome (75 en lager) falen met de nieuwe None instelling. Zie Ondersteuning van oudere browsers in dit document.

Google maakt geen oudere chrome-versies beschikbaar. Volg de instructies bij Chromium downloaden om oudere versies van Chrome te testen. Download Chrome niet via koppelingen die worden aangeboden door te zoeken naar oudere versies van Chrome.

Vanaf de Canary-versie 80.0.3975.0kan de tijdelijke Beperking van Lax+POST worden uitgeschakeld voor testdoeleinden met behulp van de nieuwe vlag --enable-features=SameSiteDefaultChecksMethodRigorously om het testen van sites en services in de uiteindelijke eindstatus van de functie waar de beperking is verwijderd, toe te staan. Zie The Chromium Projects SameSite Updates voor meer informatie

Testen met Safari

Safari 12 heeft het vorige concept strikt geïmplementeerd en mislukt wanneer de nieuwe None waarde zich in een cookiebevindt. None wordt vermeden via de browserdetectiecode die oudere browsers in dit document ondersteunt. Test Safari 12, Safari 13 en WebKit-gebaseerde aanmeldingen in OS-stijl met behulp van MSAL, ADAL of welke bibliotheek u ook gebruikt. Het probleem is afhankelijk van de onderliggende versie van het besturingssysteem. OSX Mojave (10.14) en iOS 12 zijn bekend dat er compatibiliteitsproblemen zijn met het nieuwe SameSite-gedrag. Als u het besturingssysteem bijwerkt naar OSX Catalina (10.15) of iOS 13, wordt het probleem opgelost. Safari heeft momenteel geen opt-in-vlag voor het testen van het nieuwe spec-gedrag.

Testen met Firefox

Firefox-ondersteuning voor de nieuwe standaard kan worden getest op versie 68+ door op de about:config pagina te kiezen met de functievlag network.cookie.sameSite.laxByDefault. Er zijn geen rapporten over compatibiliteitsproblemen met oudere versies van Firefox.

Testen met Edge-browser

Edge ondersteunt de oude SameSite-standaard. Edge-versie 44 heeft geen bekende compatibiliteitsproblemen met de nieuwe standaard.

Testen met Edge (Chromium)

SameSite-vlaggen worden ingesteld op de edge://flags/#same-site-by-default-cookies pagina. Er zijn geen compatibiliteitsproblemen gedetecteerd met Edge Chromium.

Testen met Electron

Versies van Electron zijn onder andere oudere versies van Chromium. De versie van Electron die door Teams wordt gebruikt, is bijvoorbeeld Chromium 66, dat het oudere gedrag vertoont. U moet uw eigen compatibiliteitstests uitvoeren met de versie die Electron door uw product wordt gebruikt. Zie Ondersteunende oudere browsers in de volgende sectie.

Aanvullende bronnen

Sample Document
Razor pagina's voorbeeld van ASP.NET Core 3.1 Razor Pages SameSite cookie

Het volgende voorbeeld kan worden gedownload en getest:

Sample Document
Razor pagina's voorbeeld van ASP.NET Core 3.1 Razor Pages SameSite cookie

.NET Core-ondersteuning voor hetzelfde sitekenmerk

.NET Core 3.1 of hoger ondersteunt de conceptstandaard 2019 voor SameSite. Ontwikkelaars kunnen programmatisch de waarde van hetzelfde Site-kenmerk beheren met behulp van de HttpCookie.SameSite eigenschap. Als u de SameSite eigenschap instelt op Strikt, Lax of Geen, resulteert dit in de waarden die in het netwerk worden geschreven met de cookie. Het instellen van de waarde als (SameSiteMode)(-1) resulteert erin dat er geen sameSite-kenmerk wordt opgenomen bij het netwerkverkeer met de 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
    // SameSite = (SameSiteMode)(-1)
    SameSite = SameSiteMode.None
};

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

.NET Core 3.1 of hoger ondersteunt de bijgewerkte SameSite-waarden en voegt een extra opsommingswaarde SameSiteMode.Unspecified toe aan de SameSiteMode enum. Deze nieuwe waarde geeft aan dat het sameSite-attribuut niet moet worden verzonden met de cookie.

API-gebruik met SameSite

HttpContext.Response.Cookies.Append is Unspecifiedstandaard ingesteld op, wat betekent dat er geen SameSite-kenmerk wordt toegevoegd aan de cookie site en dat de client het standaardgedrag gebruikt (Lax voor nieuwe browsers, Geen voor oude). De volgende code laat zien hoe u de cookie SameSite-waarde wijzigt in SameSiteMode.Lax:

HttpContext.Response.Cookies.Append(
                     "name", "value",
                     new CookieOptions() { SameSite = SameSiteMode.Lax });

Alle ASP.NET Kernonderdelen die cookies verzenden, overschrijven de voorgaande standaardwaarden met instellingen die geschikt zijn voor hun scenario's. De overschreven voorgaande standaardwaarden zijn niet gewijzigd.

Component cookie Default
CookieBuilder SameSite Unspecified
Session SessionOptions.Cookie Lax
CookieTempDataProvider CookieTempDataProviderOptions.Cookie Lax
IAntiforgery AntiforgeryOptions.Cookie Strict
Cookie Authenticatie CookieAuthenticationOptions.Cookie Lax
AddTwitter TwitterOptions.StateCookie Lax
RemoteAuthenticationHandler<TOptions> RemoteAuthenticationOptions.CorrelationCookie None
AddOpenIdConnect OpenIdConnectOptions.NonceCookie None
HttpContext.Response.Cookies.Append CookieOptions Unspecified

ASP.NET Core 3.1 of hoger biedt de volgende Ondersteuning voor SameSite:

  • Herdefinieert het gedrag van SameSiteMode.None om SameSite=None uit te zenden
  • Voegt een nieuwe waarde SameSiteMode.Unspecified toe om het kenmerk SameSite weg te laten.
  • Alle cookies-API's zijn standaard ingesteld op Unspecified. Sommige onderdelen die cookies gebruiken, stellen waarden specifieker in voor hun scenario's. Zie de bovenstaande tabel voor voorbeelden.

In ASP.NET Core 3.0 of hoger zijn de standaardinstellingen van SameSite gewijzigd om conflicteren met inconsistente clientstandaarden te voorkomen. De volgende API's hebben de standaardinstelling gewijzigd van SameSiteMode.Lax naar -1 om te voorkomen dat er een SameSite-kenmerk voor deze cookies wordt verzonden:

Geschiedenis en wijzigingen

SameSite-ondersteuning is voor het eerst geïmplementeerd in ASP.NET Core in 2.0 met behulp van de conceptstandaard 2016. De standaard van 2016 was opt-in. ASP.NET Core heeft ervoor gekozen door standaard verschillende cookies op Lax in te stellen. Nadat er verschillende problemen met verificatie zijn optreedt, is het meeste SameSite-gebruik uitgeschakeld.

Patches zijn uitgegeven in november 2019 om bij te werken van de standaard 2016 naar de standaard 2019. Het 2019-concept van de SameSite-specificatie:

  • Is niet achterwaarts compatibel met de conceptversie van 2016. Zie Ondersteunende oudere browsers in dit document voor meer informatie.
  • Cookies worden standaard behandeld als SameSite=Lax.
  • Geeft de cookies aan die expliciet SameSite=None aangeven om cross-site levering in te schakelen en moeten worden gemarkeerd als Secure. None is een nieuwe vermelding om u af te melden.
  • Wordt ondersteund door patches die zijn uitgegeven voor ASP.NET Core 2.1, 2.2 en 3.0. ASP.NET Core 3.1 biedt extra Ondersteuning voor SameSite.
  • Is standaard ingeschakeld door Chrome in februari 2020. Browsers zijn in 2019 overgegaan naar deze standaard.

API's die worden beïnvloed door de wijziging van de conceptstandaard 2016 SameSite naar de conceptstandaard 2019

Oudere browsers ondersteunen

De SameSite-standaard van 2016 heeft tot gevolg dat onbekende waarden moeten worden behandeld als SameSite=Strict waarden. Apps die worden geopend vanuit oudere browsers die de SameSite-standaard van 2016 ondersteunen, kunnen niet goed functioneren wanneer ze een SameSite-eigenschap met een waarde van None ontvangen. Web-apps moeten browserdetectie implementeren als ze oudere browsers willen ondersteunen. ASP.NET Core implementeert geen browserdetectie omdat User-Agents waarden zeer vluchtig zijn en regelmatig worden gewijzigd. Met een uitbreidingspunt in Microsoft.AspNetCore.CookiePolicy wordt het mogelijk om User-Agent specifieke logica aan te sluiten.

Voeg in Startup.Configure code toe die UseCookiePolicy aanroept voordat UseAuthentication of een methode die cookies schrijft wordt aangeroepen.

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

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseCookiePolicy();
    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

Voeg Startup.ConfigureServicescode toe die vergelijkbaar is met de volgende:

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

    services.AddRazorPages();
}

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

In het voorgaande voorbeeld MyUserAgentDetectionLib.DisallowsSameSiteNone is een door de gebruiker opgegeven bibliotheek die detecteert of de gebruikersagent geen ondersteuning biedt voor SameSite None:

if (MyUserAgentDetectionLib.DisallowsSameSiteNone(userAgent))
{
    options.SameSite = SameSiteMode.Unspecified;
}

De volgende code toont een voorbeeldmethode DisallowsSameSiteNone :

Warning

De volgende code is alleen bedoeld voor demonstratie:

  • Deze mag niet als volledig worden beschouwd.
  • Het wordt niet onderhouden of ondersteund.
public static bool DisallowsSameSiteNone(string userAgent)
{
    // Check if a null or empty string has been passed in, since this
    // will cause further interrogation of the useragent to fail.
     if (String.IsNullOrWhiteSpace(userAgent))
        return false;
    
    // Cover all iOS based browsers here. This includes:
    // - Safari on iOS 12 for iPhone, iPod Touch, iPad
    // - WkWebview on iOS 12 for iPhone, iPod Touch, iPad
    // - Chrome on iOS 12 for iPhone, iPod Touch, iPad
    // All of which are broken by SameSite=None, because they use the iOS networking
    // stack.
    if (userAgent.Contains("CPU iPhone OS 12") ||
        userAgent.Contains("iPad; CPU OS 12"))
    {
        return true;
    }

    // Cover Mac OS X based browsers that use the Mac OS networking stack. 
    // This includes:
    // - Safari on Mac OS X.
    // This does not include:
    // - Chrome on Mac OS X
    // Because they do not use the Mac OS networking stack.
    if (userAgent.Contains("Macintosh; Intel Mac OS X 10_14") &&
        userAgent.Contains("Version/") && userAgent.Contains("Safari"))
    {
        return true;
    }

    // Cover Chrome 50-69, because some versions are broken by SameSite=None, 
    // and none in this range require it.
    // Note: this covers some pre-Chromium Edge versions, 
    // but pre-Chromium Edge does not require SameSite=None.
    if (userAgent.Contains("Chrome/5") || userAgent.Contains("Chrome/6"))
    {
        return true;
    }

    return false;
}

Apps testen voor Problemen met SameSite

Apps die communiceren met externe sites, zoals via aanmelding van derden, moeten:

Test web-apps met behulp van een clientversie die zich kan aanmelden voor het nieuwe SameSite-gedrag. Chrome, Firefox en Chromium Edge hebben allemaal nieuwe opt-in functievlagmen die kunnen worden gebruikt voor het testen. Nadat uw app de SameSite-patches heeft toegepast, test u deze met oudere clientversies, met name Safari. Zie Ondersteunende oudere browsers in dit document voor meer informatie.

Testen met Chrome

Chrome 78+ geeft misleidende resultaten omdat er een tijdelijke mitigatie is. De Chrome 78+ tijdelijke beperking staat cookies toe die minder dan twee minuten oud zijn. Chrome 76 of 77 met de juiste testvlagmen ingeschakeld biedt nauwkeurigere resultaten. Om het nieuwe SameSite-gedrag te testen, schakelt u chrome://flags/#same-site-by-default-cookies naar Ingeschakeld. Er wordt gerapporteerd dat oudere versies van Chrome (75 en lager) falen met de nieuwe None instelling. Zie Ondersteuning van oudere browsers in dit document.

Google maakt geen oudere chrome-versies beschikbaar. Volg de instructies bij Chromium downloaden om oudere versies van Chrome te testen. Download Chrome niet via koppelingen die worden aangeboden door te zoeken naar oudere versies van Chrome.

Vanaf de Canary-versie 80.0.3975.0kan de tijdelijke Beperking van Lax+POST worden uitgeschakeld voor testdoeleinden met behulp van de nieuwe vlag --enable-features=SameSiteDefaultChecksMethodRigorously om het testen van sites en services in de uiteindelijke eindstatus van de functie waar de beperking is verwijderd, toe te staan. Zie The Chromium Projects SameSite Updates voor meer informatie

Testen met Safari

Safari 12 heeft het vorige concept strikt geïmplementeerd en mislukt wanneer de nieuwe None waarde zich in een cookiebevindt. None wordt vermeden via de browserdetectiecode die oudere browsers in dit document ondersteunt. Test Safari 12, Safari 13 en WebKit-gebaseerde aanmeldingen in OS-stijl met behulp van MSAL, ADAL of welke bibliotheek u ook gebruikt. Het probleem is afhankelijk van de onderliggende versie van het besturingssysteem. OSX Mojave (10.14) en iOS 12 zijn bekend dat er compatibiliteitsproblemen zijn met het nieuwe SameSite-gedrag. Als u het besturingssysteem bijwerkt naar OSX Catalina (10.15) of iOS 13, wordt het probleem opgelost. Safari heeft momenteel geen opt-in-vlag voor het testen van het nieuwe spec-gedrag.

Testen met Firefox

Firefox-ondersteuning voor de nieuwe standaard kan worden getest op versie 68+ door op de about:config pagina te kiezen met de functievlag network.cookie.sameSite.laxByDefault. Er zijn geen rapporten over compatibiliteitsproblemen met oudere versies van Firefox.

Testen met Edge-browser

Edge ondersteunt de oude SameSite-standaard. Edge-versie 44 heeft geen bekende compatibiliteitsproblemen met de nieuwe standaard.

Testen met Edge (Chromium)

SameSite-vlaggen worden ingesteld op de edge://flags/#same-site-by-default-cookies pagina. Er zijn geen compatibiliteitsproblemen gedetecteerd met Edge Chromium.

Testen met Electron

Versies van Electron zijn onder andere oudere versies van Chromium. De versie van Electron die door Teams wordt gebruikt, is bijvoorbeeld Chromium 66, dat het oudere gedrag vertoont. U moet uw eigen compatibiliteitstests uitvoeren met de versie die Electron door uw product wordt gebruikt. Zie Ondersteunende oudere browsers in de volgende sectie.

Aanvullende bronnen

Sample Document
Razor pagina's voorbeeld van ASP.NET Core 3.1 Razor Pages SameSite cookie

De volgende voorbeelden kunnen worden gedownload en getest:

Sample Document
MVC ASP.NET Core 2.1 MVC SameSite-voorbeeld cookie
Razor pagina's voorbeeld van ASP.NET Core 2.1 Razor Pages SameSite cookie

Wijzigingen in gedrag van decemberpatch

De specifieke gedragswijziging voor .NET Framework en .NET Core 2.1 is hoe de eigenschap de SameSiteNone waarde interpreteert. Voordat de patch betekende een waarde van None 'Verzend het kenmerk helemaal niet', na de patch betekent het 'Verzend het kenmerk met een waarde van None'. Na de patch zorgt een SameSite-waarde van (SameSiteMode)(-1) ervoor dat het kenmerk niet wordt verzonden.

De standaardwaarde samesite voor formulierverificatie en sessiestatuscookies is gewijzigd van None in Lax.

API-gebruik met SameSite

HttpContext.Response.Cookies.Append is Unspecifiedstandaard ingesteld op, wat betekent dat er geen SameSite-kenmerk wordt toegevoegd aan de cookie site en dat de client het standaardgedrag gebruikt (Lax voor nieuwe browsers, Geen voor oude). De volgende code laat zien hoe u de cookie SameSite-waarde wijzigt in SameSiteMode.Lax:

HttpContext.Response.Cookies.Append(
                     "name", "value",
                     new CookieOptions() { SameSite = SameSiteMode.Lax });

Alle ASP.NET Kernonderdelen die cookies verzenden, overschrijven de voorgaande standaardwaarden met instellingen die geschikt zijn voor hun scenario's. De overschreven voorgaande standaardwaarden zijn niet gewijzigd.

Component cookie Default
CookieBuilder SameSite Unspecified
Session SessionOptions.Cookie Lax
CookieTempDataProvider CookieTempDataProviderOptions.Cookie Lax
IAntiforgery AntiforgeryOptions.Cookie Strict
Cookie Authenticatie CookieAuthenticationOptions.Cookie Lax
AddTwitter TwitterOptions.StateCookie Lax
RemoteAuthenticationHandler<TOptions> RemoteAuthenticationOptions.CorrelationCookie None
AddOpenIdConnect OpenIdConnectOptions.NonceCookie None
HttpContext.Response.Cookies.Append CookieOptions Unspecified

Geschiedenis en wijzigingen

SameSite-ondersteuning is voor het eerst geïmplementeerd in ASP.NET Core in 2.0 met behulp van de conceptstandaard 2016. De standaard van 2016 was opt-in. ASP.NET Core heeft ervoor gekozen door standaard verschillende cookies op Lax in te stellen. Nadat er verschillende problemen met verificatie zijn optreedt, is het meeste SameSite-gebruik uitgeschakeld.

Patches zijn uitgegeven in november 2019 om bij te werken van de standaard 2016 naar de standaard 2019. Het 2019-concept van de SameSite-specificatie:

  • Is niet achterwaarts compatibel met de conceptversie van 2016. Zie Ondersteunende oudere browsers in dit document voor meer informatie.
  • Cookies worden standaard behandeld als SameSite=Lax.
  • Geeft de cookies aan die expliciet SameSite=None aangeven om cross-site levering in te schakelen en moeten worden gemarkeerd als Secure. None is een nieuwe vermelding om u af te melden.
  • Wordt ondersteund door patches die zijn uitgegeven voor ASP.NET Core 2.1, 2.2 en 3.0. ASP.NET Core 3.1 biedt extra Ondersteuning voor SameSite.
  • Is standaard ingeschakeld door Chrome in februari 2020. Browsers zijn in 2019 overgegaan naar deze standaard.

API's die worden beïnvloed door de wijziging van de conceptstandaard 2016 SameSite naar de conceptstandaard 2019

Oudere browsers ondersteunen

De SameSite-standaard van 2016 heeft tot gevolg dat onbekende waarden moeten worden behandeld als SameSite=Strict waarden. Apps die worden geopend vanuit oudere browsers die de SameSite-standaard van 2016 ondersteunen, kunnen niet goed functioneren wanneer ze een SameSite-eigenschap met een waarde van None ontvangen. Web-apps moeten browserdetectie implementeren als ze oudere browsers willen ondersteunen. ASP.NET Core implementeert geen browserdetectie omdat User-Agents waarden zeer vluchtig zijn en regelmatig worden gewijzigd. Met een uitbreidingspunt in Microsoft.AspNetCore.CookiePolicy wordt het mogelijk om User-Agent specifieke logica aan te sluiten.

Voeg in Startup.Configure code toe die UseCookiePolicy aanroept voordat UseAuthentication of een methode die cookies schrijft wordt aangeroepen.

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

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseCookiePolicy();
    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

Voeg Startup.ConfigureServicescode toe die vergelijkbaar is met de volgende:

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

    services.AddRazorPages();
}

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

    }
}

In het voorgaande voorbeeld MyUserAgentDetectionLib.DisallowsSameSiteNone is een door de gebruiker opgegeven bibliotheek die detecteert of de gebruikersagent geen ondersteuning biedt voor SameSite None:

if (MyUserAgentDetectionLib.DisallowsSameSiteNone(userAgent))
{
    options.SameSite = SameSiteMode.Unspecified;
}

De volgende code toont een voorbeeldmethode DisallowsSameSiteNone :

Warning

De volgende code is alleen bedoeld voor demonstratie:

  • Deze mag niet als volledig worden beschouwd.
  • Het wordt niet onderhouden of ondersteund.
public static bool DisallowsSameSiteNone(string userAgent)
{
    // Check if a null or empty string has been passed in, since this
    // will cause further interrogation of the useragent to fail.
     if (String.IsNullOrWhiteSpace(userAgent))
        return false;
    
    // Cover all iOS based browsers here. This includes:
    // - Safari on iOS 12 for iPhone, iPod Touch, iPad
    // - WkWebview on iOS 12 for iPhone, iPod Touch, iPad
    // - Chrome on iOS 12 for iPhone, iPod Touch, iPad
    // All of which are broken by SameSite=None, because they use the iOS networking
    // stack.
    if (userAgent.Contains("CPU iPhone OS 12") ||
        userAgent.Contains("iPad; CPU OS 12"))
    {
        return true;
    }

    // Cover Mac OS X based browsers that use the Mac OS networking stack. 
    // This includes:
    // - Safari on Mac OS X.
    // This does not include:
    // - Chrome on Mac OS X
    // Because they do not use the Mac OS networking stack.
    if (userAgent.Contains("Macintosh; Intel Mac OS X 10_14") &&
        userAgent.Contains("Version/") && userAgent.Contains("Safari"))
    {
        return true;
    }

    // Cover Chrome 50-69, because some versions are broken by SameSite=None, 
    // and none in this range require it.
    // Note: this covers some pre-Chromium Edge versions, 
    // but pre-Chromium Edge does not require SameSite=None.
    if (userAgent.Contains("Chrome/5") || userAgent.Contains("Chrome/6"))
    {
        return true;
    }

    return false;
}

Apps testen voor Problemen met SameSite

Apps die communiceren met externe sites, zoals via aanmelding van derden, moeten:

Test web-apps met behulp van een clientversie die zich kan aanmelden voor het nieuwe SameSite-gedrag. Chrome, Firefox en Chromium Edge hebben allemaal nieuwe opt-in functievlagmen die kunnen worden gebruikt voor het testen. Nadat uw app de SameSite-patches heeft toegepast, test u deze met oudere clientversies, met name Safari. Zie Ondersteunende oudere browsers in dit document voor meer informatie.

Testen met Chrome

Chrome 78+ geeft misleidende resultaten omdat er een tijdelijke mitigatie is. De Chrome 78+ tijdelijke beperking staat cookies toe die minder dan twee minuten oud zijn. Chrome 76 of 77 met de juiste testvlagmen ingeschakeld biedt nauwkeurigere resultaten. Om het nieuwe SameSite-gedrag te testen, schakelt u chrome://flags/#same-site-by-default-cookies naar Ingeschakeld. Er wordt gerapporteerd dat oudere versies van Chrome (75 en lager) falen met de nieuwe None instelling. Zie Ondersteuning van oudere browsers in dit document.

Google maakt geen oudere chrome-versies beschikbaar. Volg de instructies bij Chromium downloaden om oudere versies van Chrome te testen. Download Chrome niet via koppelingen die worden aangeboden door te zoeken naar oudere versies van Chrome.

Vanaf de Canary-versie 80.0.3975.0kan de tijdelijke Beperking van Lax+POST worden uitgeschakeld voor testdoeleinden met behulp van de nieuwe vlag --enable-features=SameSiteDefaultChecksMethodRigorously om het testen van sites en services in de uiteindelijke eindstatus van de functie waar de beperking is verwijderd, toe te staan. Zie The Chromium Projects SameSite Updates voor meer informatie

Testen met Safari

Safari 12 heeft het vorige concept strikt geïmplementeerd en mislukt wanneer de nieuwe None waarde zich in een cookiebevindt. None wordt vermeden via de browserdetectiecode die oudere browsers in dit document ondersteunt. Test Safari 12, Safari 13 en WebKit-gebaseerde aanmeldingen in OS-stijl met behulp van MSAL, ADAL of welke bibliotheek u ook gebruikt. Het probleem is afhankelijk van de onderliggende versie van het besturingssysteem. OSX Mojave (10.14) en iOS 12 zijn bekend dat er compatibiliteitsproblemen zijn met het nieuwe SameSite-gedrag. Als u het besturingssysteem bijwerkt naar OSX Catalina (10.15) of iOS 13, wordt het probleem opgelost. Safari heeft momenteel geen opt-in-vlag voor het testen van het nieuwe spec-gedrag.

Testen met Firefox

Firefox-ondersteuning voor de nieuwe standaard kan worden getest op versie 68+ door op de about:config pagina te kiezen met de functievlag network.cookie.sameSite.laxByDefault. Er zijn geen rapporten over compatibiliteitsproblemen met oudere versies van Firefox.

Testen met Edge-browser

Edge ondersteunt de oude SameSite-standaard. Edge-versie 44 heeft geen bekende compatibiliteitsproblemen met de nieuwe standaard.

Testen met Edge (Chromium)

SameSite-vlaggen worden ingesteld op de edge://flags/#same-site-by-default-cookies pagina. Er zijn geen compatibiliteitsproblemen gedetecteerd met Edge Chromium.

Testen met Electron

Versies van Electron zijn onder andere oudere versies van Chromium. De versie van Electron die door Teams wordt gebruikt, is bijvoorbeeld Chromium 66, dat het oudere gedrag vertoont. U moet uw eigen compatibiliteitstests uitvoeren met de versie die Electron door uw product wordt gebruikt. Zie Ondersteunende oudere browsers in de volgende sectie.

Aanvullende bronnen

Sample Document
MVC ASP.NET Core 2.1 MVC SameSite-voorbeeld cookie
Razor pagina's voorbeeld van ASP.NET Core 2.1 Razor Pages SameSite cookie