Sdílet prostřednictvím


Práce s SameSite cookies v ASP.NET Core

Autor: Rick Anderson

SameSite je koncept IETF standard navržený tak, aby poskytoval určitou ochranu před útoky csrF (cross-site request forgery). Původně byl koncept v roce 2016 aktualizován v roce 2019. Aktualizovaný standard není zpětně kompatibilní s předchozím standardem, přičemž nejvýraznější rozdíly jsou následující:

  • Cookies bez hlavičky SameSite se ve výchozím nastavení zachází jako SameSite=Lax s hlavičkou SameSite.
  • SameSite=None musí být použita k povolení použití mezi weby cookie .
  • Cookies, že kontrolní výraz SameSite=None musí být také označen jako Secure.
  • Aplikace, které používají <iframe> , můžou mít problémy s sameSite=Lax nebo sameSite=Strictcookies, protože <iframe> se považují za scénáře mezi weby.
  • Hodnota SameSite=None není povolena standardem 2016 a způsobuje, že některé implementace budou považovat za takové cookiejako SameSite=Strict. Viz Podpora starších prohlížečů v tomto dokumentu.

Nastavení SameSite=Lax funguje pro většinu aplikací cookie. Některé formy ověřování, jako je OpenID Připojení (OIDC) a WS-Federation, jsou výchozí pro přesměrování založené na POST. Přesměrování na základě POST aktivují ochranu prohlížeče SameSite, takže pro tyto komponenty je zakázáno SameSite. Většina přihlášení OAuth nemá vliv na rozdíly ve způsobu toku požadavků.

Každá komponenta ASP.NET Core, která generuje cookie, se musí rozhodnout, jestli je to vhodné pro SameSite.

SameSite a Identity

ASP.NET Core Identity nemá na SameSitecookievliv, s výjimkou pokročilých scénářů, jako IFrames je nebo OpenIdConnect integrace.

Pokud používáte Identity, nepřidávejte žádné cookie poskytovatele ani volání services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme), Identity postará se o to.

Vzorový kód testu SameSite

Následující ukázku je možné stáhnout a otestovat:

Vzorek Dokument
Stránky .NET Core Razor Ukázka ASP.NET Core 3.1 Razor Pages SameSite cookie

Podpora .NET Core pro atribut sameSite

.NET Core podporuje koncept standardu 2019 pro SameSite. Vývojáři můžou programově řídit hodnotu stejného atributuSite pomocí HttpCookie.SameSite vlastnosti. SameSite Nastavení vlastnosti na Stricthodnotu , Laxnebo None vede k zápisu těchto hodnot v síti pomocí cookie. Nastavení označující, že SameSiteMode.Unspecified se nemá odesílat žádná stejná lokalita pomocí 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);
}

Využití rozhraní API se samesitem

HttpContext.Response.Cookies.Append defaults to Unspecified, což znamená, že žádný atribut SameSite přidán do cookie a klient bude používat jeho výchozí chování (Lax pro nové prohlížeče, None pro staré). Následující kód ukazuje, jak změnit cookie hodnotu SameSite na SameSiteMode.Lax:

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

Všechny komponenty ASP.NET Core, které generují cookie, přepíší předchozí výchozí hodnoty nastavením odpovídajícím jejich scénářům. Přepsáné předchozí výchozí hodnoty se nezměnily.

Komponenta cookie Výchozí
CookieBuilder SameSite Unspecified
Session SessionOptions.Cookie Lax
CookieTempDataProvider CookieTempDataProviderOptions.Cookie Lax
IAntiforgery AntiforgeryOptions.Cookie Strict
Cookie Ověřování CookieAuthenticationOptions.Cookie Lax
AddTwitter TwitterOptions.StateCookie Lax
RemoteAuthenticationHandler<TOptions> RemoteAuthenticationOptions.CorrelationCookie None
AddOpenIdConnect OpenId Připojení Options.NonceCookie None
HttpContext.Response.Cookies.Append CookieOptions Unspecified

ASP.NET Core 3.1 a novější poskytuje následující podporu SameSite:

  • Předefinuje chování SameSiteMode.None při generování. SameSite=None
  • Přidá novou hodnotu SameSiteMode.Unspecified , která vynechá atribut SameSite.
  • Všechna cookierozhraní API ve výchozím nastavení Unspecified. Některé komponenty, které používají cookiehodnoty nastavené konkrétněji pro jejich scénáře. Příklady najdete v tabulce výše.

