Amostra de SameSite MVC cookie do ASP.NET Core 2.1
O ASP.NET Core 2.1 tem suporte interno para o atributo SameSite, mas foi gravado no padrão original. O comportamento corrigido alterou o significado de SameSite.None
para emitir o atributo SameSite com um valor de None
, em vez de não emitir o valor. Se você não quiser emitir o valor, poderá definir a propriedadeSameSite
em um cookie como -1.
O Identity do ASP.NET Core não é substancialmente afetado pelos cookies SameSite, exceto por cenários avançados, como integração de IFrames
ou OpenIdConnect
.
Ao usar Identity
, não adicione nenhum cookie provedor ou chame services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
. O Identity
cuida disso.
Gravando o atributo SameSite
Veja a seguir um exemplo de como escrever um atributo SameSite em um 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 the SameSite property to (SameSiteMode)(-1).
SameSite = SameSiteMode.None
};
// Add the cookie to the response cookie collection
Response.Cookies.Append(CookieName, "cookieValue", cookieOptions);
Como definir o Cookie de autenticação e os cookies de estados da sessão
A autenticação Cookie, o estado de sessão e vários outros componentes definem suas opções do sameSite por meio de opções Cookie, por exemplo
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.Cookie.SameSite = SameSiteMode.None;
options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
options.Cookie.IsEssential = true;
});
services.AddSession(options =>
{
options.Cookie.SameSite = SameSiteMode.None;
options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
options.Cookie.IsEssential = true;
});
No código mostrado acima, a autenticação cookie e o estado de sessão definem seu atributo SameSite como None
, emitindo o atributo com um valor None
e também define o atributo Secure como true.
Execute o exemplo
Se você executar o projeto de exemplo, carregue o depurador do navegador na página inicial e use-o para exibir o conjunto cookie do site. Para fazer isso no Edge e no Chrome, pressione F12
, selecione a guia Application
e clique na URL do site na opção Cookies
na seção Storage
.
Você pode ver na imagem acima que o cookie criado pelo exemplo quando você clica no botão "Criar SameSite Cookie" tem um valor de atributo SameSite igual ao valor de Lax
definido no código de exemplo.
Interceptação de cookies
Para interceptar o cookies para ajustar o valor none de acordo com seu suporte no agente do navegador do usuário, você deve usar o middleware CookiePolicy
. Isso deve ser colocado no pipeline da solicitação http antes de todos os componentes que gravam cookies e são configurados no ConfigureServices()
.
Para inseri-lo no pipeline, use app.UseCookiePolicy()
no método Configure(IApplicationBuilder, IHostingEnvironment)
em startup.cs. Por exemplo:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseAuthentication();
app.UseSession();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
Em seguida, no ConfigureServices(IServiceCollection services)
, configure a política cookie para chamar uma classe auxiliar quando cookies são acrescentados ou excluídos. Por exemplo:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
options.OnAppendCookie = cookieContext =>
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
options.OnDeleteCookie = cookieContext =>
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
});
}
private void CheckSameSite(HttpContext httpContext, CookieOptions options)
{
if (options.SameSite == SameSiteMode.None)
{
var userAgent = httpContext.Request.Headers["User-Agent"].ToString();
if (SameSite.BrowserDetection.DisallowsSameSiteNone(userAgent))
{
options.SameSite = (SameSiteMode)(-1);
}
}
}
A função CheckSameSite(HttpContext, CookieOptions)
auxiliar:
- É chamada quando os cookies são acrescentados à solicitação ou excluídos da solicitação.
- Verifica se a propriedade
SameSite
está definida comoNone
. - Se
SameSite
for definido comoNone
e o agente de usuário atual for conhecido por não dar suporte ao valor de atributo none. A marcar é feita usando a classe SameSiteSupport:- Define
SameSite
para não emitir o valor definindo a propriedade como(SameSiteMode)(-1)
- Define
Direcionamento ao .NET Framework
O ASP.NET Core e o System.Web (ASP.NET 4.x) têm implementações independentes do SameSite. Os patches de KB do SameSite para .NET Framework não serão necessários se forem usados no ASP.NET Core nem o requisito de versão mínima da estrutura System.Web SameSite (.NET Framework 4.7.2) se aplica ao ASP.NET Core.
O ASP.NET Core no .NET requer a atualização das dependências do pacote NuGet para obter as correções apropriadas.
Para obter as alterações do ASP.NET Core para .NET Framework verifique se você tem uma referência direta aos pacotes e versões corrigidos (2.1.14 ou versões posteriores 2.1).
<PackageReference Include="Microsoft.Net.Http.Headers" Version="2.1.14" />
<PackageReference Include="Microsoft.AspNetCore.CookiePolicy" Version="2.1.14" />
Mais informações
Anúncio de Alterações do SameSite do ASP.NET Core 2.1nas Atualizações do Chrome para a Documentação do SameSite do ASP.NET Core 2.1