Exemplo de cookie SameSite para WebForms do ASP.NET 4.7.2 C#

.NET Framework 4,7 tem suporte interno para o atributo SameSite , mas está de acordo com o padrão original. O comportamento de patches alterou o significado de SameSite.None para emitir o atributo com um valor de None, em vez de não emitir o valor. Se você quiser não emitir o valor, poderá definir a propriedade SameSite em um cookie como-1.

Gravando o atributo SameSite

Veja a seguir um exemplo de como escrever um atributo SameSite em um cookie;

// Create the cookie
HttpCookie sameSiteCookie = new HttpCookie("SameSiteSample");

// Set a value for the cookie
sameSiteCookie.Value = "sample";

// Set the secure flag, which Chrome's changes will require for SameSite none.
// Note this will also require you to be running on HTTPS
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);

Se você estiver lendo isso em um idioma diferente do inglês, informe-nos sobre esse problema de discussão do GitHub se quiser ver os comentários de código em seu idioma nativo.

O atributo sameSite padrão para um cookie de autenticação de formulários é definido no parâmetro cookieSameSite das configurações de autenticação de formulários no web.config

<system.web>
  <authentication mode="Forms">
    <forms name=".ASPXAUTH" loginUrl="~/" cookieSameSite="None" requireSSL="true">
    </forms>
  </authentication>
</system.web>

O atributo sameSite padrão para o estado de sessão também é definido no parâmetro ' cookieSameSite ' das configurações de sessão no web.config

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

A atualização de novembro de 2019 para .NET alterou as configurações padrão de autenticação de formulários e sessão para lax como é a configuração mais compatível. no entanto, se você inserir páginas em IFrames, talvez seja necessário reverter essa configuração para nenhuma e, em seguida, adicionar o código de intercepção mostrado abaixo para ajustar o comportamento de none dependendo da funcionalidade do navegador.

Executando o exemplo

Se você executar o projeto de exemplo, carregue o depurador do navegador na página inicial e use-o para exibir a coleção de cookies para o site. Para fazer isso no Microsoft Edge e no Chrome, pressione F12 selecione a guia Application e clique na URL do site na opção Cookies na seção Storage.

Lista de cookies do depurador do navegador

Você pode ver na imagem acima que o cookie criado pelo exemplo ao clicar no botão "criar cookies" tem um valor de atributo SameSite de Lax, correspondendo ao valor definido no código de exemplo.

Interceptando cookies que você não controla

O .NET 4.5.2 introduziu um novo evento para interceptar a gravação de cabeçalhos, Response.AddOnSendingHeaders. Isso pode ser usado para interceptar cookies antes que eles sejam retornados para o computador cliente. No exemplo, conectamos o evento a um método estático que verifica se o navegador dá suporte a novas alterações de sameSite e, caso contrário, altera os cookies para não emitir o atributo se o novo valor de None tiver sido definido.

Consulte global. asax para obter um exemplo de como conectar o evento e SameSiteCookieRewriter.cs para obter um exemplo de como manipular o evento e ajustar o atributo sameSite cookie.

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

Você pode alterar o comportamento de Cookie nomeado específico praticamente da mesma forma; o exemplo a seguir ajusta o cookie de autenticação padrão de Lax para None em navegadores que dão suporte ao valor de None ou remove o atributo sameSite em navegadores que não dão suporte a 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;
            }
        }
    });
}

Mais informações

Atualizações do Chrome

Documentação do ASP.NET

Patches do .NET SameSite