V ASP.NET Core 3.0 a novějších se změnily výchozí hodnoty SameSite, aby nedocházelo ke konfliktu s nekonzistentními výchozími nastaveními klienta. Následující rozhraní API změnila výchozí hodnotu tak SameSiteMode.Lax , aby -1 se zabránilo generování atributu SameSite pro tyto cookies:

Historie a změny

Podpora SameSite byla poprvé implementována v ASP.NET Core ve verzi 2.0 pomocí konceptu standardu 2016. Standard 2016 byl opt-in. ASP.NET core se přihlásilo nastavením několika cookiemožností na Lax výchozí nastavení. Po výskytu několika problémů s ověřováním se většina využití SameSite zakázala.

Opravy byly vydány v listopadu 2019, aby se aktualizovaly ze standardu 2016 na standard 2019. Koncept specifikace SameSite z roku 2019:

  • Není zpětně kompatibilní s konceptem 2016. Další informace naleznete v tématu Podpora starších prohlížečů v tomto dokumentu.
  • Určujecookie, že se s nimi ve výchozím nastavení zachází.SameSite=Lax
  • Určuje cookie, že explicitní tvrzení SameSite=None , aby bylo možné povolit doručování mezi weby, by mělo být označeno jako Secure. None je nová položka pro odhlášení.
  • Podporují se opravy vydané pro ASP.NET Core 2.1, 2.2 a 3.0. ASP.NET Core 3.1 a novější má další podporu SameSite.
  • Ve výchozím nastavení je v únoru 2020 naplánované, aby ho chrome povolil. Prohlížeče začaly v roce 2019 přejít na tento standard.

Rozhraní API ovlivněná změnou ze standardu konceptu SameSite z roku 2016 na koncept 2019

Podpora starších prohlížečů

Standard SameSite 2016 vyžaduje, aby neznámé hodnoty byly považovány za SameSite=Strict hodnoty. Aplikace, ke kterým se přistupuje ze starších prohlížečů, které podporují standard SameSite 2016, se můžou přerušit, když získají vlastnost SameSite s hodnotou None. Webové aplikace musí implementovat detekci prohlížeče, pokud mají v úmyslu podporovat starší prohlížeče. ASP.NET Core neimplementuje detekci prohlížeče, protože hodnoty User-Agents jsou vysoce nestálé a často se mění. Bod Microsoft.AspNetCore.CookiePolicy rozšíření umožňuje připojit logiku specifickou pro uživatele agenta.

Do Program.cspříkazu přidejte kód, který volá UseCookiePolicy před voláním UseAuthentication nebo jakoukoli metodou, která zapisuje cookie:

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

Přidejte Program.cskód podobný následujícímu zvýrazněného kódu:

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

V předchozí ukázce je knihovna zadaná uživatelem, která zjistí, MyUserAgentDetectionLib.DisallowsSameSiteNone jestli uživatelský agent nepodporuje SameSite None:

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

Následující kód ukazuje ukázkovou DisallowsSameSiteNone metodu:

Upozorňující

Následující kód je určen pouze pro ukázku:

  • Nemělo by se považovat za dokončené.
  • Neudržuje se ani nepodporuje.
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;
}

Testování aplikací pro problémy se samesitem

Aplikace, které komunikují se vzdálenými weby, jako je přihlášení třetích stran, musí:

Otestujte webové aplikace pomocí klientské verze, která se může přihlásit k novému chování SameSite. Chrome, Firefox a Chromium Edge mají nové příznaky funkce opt-in, které je možné použít k testování. Jakmile aplikace použije opravy SameSite, otestujte ji ve starších verzích klienta, zejména v Safari. Další informace naleznete v tématu Podpora starších prohlížečů v tomto dokumentu.

Testování pomocí Chromu

