Auf Englisch lesen

Freigeben über


SameSite-Cookiebeispiel für ASP.NET 4.7.2 C#-MVC

.NET Framework 4.7 verfügt über integrierte Unterstützung für das SameSite-Attribut, entspricht jedoch dem ursprünglichen Standard. Das gepatchte Verhalten hat die Bedeutung von SameSite.None geändert, um das -Attribut mit dem Wert von Noneauszustrahlen, anstatt den Wert überhaupt nicht auszustrahlen. Wenn Sie den Wert nicht ausgeben möchten, können Sie die SameSite Eigenschaft für ein Cookie auf -1 festlegen.

Schreiben des SameSite-Attributs

Im Folgenden finden Sie ein Beispiel für das Schreiben eines SameSite-Attributs für ein 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);

Wenn Sie dies in einer anderen Sprache als Englisch lesen, teilen Sie uns dies in diesem GitHub-Diskussionsproblem mit, wenn Sie die Codekommentare in Ihrer Muttersprache sehen möchten.

Das standard sameSite-Attribut für den Sitzungszustand wird im Parameter "cookieSameSite" der Sitzungseinstellungen in festgelegt. web.config

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

MVC-Authentifizierung

Die OWIN MVC-cookiebasierte Authentifizierung verwendet einen Cookie-Manager, um das Ändern von Cookieattributen zu ermöglichen. SameSiteCookieManager.cs ist eine Implementierung einer solchen Klasse, die Sie in Ihre eigenen Projekte kopieren können.

Sie müssen sicherstellen, dass Ihre Microsoft.Owin-Komponenten alle auf Version 4.1.0 oder höher aktualisiert werden. Überprüfen Sie Ihre packages.config Datei, um z. B. sicherzustellen, dass alle Versionsnummern übereinstimmen.

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

Die Authentifizierungskomponenten müssen dann für die Verwendung des CookieManagers in Ihrer Startklasse konfiguriert werden.

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

Für jede Komponente, die sie unterstützt, muss ein Cookie-Manager festgelegt werden, einschließlich CookieAuthentication und OpenIdConnectAuthentication.

Der SystemWebCookieManager wird verwendet, um bekannte Probleme bei der Integration von Antwortcookies zu vermeiden.

Ausführen des Beispiels

Wenn Sie das Beispielprojekt ausführen, laden Sie Ihren Browserdebugger auf der ersten Seite, und verwenden Sie ihn, um die Cookiesammlung für die Website anzuzeigen. Klicken F12 Sie dazu in Edge und Chrome auf die Application Registerkarte, und klicken Sie unter der Option im Storage Abschnitt auf die Cookies Website-URL.

Cookieliste des Browserdebuggers

In der obigen Abbildung sehen Sie, dass das vom Beispiel erstellte Cookie, wenn Sie auf die Schaltfläche "Cookies erstellen" klicken, den SameSite-Attributwert von Laxaufweist, der dem im Beispielcode festgelegten Wert entspricht.

Abfangen von Cookies, die Sie nicht steuern

In .NET 4.5.2 wurde ein neues Ereignis zum Abfangen des Schreibens von Headern eingeführt. Response.AddOnSendingHeaders Dies kann verwendet werden, um Cookies abzufangen, bevor sie an den Clientcomputer zurückgegeben werden. Im Beispiel verknüpfen wir das Ereignis mit einer statischen Methode, die überprüft, ob der Browser die neuen GleichenSite-Änderungen unterstützt, und wenn dies nicht der Fall ist, werden die Cookies so geändert, dass das Attribut nicht ausgegeben wird, wenn der neue None Wert festgelegt wurde.

Ein Beispiel für die Verarbeitung des Ereignisses und das Anpassen des Cookie-AttributssameSite, das Sie in Ihren eigenen Code kopieren können, finden Sie unter global.asax und SameSiteCookieRewriter.cs.

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

Sie können bestimmtes Benanntes Cookie-Verhalten auf die gleiche Weise ändern. Im folgenden Beispiel wird das Standardauthentifizierungscooky in LaxNone Browsern angepasst, die den None Wert unterstützen, oder dasselbeSite-Attribut in Browsern entfernt, die nicht unterstützen 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;
            }
        }
    });
}

Weitere Informationen

Chrome Updates

OWIN SameSite-Dokumentation

ASP.NET-Dokumentation

.NET SameSite Patches