Usar autenticação cookie sem ASP.NET Core Identity
O ASP.NET Core Identity é um provedor de autenticação completo para criar e manter logins. No entanto, um provedor de autenticação baseado em cookie sem ASP.NET Core Identity pode ser usado. Para obter mais informações, confira Introdução a Identity no ASP.NET Core.
Exibir ou baixar código de exemplo (como baixar)
Para fins de demonstração no aplicativo de exemplo, a conta de usuário do usuário hipotético, Maria Rodriguez, é codificada no aplicativo. Use o endereço de emailmaria.rodriguez@contoso.com
e qualquer senha para entrar no usuário. O usuário é autenticado no método AuthenticateUser
do arquivo Pages/Account/Login.cshtml.cs
. Em um exemplo real, o usuário seria autenticado em um armazenamento de dados.
Adicionar autenticação cookie
- Adicione os serviços do Middleware de autenticação com os métodos AddAuthentication e AddCookie .
- Chame UseAuthentication e UseAuthorization para definir a propriedade
HttpContext.User
e execute o Middleware de autorização para solicitações.UseAuthentication
eUseAuthorization
deve ser chamado antes dos métodosMap
como MapRazorPages e MapDefaultControllerRoute
using Microsoft.AspNetCore.Authentication.Cookies;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie();
builder.Services.AddHttpContextAccessor();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthentication();
app.UseAuthorization();
app.MapRazorPages();
app.MapDefaultControllerRoute();
app.Run();
AuthenticationScheme passado para AddAuthentication
define o esquema de autenticação padrão do aplicativo. AuthenticationScheme
é útil quando há várias instâncias de autenticação cookie e o aplicativo precisa autorizar com um esquema específico. Configurar AuthenticationScheme
como CookieAuthenticationDefaults.AuthenticationScheme fornece um valor igual a "Cookies"
para o esquema. Qualquer valor de cadeia de caracteres que distingue o esquema pode ser usado.
O esquema de autenticação do aplicativo é diferente do esquema de autenticação cookie do aplicativo. Quando um esquema de autenticação cookie não é fornecido para AddCookie, ele usa CookieAuthenticationDefaults.AuthenticationScheme
. A CookieAuthenticationDefaults.AuthenticationScheme
Fonte do GitHub mostra que está definido como "Cookies"
.
A propriedade cookie de autenticação IsEssential é definida como true
por padrão. Os cookies de autenticação são permitidos quando um visitante do site não consente a coleta de dados. Para obter mais informações, veja Suporte ao RGPD (Regulamento Geral sobre a Proteção de Dados) no ASP.NET Core.
A classe CookieAuthenticationOptions é usada para configurar as opções do provedor de autenticação.
Configure CookieAuthenticationOptions no método AddCookie:
using Microsoft.AspNetCore.Authentication.Cookies;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.ExpireTimeSpan = TimeSpan.FromMinutes(20);
options.SlidingExpiration = true;
options.AccessDeniedPath = "/Forbidden/";
});
builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthentication();
app.UseAuthorization();
app.MapRazorPages();
app.MapDefaultControllerRoute();
app.Run();
Middleware de política de Cookie
O Cookie Middleware de política (fonte do GitHub) UseCookiePolicy habilita cookie recursos de política. O middleware é processado na ordem em que é adicionado:
app.UseCookiePolicy(cookiePolicyOptions);
Use CookiePolicyOptions fornecido ao CookieMiddleware de política para controlar as características globais do processamento de cookie e conecte-se aos manipuladores de processamento de cookie quando os cookies forem acrescentados ou excluídos.
O valor padrão MinimumSameSitePolicy é SameSiteMode.Lax
para permitir a autenticação OAuth2. Para impor estritamente uma política do mesmo site de SameSiteMode.Strict
, defina o MinimumSameSitePolicy
. Embora essa configuração interrompa o OAuth2 e outros esquemas de autenticação entre origens, ela eleva o nível de segurança do cookie para outros tipos de aplicativos que não dependem do processamento de solicitações entre origens.
var cookiePolicyOptions = new CookiePolicyOptions
{
MinimumSameSitePolicy = SameSiteMode.Strict,
};
A configuração do Middleware de política de Cookie para MinimumSameSitePolicy
pode afetar a configuração de Cookie.SameSite
em configurações CookieAuthenticationOptions
de acordo com a matriz abaixo.
MinimumSameSitePolicy | Cookie.SameSite | Cookie resultante. Configuração SameSite |
---|---|---|
SameSiteMode.None | SameSiteMode.None SameSiteMode.Lax SameSiteMode.Strict |
SameSiteMode.None SameSiteMode.Lax SameSiteMode.Strict |
SameSiteMode.Lax | SameSiteMode.None SameSiteMode.Lax SameSiteMode.Strict |
SameSiteMode.Lax SameSiteMode.Lax SameSiteMode.Strict |
SameSiteMode.Strict | SameSiteMode.None SameSiteMode.Lax SameSiteMode.Strict |
SameSiteMode.Strict SameSiteMode.Strict SameSiteMode.Strict |
Criar um cookie de autenticação
Para criar um cookie que contenha as informações do usuário, construa um ClaimsPrincipal. As informações do usuário são serializadas e armazenadas no cookie.
Crie um ClaimsIdentity com quaisquer Claims necessários e chame SignInAsync para conectar o usuário. O Login.cshtml.cs
no aplicativo de amostra contém o seguinte código:
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
ReturnUrl = returnUrl;
if (ModelState.IsValid)
{
// Use Input.Email and Input.Password to authenticate the user
// with your custom authentication logic.
//
// For demonstration purposes, the sample validates the user
// on the email address maria.rodriguez@contoso.com with
// any password that passes model validation.
var user = await AuthenticateUser(Input.Email, Input.Password);
if (user == null)
{
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
return Page();
}
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, user.Email),
new Claim("FullName", user.FullName),
new Claim(ClaimTypes.Role, "Administrator"),
};
var claimsIdentity = new ClaimsIdentity(
claims, CookieAuthenticationDefaults.AuthenticationScheme);
var authProperties = new AuthenticationProperties
{
//AllowRefresh = <bool>,
// Refreshing the authentication session should be allowed.
//ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(10),
// The time at which the authentication ticket expires. A
// value set here overrides the ExpireTimeSpan option of
// CookieAuthenticationOptions set with AddCookie.
//IsPersistent = true,
// Whether the authentication session is persisted across
// multiple requests. When used with cookies, controls
// whether the cookie's lifetime is absolute (matching the
// lifetime of the authentication ticket) or session-based.
//IssuedUtc = <DateTimeOffset>,
// The time at which the authentication ticket was issued.
//RedirectUri = <string>
// The full path or absolute URI to be used as an http
// redirect response value.
};
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity),
authProperties);
_logger.LogInformation("User {Email} logged in at {Time}.",
user.Email, DateTime.UtcNow);
return LocalRedirect(Url.GetLocalUrl(returnUrl));
}
// Something failed. Redisplay the form.
return Page();
}
Se você quiser ver os comentários de código traduzidos para idiomas diferentes do inglês, informe-nos neste problema de discussão do GitHub.
SignInAsync
cria um cookie criptografado e adiciona-o à resposta atual. Se AuthenticationScheme
não for especificado, o esquema padrão será usado.
RedirectUri é usado apenas em alguns caminhos específicos por padrão, por exemplo, o caminho de logon e os caminhos de logoff. Para mais informações, consulte a origem CookieAuthenticationHandler .
O sistema de Proteção de Dados do ASP.NET Core é usado para criptografia. Para um aplicativo hospedado em vários computadores, balanceamento de carga entre aplicativos ou usando um web farm, configure a proteção de dados para usar o mesmo anel de chave e identificador de aplicativo.
Sair
Para fazer logoff do usuário atual e excluir o cookie dele, chame SignOutAsync:
public async Task OnGetAsync(string returnUrl = null)
{
if (!string.IsNullOrEmpty(ErrorMessage))
{
ModelState.AddModelError(string.Empty, ErrorMessage);
}
// Clear the existing external cookie
await HttpContext.SignOutAsync(
CookieAuthenticationDefaults.AuthenticationScheme);
ReturnUrl = returnUrl;
}
Se CookieAuthenticationDefaults.AuthenticationScheme
ou "Cookies" não for usado como o esquema, forneça o esquema usado ao configurar o provedor de autenticação. Caso contrário, o esquema padrão será usado. Por exemplo, se "ContosoCookies" for usado como esquema, forneça o esquema usado ao configurar o provedor de autenticação.
Quando o navegador fecha, ele exclui automaticamente cookies baseados em sessão (cookies não persistentes), mas nenhum cookie é apagado quando uma guia individual é fechada. O servidor não é notificado sobre eventos de fechamento de guia ou de navegador.
Reagir a alterações de back-end
Depois que um cookie for criado, o cookie será a única fonte de identity. Se uma conta de usuário estiver desabilitada em sistemas de back-end:
- O sistema de autenticação de cookie do aplicativo continua a processar solicitações com base na autenticação cookie.
- O usuário permanece conectado ao aplicativo, desde que a autenticação cookie seja válida.
O evento ValidatePrincipal pode ser usado para interceptar e substituir a validação da identidade cookieidentity. Validar o cookie em cada solicitação reduz o risco de usuários revogados acessarem o aplicativo.
Uma abordagem para validação cookie baseia-se em manter o controle de quando o banco de dados do usuário é alterado. Se o banco de dados não tiver sido alterado desde que o cookie do usuário foi emitido, não será necessário autenticar novamente o usuário se cookie dele ainda for válido. No aplicativo de exemplo, o banco de dados é implementado em IUserRepository
e armazena um valor LastChanged
. Quando um usuário é atualizado no banco de dados, o valor LastChanged
é definido como a hora atual.
Para invalidar um cookie quando o banco de dados for alterado com base no valor LastChanged
, crie o cookie com uma declaração LastChanged
que contenha o valor LastChanged
atual do banco de dados:
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, user.Email),
new Claim("LastChanged", {Database Value})
};
var claimsIdentity = new ClaimsIdentity(
claims,
CookieAuthenticationDefaults.AuthenticationScheme);
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity));
Para implementar uma substituição para o evento ValidatePrincipal
, escreva um método com a seguinte assinatura em uma classe derivada de CookieAuthenticationEvents:
ValidatePrincipal(CookieValidatePrincipalContext)
A seguir é um exemplo de implementação de CookieAuthenticationEvents
:
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
public class CustomCookieAuthenticationEvents : CookieAuthenticationEvents
{
private readonly IUserRepository _userRepository;
public CustomCookieAuthenticationEvents(IUserRepository userRepository)
{
_userRepository = userRepository;
}
public override async Task ValidatePrincipal(CookieValidatePrincipalContext context)
{
var userPrincipal = context.Principal;
// Look for the LastChanged claim.
var lastChanged = (from c in userPrincipal.Claims
where c.Type == "LastChanged"
select c.Value).FirstOrDefault();
if (string.IsNullOrEmpty(lastChanged) ||
!_userRepository.ValidateLastChanged(lastChanged))
{
context.RejectPrincipal();
await context.HttpContext.SignOutAsync(
CookieAuthenticationDefaults.AuthenticationScheme);
}
}
}
Registre a instância de eventos durante o registro do serviço cookie. Forneça um registro de serviço com escopo para sua classe CustomCookieAuthenticationEvents
:
using Microsoft.AspNetCore.Authentication.Cookies;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.EventsType = typeof(CustomCookieAuthenticationEvents);
});
builder.Services.AddScoped<CustomCookieAuthenticationEvents>();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthentication();
app.UseAuthorization();
app.MapRazorPages();
app.MapDefaultControllerRoute();
app.Run();
Considere uma situação em que o nome do usuário é atualizado — uma decisão que não afeta a segurança de forma alguma. Se você quiser atualizar de forma não destrutiva a entidade de segurança do usuário, chame context.ReplacePrincipal
e defina a propriedade context.ShouldRenew
como true
.
Aviso
A abordagem descrita aqui é disparada em cada solicitação. Validar cookies de autenticação para todos os usuários em cada solicitação pode resultar em um grande comprometimento de desempenho para o aplicativo.
Cookies persistentes
Talvez você queira que o cookie persista entre as sessões do navegador. Essa persistência só deve ser habilitada com o consentimento explícito do usuário com uma caixa de seleção "Lembrar-me" na entrada ou em um mecanismo semelhante.
O snippet de código a seguir cria uma identity e o cookie correspondente que sobrevive por meio de fechamentos do navegador. Todas as configurações de expiração deslizantes configuradas anteriormente são respeitadas. Se o cookie expirar enquanto o navegador estiver fechado, o navegador limpará o cookie depois de reiniciado.
Defina IsPersistent como true
em AuthenticationProperties:
// using Microsoft.AspNetCore.Authentication;
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity),
new AuthenticationProperties
{
IsPersistent = true
});
Expiração absoluta de cookie
Um tempo de expiração absoluto pode ser definido com ExpiresUtc. Para criar um cookie persistente, IsPersistent
também deve ser definido. Caso contrário, o cookie será criado com um tempo de vida baseado em sessão e poderá expirar antes ou depois do tíquete de autenticação que ele contém. Quando ExpiresUtc
é definido, ele substitui o valor da opção ExpireTimeSpan de CookieAuthenticationOptions, se definido.
O snippet de código a seguir cria uma identity e o cookie correspondente que dura 20 minutos. Isso ignora as configurações de expiração deslizantes configuradas anteriormente.
// using Microsoft.AspNetCore.Authentication;
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity),
new AuthenticationProperties
{
IsPersistent = true,
ExpiresUtc = DateTime.UtcNow.AddMinutes(20)
});
O ASP.NET Core Identity é um provedor de autenticação completo para criar e manter logins. No entanto, um provedor de autenticação baseado em cookie sem ASP.NET Core Identity pode ser usado. Para obter mais informações, confira Introdução a Identity no ASP.NET Core.
Exibir ou baixar código de exemplo (como baixar)
Para fins de demonstração no aplicativo de exemplo, a conta de usuário do usuário hipotético, Maria Rodriguez, é codificada no aplicativo. Use o endereço de emailmaria.rodriguez@contoso.com
e qualquer senha para entrar no usuário. O usuário é autenticado no método AuthenticateUser
do arquivo Pages/Account/Login.cshtml.cs
. Em um exemplo real, o usuário seria autenticado em um banco de dados.
Configuração
No método Startup.ConfigureServices
, crie os serviços do Middleware de autenticação com os métodos AddAuthentication e AddCookie:
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie();
AuthenticationScheme passado para AddAuthentication
define o esquema de autenticação padrão do aplicativo. AuthenticationScheme
é útil quando há várias instâncias de autenticação cookie e deseja autorizar com um esquema específico. Configurar AuthenticationScheme
como CookieAuthenticationDefaults.AuthenticationScheme fornece um valor de "Cookies" para o esquema. Você pode fornecer qualquer valor de cadeia de caracteres que distingue o esquema.
O esquema de autenticação do aplicativo é diferente do esquema de autenticação cookie do aplicativo. Quando um esquema de autenticação cookie não é fornecido para AddCookie, ele usa CookieAuthenticationDefaults.AuthenticationScheme
("Cookies").
A propriedade cookie de autenticação IsEssential é definida como true
por padrão. Os cookies de autenticação são permitidos quando um visitante do site não consente a coleta de dados. Para obter mais informações, veja Suporte ao RGPD (Regulamento Geral sobre a Proteção de Dados) no ASP.NET Core.
Em Startup.Configure
, chame UseAuthentication
e UseAuthorization
para definir a propriedade HttpContext.User
e execute o Middleware de autorização para solicitações. Chame os métodos UseAuthentication
e UseAuthorization
antes de chamar UseEndpoints
:
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapRazorPages();
});
A classe CookieAuthenticationOptions é usada para configurar as opções do provedor de autenticação.
Defina na configuração do serviço CookieAuthenticationOptions
para autenticação no método Startup.ConfigureServices
:
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
...
});
Middleware de política de Cookie
O Middleware de política Cookie habilita os recursos de política cookie. A adição do middleware ao pipeline de processamento de aplicativos diferencia a ordem, afetando apenas os componentes downstream registrados no pipeline.
app.UseCookiePolicy(cookiePolicyOptions);
Use CookiePolicyOptions fornecido ao CookieMiddleware de política para controlar as características globais do processamento de cookie e conecte-se aos manipuladores de processamento de cookie quando os cookies forem acrescentados ou excluídos.
O valor padrão MinimumSameSitePolicy é SameSiteMode.Lax
para permitir a autenticação OAuth2. Para impor estritamente uma política do mesmo site de SameSiteMode.Strict
, defina o MinimumSameSitePolicy
. Embora essa configuração interrompa o OAuth2 e outros esquemas de autenticação entre origens, ela eleva o nível de segurança do cookie para outros tipos de aplicativos que não dependem do processamento de solicitações entre origens.
var cookiePolicyOptions = new CookiePolicyOptions
{
MinimumSameSitePolicy = SameSiteMode.Strict,
};
A configuração do Middleware de política de Cookie para MinimumSameSitePolicy
pode afetar a configuração de Cookie.SameSite
em configurações CookieAuthenticationOptions
de acordo com a matriz abaixo.
MinimumSameSitePolicy | Cookie.SameSite | Cookie resultante. Configuração SameSite |
---|---|---|
SameSiteMode.None | SameSiteMode.None SameSiteMode.Lax SameSiteMode.Strict |
SameSiteMode.None SameSiteMode.Lax SameSiteMode.Strict |
SameSiteMode.Lax | SameSiteMode.None SameSiteMode.Lax SameSiteMode.Strict |
SameSiteMode.Lax SameSiteMode.Lax SameSiteMode.Strict |
SameSiteMode.Strict | SameSiteMode.None SameSiteMode.Lax SameSiteMode.Strict |
SameSiteMode.Strict SameSiteMode.Strict SameSiteMode.Strict |
Criar um cookie de autenticação
Para criar um cookie que contenha as informações do usuário, construa um ClaimsPrincipal. As informações do usuário são serializadas e armazenadas no cookie.
Crie um ClaimsIdentity com qualquer Claims necessário e chame SignInAsync para conectar o usuário:
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, user.Email),
new Claim("FullName", user.FullName),
new Claim(ClaimTypes.Role, "Administrator"),
};
var claimsIdentity = new ClaimsIdentity(
claims, CookieAuthenticationDefaults.AuthenticationScheme);
var authProperties = new AuthenticationProperties
{
//AllowRefresh = <bool>,
// Refreshing the authentication session should be allowed.
//ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(10),
// The time at which the authentication ticket expires. A
// value set here overrides the ExpireTimeSpan option of
// CookieAuthenticationOptions set with AddCookie.
//IsPersistent = true,
// Whether the authentication session is persisted across
// multiple requests. When used with cookies, controls
// whether the cookie's lifetime is absolute (matching the
// lifetime of the authentication ticket) or session-based.
//IssuedUtc = <DateTimeOffset>,
// The time at which the authentication ticket was issued.
//RedirectUri = <string>
// The full path or absolute URI to be used as an http
// redirect response value.
};
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity),
authProperties);
Se você quiser ver os comentários de código traduzidos para idiomas diferentes do inglês, informe-nos neste problema de discussão do GitHub.
SignInAsync
cria um cookie criptografado e adiciona-o à resposta atual. Se AuthenticationScheme
não for especificado, o esquema padrão será usado.
RedirectUri é usado apenas em alguns caminhos específicos por padrão, por exemplo, o caminho de logon e os caminhos de logoff. Para mais informações, consulte a origem CookieAuthenticationHandler .
O sistema de Proteção de Dados do ASP.NET Core é usado para criptografia. Para um aplicativo hospedado em vários computadores, balanceamento de carga entre aplicativos ou usando um web farm, configure a proteção de dados para usar o mesmo anel de chave e identificador de aplicativo.
Sair
Para fazer logoff do usuário atual e excluir o cookie dele, chame SignOutAsync:
await HttpContext.SignOutAsync(
CookieAuthenticationDefaults.AuthenticationScheme);
Se CookieAuthenticationDefaults.AuthenticationScheme
(ou "Cookies") não for usado como esquema (por exemplo, "ContosoCookie"), forneça o esquema usado ao configurar o provedor de autenticação. Caso contrário, o esquema padrão será usado.
Quando o navegador fecha, ele exclui automaticamente cookies baseados em sessão (cookies não persistentes), mas nenhum cookie é apagado quando uma guia individual é fechada. O servidor não é notificado sobre eventos de fechamento de guia ou de navegador.
Reagir a alterações de back-end
Depois que um cookie for criado, o cookie será a única fonte de identity. Se uma conta de usuário estiver desabilitada em sistemas de back-end:
- O sistema de autenticação de cookie do aplicativo continua a processar solicitações com base na autenticação cookie.
- O usuário permanece conectado ao aplicativo, desde que a autenticação cookie seja válida.
O evento ValidatePrincipal pode ser usado para interceptar e substituir a validação da identidade cookieidentity. Validar o cookie em cada solicitação reduz o risco de usuários revogados acessarem o aplicativo.
Uma abordagem para validação cookie baseia-se em manter o controle de quando o banco de dados do usuário é alterado. Se o banco de dados não tiver sido alterado desde que o cookie do usuário foi emitido, não será necessário autenticar novamente o usuário se cookie dele ainda for válido. No aplicativo de exemplo, o banco de dados é implementado em IUserRepository
e armazena um valor LastChanged
. Quando um usuário é atualizado no banco de dados, o valor LastChanged
é definido como a hora atual.
Para invalidar um cookie quando o banco de dados for alterado com base no valor LastChanged
, crie o cookie com uma declaração LastChanged
que contenha o valor LastChanged
atual do banco de dados:
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, user.Email),
new Claim("LastChanged", {Database Value})
};
var claimsIdentity = new ClaimsIdentity(
claims,
CookieAuthenticationDefaults.AuthenticationScheme);
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity));
Para implementar uma substituição para o evento ValidatePrincipal
, escreva um método com a seguinte assinatura em uma classe derivada de CookieAuthenticationEvents:
ValidatePrincipal(CookieValidatePrincipalContext)
A seguir é um exemplo de implementação de CookieAuthenticationEvents
:
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
public class CustomCookieAuthenticationEvents : CookieAuthenticationEvents
{
private readonly IUserRepository _userRepository;
public CustomCookieAuthenticationEvents(IUserRepository userRepository)
{
// Get the database from registered DI services.
_userRepository = userRepository;
}
public override async Task ValidatePrincipal(CookieValidatePrincipalContext context)
{
var userPrincipal = context.Principal;
// Look for the LastChanged claim.
var lastChanged = (from c in userPrincipal.Claims
where c.Type == "LastChanged"
select c.Value).FirstOrDefault();
if (string.IsNullOrEmpty(lastChanged) ||
!_userRepository.ValidateLastChanged(lastChanged))
{
context.RejectPrincipal();
await context.HttpContext.SignOutAsync(
CookieAuthenticationDefaults.AuthenticationScheme);
}
}
}
Registre a instância de eventos durante o registro do serviço cookie no método Startup.ConfigureServices
. Forneça um registro de serviço com escopo para sua classe CustomCookieAuthenticationEvents
:
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.EventsType = typeof(CustomCookieAuthenticationEvents);
});
services.AddScoped<CustomCookieAuthenticationEvents>();
Considere uma situação em que o nome do usuário é atualizado — uma decisão que não afeta a segurança de forma alguma. Se você quiser atualizar de forma não destrutiva a entidade de segurança do usuário, chame context.ReplacePrincipal
e defina a propriedade context.ShouldRenew
como true
.
Aviso
A abordagem descrita aqui é disparada em cada solicitação. Validar cookies de autenticação para todos os usuários em cada solicitação pode resultar em um grande comprometimento de desempenho para o aplicativo.
Cookies persistentes
Talvez você queira que o cookie persista entre as sessões do navegador. Essa persistência só deve ser habilitada com o consentimento explícito do usuário com uma caixa de seleção "Lembrar-me" na entrada ou em um mecanismo semelhante.
O snippet de código a seguir cria uma identity e o cookie correspondente que sobrevive por meio de fechamentos do navegador. Todas as configurações de expiração deslizantes configuradas anteriormente são respeitadas. Se o cookie expirar enquanto o navegador estiver fechado, o navegador limpará o cookie depois de reiniciado.
Defina IsPersistent como true
em AuthenticationProperties:
// using Microsoft.AspNetCore.Authentication;
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity),
new AuthenticationProperties
{
IsPersistent = true
});
Expiração absoluta de cookie
Um tempo de expiração absoluto pode ser definido com ExpiresUtc. Para criar um cookie persistente, IsPersistent
também deve ser definido. Caso contrário, o cookie será criado com um tempo de vida baseado em sessão e poderá expirar antes ou depois do tíquete de autenticação que ele contém. Quando ExpiresUtc
é definido, ele substitui o valor da opção ExpireTimeSpan de CookieAuthenticationOptions, se definido.
O snippet de código a seguir cria uma identity e o cookie correspondente que dura 20 minutos. Isso ignora as configurações de expiração deslizantes configuradas anteriormente.
// using Microsoft.AspNetCore.Authentication;
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity),
new AuthenticationProperties
{
IsPersistent = true,
ExpiresUtc = DateTime.UtcNow.AddMinutes(20)
});