Chrome 78+ poskytuje zavádějící výsledky, protože má dočasné zmírnění rizik. Dočasné zmírnění rizik pro Chrome 78+ umožňuje cookieméně než dvě minuty staré. Chrome 76 nebo 77 s povolenými příslušnými testovacími příznaky poskytuje přesnější výsledky. Chcete-li otestovat nové chování SameSite, přepněte chrome://flags/#same-site-by-default-cookies na Povoleno. Starší verze Chromu (75 a novější) se hlásí, že selhávají s novým None nastavením. Viz Podpora starších prohlížečů v tomto dokumentu.

Google nezpřístupní starší verze chromu. Postupujte podle pokynů ke stažení Chromium a otestujte starší verze Chromu. Nestahujte Chrome z odkazů poskytovaných vyhledáváním starších verzí chromu.

Počínaje verzí 80.0.3975.0Canary je možné dočasné zmírnění rizik Lax+POST zakázat pro účely testování pomocí nového příznaku --enable-features=SameSiteDefaultChecksMethodRigorously , který umožňuje testování webů a služeb v konečném koncovém stavu funkce, ve které bylo zmírnění rizik odebráno. Další informace naleznete v tématu Chromium Projects SameSite Aktualizace

Testování pomocí Safari

Safari 12 striktně implementoval předchozí koncept a selže, když je nová None hodnota v cookie. None se vyhnete prostřednictvím kódu detekce prohlížeče podporujícího starší prohlížeče v tomto dokumentu. Otestujte přihlášení stylu operačního systému Založené na Safari 12, Safari 13 a WebKitu pomocí knihovny MSAL, ADAL nebo libovolné knihovny, kterou používáte. Problém závisí na základní verzi operačního systému. OSX Mojave (10.14) a iOS 12 jsou známé, že mají problémy s kompatibilitou s novým chováním SameSite. Problém řeší upgrade operačního systému na OSX Catalina (10.15) nebo iOS 13. Safari momentálně nemá příznak výslovného souhlasu pro testování nového chování specifikace.

Testování ve Firefoxu

Podporu Firefoxu pro nový standard lze testovat na verzi 68+ výslovným souhlasem na about:config stránce s příznakem network.cookie.sameSite.laxByDefaultfunkce . Ve starších verzích Firefoxu nebyly hlášeny problémy s kompatibilitou.

Testování v prohlížeči Edge

Edge podporuje starý standard SameSite. Edge verze 44 nemá žádné známé problémy s kompatibilitou s novým standardem.

Testování s edgem (Chromium)

Na stránce jsou nastavené edge://flags/#same-site-by-default-cookies příznaky SameSite. U Edge Chromium nebyly zjištěny žádné problémy s kompatibilitou.

Testování s využitím Electron

Verze Electron zahrnují starší verze Chromium. Například verze Electron používaná aplikací Teams je Chromium 66, která vykazuje starší chování. Musíte provést vlastní testování kompatibility s verzí Electron vašeho produktu. Viz Podpora starších prohlížečů v následující části.

Další materiály

Vzorek Dokument
Stránky .NET Core Razor Ukázka ASP.NET Core 3.1 Razor Pages SameSite cookie

Následující ukázku je možné stáhnout a otestovat:

Vzorek Dokument
Stránky .NET Core Razor Ukázka ASP.NET Core 3.1 Razor Pages SameSite cookie

Podpora .NET Core pro atribut sameSite

.NET Core 3.1 a novější podporují koncept standardu 2019 pro SameSite. Vývojáři můžou programově řídit hodnotu stejného atributuSite pomocí HttpCookie.SameSite vlastnosti. SameSite Nastavení vlastnosti Strict, Lax nebo None způsobí, že tyto hodnoty se zapisují do sítě pomocí cookie. Nastavení, které (SameSiteMode)(-1) se rovná značí, že v síti by neměl být zahrnut žádný atribut sameSite 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 a novější podporují aktualizované hodnoty SameSite a přidají do výčtu SameSiteMode další výčtovou hodnotuSameSiteMode.Unspecified. Tato nová hodnota indikuje, že se nemá odesílat žádná stejná lokalita s hodnotou cookie.

Využití rozhraní API se samesitem

HttpContext.Response.Cookies.Append defaults to Unspecified, což znamená, že žádný atribut SameSite přidán do cookie a klient bude používat jeho výchozí chování (Lax pro nové prohlížeče, None pro staré). Následující kód ukazuje, jak změnit cookie hodnotu SameSite na SameSiteMode.Lax:

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

