Amostra de cookie SameSite para ASP.NET MVC 4.7.2 C#
.NET Framework 4.7 tem suporte interno para o atributo SameSite, mas segue o padrão original.
O comportamento corrigido alterou o significado de SameSite.None
para emitir o atributo com um valor de , em vez de None
não emitir o valor. Se você não quiser emitir o valor, poderá definir a SameSite
propriedade em um cookie como -1.
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 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);
Se você estiver lendo isso em um idioma diferente do inglês, informe-nos neste 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 o estado da sessão é definido no parâmetro 'cookieSameSite' das configurações de sessão em web.config
<system.web>
<sessionState cookieSameSite="None">
</sessionState>
</system.web>
A autenticação baseada em cookie OWIN MVC usa um gerenciador de cookies para habilitar a alteração de atributos de cookie. O SameSiteCookieManager.cs é uma implementação dessa classe que você pode copiar para seus próprios projetos.
Você deve garantir que os componentes do Microsoft.Owin sejam atualizados para a versão 4.1.0 ou superior. Verifique o packages.config
arquivo para garantir que todos os números de versão correspondam, por exemplo.
<?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>
Os componentes de autenticação devem então ser configurados para usar o CookieManager em sua classe de inicialização;
public void Configuration(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
CookieSameSite = SameSiteMode.None,
CookieHttpOnly = true,
CookieSecure = CookieSecureOption.Always,
CookieManager = new SameSiteCookieManager(new SystemWebCookieManager())
});
}
Um gerenciador de cookies deve ser definido em cada componente que dá suporte a ele, incluindo CookieAuthentication e OpenIdConnectAuthentication.
O SystemWebCookieManager é usado para evitar problemas conhecidos com a integração de cookie de resposta.
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 cookie do site.
Para fazer isso no Edge e no Chrome, pressione F12
a Application
guia e clique na URL do site na opção Cookies
na Storage
seção .
Você pode ver na imagem acima que o cookie criado pelo exemplo quando você clica no botão "Criar Cookies" tem um valor de atributo SameSite de Lax
, correspondendo ao valor definido no código de exemplo.
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 às novas alterações sameSite e, caso contrário, altera os cookies para não emitir o atributo se o novo None
valor tiver sido definido.
Consulte global.asax para obter um exemplo de como conectar o evento e SameSiteCookieRewriter.cs para obter um exemplo de manipulação do evento e ajuste do atributo de cookie sameSite
que você pode copiar em seu próprio código.
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 específico do cookie nomeado da mesma maneira; o exemplo abaixo ajusta o cookie de autenticação padrão de Lax
para None
em navegadores que dão suporte ao None
valor ou remove o mesmo atributoSite em navegadores que não dão suporte None
a .
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;
}
}
});
}