Všechny komponenty ASP.NET Core, které generují cookie, přepíší předchozí výchozí hodnoty nastavením odpovídajícím jejich scénářům. Přepsáné předchozí výchozí hodnoty se nezměnily.

Komponenta cookie Výchozí
CookieBuilder SameSite Unspecified
Session SessionOptions.Cookie Lax
CookieTempDataProvider CookieTempDataProviderOptions.Cookie Lax
IAntiforgery AntiforgeryOptions.Cookie Strict
Cookie Ověřování CookieAuthenticationOptions.Cookie Lax
AddTwitter TwitterOptions.StateCookie Lax
RemoteAuthenticationHandler<TOptions> RemoteAuthenticationOptions.CorrelationCookie None
AddOpenIdConnect OpenId Připojení Options.NonceCookie None
HttpContext.Response.Cookies.Append CookieOptions Unspecified

ASP.NET Core 3.1 a novější poskytuje následující podporu SameSite:

  • Předefinuje chování SameSiteMode.None při generování. SameSite=None
  • Přidá novou hodnotu SameSiteMode.Unspecified , která vynechá atribut SameSite.
  • Všechna cookierozhraní API ve výchozím nastavení Unspecified. Některé komponenty, které používají cookiehodnoty nastavené konkrétněji pro jejich scénáře. Příklady najdete v tabulce výše.

V ASP.NET Core 3.0 a novějších se změnily výchozí hodnoty SameSite, aby nedocházelo ke konfliktu s nekonzistentními výchozími nastaveními klienta. Následující rozhraní API změnila výchozí hodnotu tak SameSiteMode.Lax , aby -1 se zabránilo generování atributu SameSite pro tyto cookies:

Historie a změny

Podpora SameSite byla poprvé implementována v ASP.NET Core ve verzi 2.0 pomocí konceptu standardu 2016. Standard 2016 byl opt-in. ASP.NET core se přihlásilo nastavením několika cookiemožností na Lax výchozí nastavení. Po výskytu několika problémů s ověřováním se většina využití SameSite zakázala.

Opravy byly vydány v listopadu 2019, aby se aktualizovaly ze standardu 2016 na standard 2019. Koncept specifikace SameSite z roku 2019:

  • Není zpětně kompatibilní s konceptem 2016. Další informace naleznete v tématu Podpora starších prohlížečů v tomto dokumentu.
  • Určujecookie, že se s nimi ve výchozím nastavení zachází.SameSite=Lax
  • Určuje cookie, že explicitní tvrzení SameSite=None , aby bylo možné povolit doručování mezi weby, by mělo být označeno jako Secure. None je nová položka pro odhlášení.
  • Podporují se opravy vydané pro ASP.NET Core 2.1, 2.2 a 3.0. ASP.NET Core 3.1 má další podporu SameSite.
  • Ve výchozím nastavení je v únoru 2020 naplánované, aby ho chrome povolil. Prohlížeče začaly v roce 2019 přejít na tento standard.

Rozhraní API ovlivněná změnou ze standardu konceptu SameSite z roku 2016 na koncept 2019

Podpora starších prohlížečů

Standard SameSite 2016 vyžaduje, aby neznámé hodnoty byly považovány za SameSite=Strict hodnoty. Aplikace, ke kterým se přistupuje ze starších prohlížečů, které podporují standard SameSite 2016, se můžou přerušit, když získají vlastnost SameSite s hodnotou None. Webové aplikace musí implementovat detekci prohlížeče, pokud mají v úmyslu podporovat starší prohlížeče. ASP.NET Core neimplementuje detekci prohlížeče, protože hodnoty User-Agents jsou vysoce nestálé a často se mění. Bod Microsoft.AspNetCore.CookiePolicy rozšíření umožňuje připojit logiku specifickou pro uživatele agenta.

Do Startup.Configurepříkazu přidejte kód, který volá UseCookiePolicy před voláním UseAuthentication nebo jakoukoli metodou, která zapisuje cookie:

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

Do Startup.ConfigureServicespole přidejte kód podobný následujícímu:

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

V předchozí ukázce je knihovna zadaná uživatelem, která zjistí, MyUserAgentDetectionLib.DisallowsSameSiteNone jestli uživatelský agent nepodporuje SameSite None:

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

Následující kód ukazuje ukázkovou DisallowsSameSiteNone metodu:

Upozorňující

Následující kód je určen pouze pro ukázku:

  • Nemělo by se považovat za dokončené.
  • Neudržuje se ani nepodporuje.
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;
}

Testování aplikací pro problémy se samesitem

Aplikace, které komunikují se vzdálenými weby, jako je přihlášení třetích stran, musí:

Otestujte webové aplikace pomocí klientské verze, která se může přihlásit k novému chování SameSite. Chrome, Firefox a Chromium Edge mají nové příznaky funkce opt-in, které je možné použít k testování. Jakmile aplikace použije opravy SameSite, otestujte ji ve starších verzích klienta, zejména v Safari. Další informace naleznete v tématu Podpora starších prohlížečů v tomto dokumentu.

Testování pomocí Chromu

Chrome 78+ poskytuje zavádějící výsledky, protože má dočasné zmírnění rizik. Dočasné zmírnění rizik pro Chrome 78+ umožňuje cookieméně než dvě minuty staré. Chrome 76 nebo 77 s povolenými příslušnými testovacími příznaky poskytuje přesnější výsledky. Chcete-li otestovat nové chování SameSite, přepněte chrome://flags/#same-site-by-default-cookies na Povoleno. Starší verze Chromu (75 a novější) se hlásí, že selhávají s novým None nastavením. Viz Podpora starších prohlížečů v tomto dokumentu.

Google nezpřístupní starší verze chromu. Postupujte podle pokynů ke stažení Chromium a otestujte starší verze Chromu. Nestahujte Chrome z odkazů poskytovaných vyhledáváním starších verzí chromu.

Počínaje verzí 80.0.3975.0Canary je možné dočasné zmírnění rizik Lax+POST zakázat pro účely testování pomocí nového příznaku --enable-features=SameSiteDefaultChecksMethodRigorously , který umožňuje testování webů a služeb v konečném koncovém stavu funkce, ve které bylo zmírnění rizik odebráno. Další informace naleznete v tématu Chromium Projects SameSite Aktualizace

Testování pomocí Safari

Safari 12 striktně implementoval předchozí koncept a selže, když je nová None hodnota v cookie. None se vyhnete prostřednictvím kódu detekce prohlížeče podporujícího starší prohlížeče v tomto dokumentu. Otestujte přihlášení stylu operačního systému Založené na Safari 12, Safari 13 a WebKitu pomocí knihovny MSAL, ADAL nebo libovolné knihovny, kterou používáte. Problém závisí na základní verzi operačního systému. OSX Mojave (10.14) a iOS 12 jsou známé, že mají problémy s kompatibilitou s novým chováním SameSite. Problém řeší upgrade operačního systému na OSX Catalina (10.15) nebo iOS 13. Safari momentálně nemá příznak výslovného souhlasu pro testování nového chování specifikace.

Testování ve Firefoxu

Podporu Firefoxu pro nový standard lze testovat na verzi 68+ výslovným souhlasem na about:config stránce s příznakem network.cookie.sameSite.laxByDefaultfunkce . Ve starších verzích Firefoxu nebyly hlášeny problémy s kompatibilitou.

Testování v prohlížeči Edge

Edge podporuje starý standard SameSite. Edge verze 44 nemá žádné známé problémy s kompatibilitou s novým standardem.

Testování s edgem (Chromium)

Na stránce jsou nastavené edge://flags/#same-site-by-default-cookies příznaky SameSite. U Edge Chromium nebyly zjištěny žádné problémy s kompatibilitou.

Testování s využitím Electron

Verze Electron zahrnují starší verze Chromium. Například verze Electron používaná aplikací Teams je Chromium 66, která vykazuje starší chování. Musíte provést vlastní testování kompatibility s verzí Electron vašeho produktu. Viz Podpora starších prohlížečů v následující části.

Další materiály

Vzorek Dokument
Stránky .NET Core Razor Ukázka ASP.NET Core 3.1 Razor Pages SameSite cookie

Následující ukázky je možné stáhnout a otestovat:

Vzorek Dokument
.NET Core MVC Ukázka ASP.NET Core 2.1 MVC SameSite cookie
Stránky .NET Core Razor Ukázka ASP.NET Core 2.1 Razor Pages SameSite cookie

Změny chování oprav v prosinci

Konkrétní změna chování pro rozhraní .NET Framework a .NET Core 2.1 je způsob, jakým SameSite vlastnost interpretuje None hodnotu. Před opravou je hodnota None "Nevysílejte atribut vůbec", po opravě to znamená "Vygenerovat atribut s hodnotou None". Po opravě SameSite hodnota (SameSiteMode)(-1) způsobí, že se atribut nevygeneruje.

Výchozí hodnota SameSite pro ověřování formulářů a stav cookierelací se změnila z None na Lax.

Využití rozhraní API se samesitem

HttpContext.Response.Cookies.Append defaults to Unspecified, což znamená, že žádný atribut SameSite přidán do cookie a klient bude používat jeho výchozí chování (Lax pro nové prohlížeče, None pro staré). Následující kód ukazuje, jak změnit cookie hodnotu SameSite na SameSiteMode.Lax:

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

Všechny komponenty ASP.NET Core, které generují cookie, přepíší předchozí výchozí hodnoty nastavením odpovídajícím jejich scénářům. Přepsáné předchozí výchozí hodnoty se nezměnily.

Komponenta cookie Výchozí
CookieBuilder SameSite Unspecified
Session SessionOptions.Cookie Lax
CookieTempDataProvider CookieTempDataProviderOptions.Cookie Lax
IAntiforgery AntiforgeryOptions.Cookie Strict
Cookie Ověřování CookieAuthenticationOptions.Cookie Lax
AddTwitter TwitterOptions.StateCookie Lax
RemoteAuthenticationHandler<TOptions> RemoteAuthenticationOptions.CorrelationCookie None
AddOpenIdConnect OpenId Připojení Options.NonceCookie None
HttpContext.Response.Cookies.Append CookieOptions Unspecified

Historie a změny

Podpora SameSite byla poprvé implementována v ASP.NET Core ve verzi 2.0 pomocí konceptu standardu 2016. Standard 2016 byl opt-in. ASP.NET core se přihlásilo nastavením několika cookiemožností na Lax výchozí nastavení. Po výskytu několika problémů s ověřováním se většina využití SameSite zakázala.

Opravy byly vydány v listopadu 2019, aby se aktualizovaly ze standardu 2016 na standard 2019. Koncept specifikace SameSite z roku 2019:

  • Není zpětně kompatibilní s konceptem 2016. Další informace naleznete v tématu Podpora starších prohlížečů v tomto dokumentu.
  • Určujecookie, že se s nimi ve výchozím nastavení zachází.SameSite=Lax
  • Určuje cookie, že explicitní tvrzení SameSite=None , aby bylo možné povolit doručování mezi weby, by mělo být označeno jako Secure. None je nová položka pro odhlášení.
  • Podporují se opravy vydané pro ASP.NET Core 2.1, 2.2 a 3.0. ASP.NET Core 3.1 má další podporu SameSite.
  • Ve výchozím nastavení je v únoru 2020 naplánované, aby ho chrome povolil. Prohlížeče začaly v roce 2019 přejít na tento standard.

Rozhraní API ovlivněná změnou ze standardu konceptu SameSite z roku 2016 na koncept 2019

Podpora starších prohlížečů

Standard SameSite 2016 vyžaduje, aby neznámé hodnoty byly považovány za SameSite=Strict hodnoty. Aplikace, ke kterým se přistupuje ze starších prohlížečů, které podporují standard SameSite 2016, se můžou přerušit, když získají vlastnost SameSite s hodnotou None. Webové aplikace musí implementovat detekci prohlížeče, pokud mají v úmyslu podporovat starší prohlížeče. ASP.NET Core neimplementuje detekci prohlížeče, protože hodnoty User-Agents jsou vysoce nestálé a často se mění. Bod Microsoft.AspNetCore.CookiePolicy rozšíření umožňuje připojit logiku specifickou pro uživatele agenta.

Do Startup.Configurepříkazu přidejte kód, který volá UseCookiePolicy před voláním UseAuthentication nebo jakoukoli metodou, která zapisuje cookie:

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

Do Startup.ConfigureServicespole přidejte kód podobný následujícímu:

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

    }
}

V předchozí ukázce je knihovna zadaná uživatelem, která zjistí, MyUserAgentDetectionLib.DisallowsSameSiteNone jestli uživatelský agent nepodporuje SameSite None:

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

Následující kód ukazuje ukázkovou DisallowsSameSiteNone metodu:

Upozorňující

Následující kód je určen pouze pro ukázku:

  • Nemělo by se považovat za dokončené.
  • Neudržuje se ani nepodporuje.
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;
}

Testování aplikací pro problémy se samesitem

Aplikace, které komunikují se vzdálenými weby, jako je přihlášení třetích stran, musí:

Otestujte webové aplikace pomocí klientské verze, která se může přihlásit k novému chování SameSite. Chrome, Firefox a Chromium Edge mají nové příznaky funkce opt-in, které je možné použít k testování. Jakmile aplikace použije opravy SameSite, otestujte ji ve starších verzích klienta, zejména v Safari. Další informace naleznete v tématu Podpora starších prohlížečů v tomto dokumentu.

Testování pomocí Chromu

Chrome 78+ poskytuje zavádějící výsledky, protože má dočasné zmírnění rizik. Dočasné zmírnění rizik pro Chrome 78+ umožňuje cookieméně než dvě minuty staré. Chrome 76 nebo 77 s povolenými příslušnými testovacími příznaky poskytuje přesnější výsledky. Chcete-li otestovat nové chování SameSite, přepněte chrome://flags/#same-site-by-default-cookies na Povoleno. Starší verze Chromu (75 a novější) se hlásí, že selhávají s novým None nastavením. Viz Podpora starších prohlížečů v tomto dokumentu.

Google nezpřístupní starší verze chromu. Postupujte podle pokynů ke stažení Chromium a otestujte starší verze Chromu. Nestahujte Chrome z odkazů poskytovaných vyhledáváním starších verzí chromu.

Počínaje verzí 80.0.3975.0Canary je možné dočasné zmírnění rizik Lax+POST zakázat pro účely testování pomocí nového příznaku --enable-features=SameSiteDefaultChecksMethodRigorously , který umožňuje testování webů a služeb v konečném koncovém stavu funkce, ve které bylo zmírnění rizik odebráno. Další informace naleznete v tématu Chromium Projects SameSite Aktualizace

Testování pomocí Safari

Safari 12 striktně implementoval předchozí koncept a selže, když je nová None hodnota v cookie. None se vyhnete prostřednictvím kódu detekce prohlížeče podporujícího starší prohlížeče v tomto dokumentu. Otestujte přihlášení stylu operačního systému Založené na Safari 12, Safari 13 a WebKitu pomocí knihovny MSAL, ADAL nebo libovolné knihovny, kterou používáte. Problém závisí na základní verzi operačního systému. OSX Mojave (10.14) a iOS 12 jsou známé, že mají problémy s kompatibilitou s novým chováním SameSite. Problém řeší upgrade operačního systému na OSX Catalina (10.15) nebo iOS 13. Safari momentálně nemá příznak výslovného souhlasu pro testování nového chování specifikace.

Testování ve Firefoxu

Podporu Firefoxu pro nový standard lze testovat na verzi 68+ výslovným souhlasem na about:config stránce s příznakem network.cookie.sameSite.laxByDefaultfunkce . Ve starších verzích Firefoxu nebyly hlášeny problémy s kompatibilitou.

Testování v prohlížeči Edge

Edge podporuje starý standard SameSite. Edge verze 44 nemá žádné známé problémy s kompatibilitou s novým standardem.

Testování s edgem (Chromium)

Na stránce jsou nastavené edge://flags/#same-site-by-default-cookies příznaky SameSite. U Edge Chromium nebyly zjištěny žádné problémy s kompatibilitou.

Testování s využitím Electron

Verze Electron zahrnují starší verze Chromium. Například verze Electron používaná aplikací Teams je Chromium 66, která vykazuje starší chování. Musíte provést vlastní testování kompatibility s verzí Electron vašeho produktu. Viz Podpora starších prohlížečů v následující části.

Další materiály

Vzorek Dokument
.NET Core MVC Ukázka ASP.NET Core 2.1 MVC SameSite cookie
Stránky .NET Core Razor Ukázka ASP.NET Core 2.1 Razor Pages SameSite cookie