Partilhar via


Usar cookie autenticação sem ASP.NET Core Identity

Por Rick Anderson

ASP.NET Core Identity é um provedor de autenticação completo para criar e manter acessos. No entanto, um provedor de autenticação com base em cookie sem ASP.NET Core Identity pode ser usado. Para obter mais informações, consulte Introdução ao Identity em ASP.NET Core.

Visualizar ou descarregar amostra de código (como descarregar)

Para fins de demonstração no aplicativo de exemplo, a conta de usuário para o usuário hipotético, Maria Rodriguez, é codificada no aplicativo. Use o endereço maria.rodriguez@contoso.com e qualquer senha para entrar no usuário. O utilizador é autenticado no método AuthenticateUser no arquivo Pages/Account/Login.cshtml.cs. Em um exemplo do mundo real, o utilizador seria autenticado contra um repositório de dados.

Importante

A partir do ASP.NET Core 10, os pontos de extremidade de API conhecidos não redirecionam mais para páginas de login ao usar cookie a autenticação. Em vez disso, eles retornam códigos de status 401/403. Para obter detalhes, consulte Comportamento de autenticação de ponto de extremidade da API no ASP.NET Core.

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 para o aplicativo. AuthenticationScheme é útil quando há várias instâncias de cookie autenticação e o aplicativo precisa autorizar com um esquema específico. Definir o AuthenticationScheme para CookieAuthenticationDefaults.AuthenticationScheme fornece um valor de "Cookies" para o esquema. Qualquer valor de cadeia de caracteres pode ser usado para distinguir o esquema.

Se CookieAuthenticationDefaults.AuthenticationScheme (valor padrão: "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 é usado. Por exemplo, se "ContosoCookie" for usado como o esquema, forneça o esquema usado ao configurar o provedor de autenticação.

Por padrão, a propriedade cookie da autenticação IsEssential é definida como true. Os cookies de autenticação são permitidos quando um visitante do site não consentiu com a recolha de dados. Para obter mais informações, consulte Suporte do Regulamento Geral sobre a Proteção de Dados (RGPD) no ASP.NET Core.

A CookieAuthenticationOptions classe é usada para configurar as opções do provedor de autenticação.

Configure o 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();

O Cookie Policy Middleware (GitHub Source)UseCookiePolicy habilita cookie os recursos de política. O middleware é processado na ordem em que é adicionado e Cookie o Policy Middleware deve ser adicionado antes cookie do middleware de autenticação.

Use o CookiePolicyOptions fornecido ao Middleware de Política para controlar as Cookie características globais de processamento e integre-se com os manipuladores de processamento cookie ao anexar ou excluir cookies.

O valor padrão MinimumSameSitePolicy é SameSiteMode.Lax para permitir a autenticação OAuth2. Para aplicar estritamente uma política de mesmo domínio do SameSiteMode.Strict, defina o MinimumSameSitePolicy. Embora essa configuração quebre o OAuth2 e outros esquemas de autenticação entre origens, ela eleva o nível de segurança para outros tipos de aplicativos que não dependem do processamento de cookie solicitações entre origens.

O exemplo a seguir mostra como configurar cookie autenticação com Cookie Policy Middleware.

var cookiePolicyOptions = new CookiePolicyOptions
{
    MinimumSameSitePolicy = SameSiteMode.Strict,
};

app.UseCookiePolicy(cookiePolicyOptions);

A configuração de Middleware de Política em Cookie para MinimumSameSitePolicy pode afetar a configuração de Cookie.SameSite nas definições de CookieAuthenticationOptions de acordo com a matriz abaixo.

MínimoSameSitePolicy Cookie. SameSite Resultado Cookie. Configuração SameSite
SameSiteMode.Nenhum SameSiteMode.Nenhum
SameSiteMode.Lax
SameSiteMode.Strict
SameSiteMode.Nenhum
SameSiteMode.Lax
SameSiteMode.Strict
SameSiteMode.Lax SameSiteMode.Nenhum
SameSiteMode.Lax
SameSiteMode.Strict
SameSiteMode.Lax
SameSiteMode.Lax
SameSiteMode.Strict
SameSiteMode.Strict SameSiteMode.Nenhum
SameSiteMode.Lax
SameSiteMode.Strict
SameSiteMode.Strict
SameSiteMode.Strict
SameSiteMode.Strict

Para criar um cookie que contenha informações do usuário, crie um ClaimsPrincipal. As informações do usuário são serializadas e armazenadas no cookie.

Crie um ClaimsIdentity com qualquer Claim necessário e chame SignInAsync para iniciar sessão no utilizador. Login.cshtml.cs no aplicativo de exemplo 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 quiser ver os comentários de código traduzidos para outros idiomas além do inglês, avise-nos nesta discussão do GitHub .

SignInAsync cria um criptografado cookie e o adiciona à 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 login e os caminhos de logout. Para obter mais informações, consulte a fonte CookieAuthenticationHandler.

O sistema de Proteção de Dados do ASP.NET Core é usado para criptografia. Para um aplicativo hospedado em várias máquinas, balanceamento de carga entre aplicativos ou usando uma web farm, configure a proteção de dados para usar o mesmo conjunto de chaves e identificador de aplicativo.

Terminar sessão

Para terminar a sessão do utilizador atual e eliminar o cookie, 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 (valor padrão: "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 é usado. Por exemplo, se "ContosoCookie" for usado como o esquema, forneça o esquema usado ao configurar o provedor de autenticação.

Quando o navegador fecha, elimina automaticamente os cookies baseados na sessão (cookies não persistentes), mas nenhum cookie é apagado quando um separador individual é fechado. O servidor não é notificado de eventos de fechamento de guias ou navegadores.

Reaja a alterações no servidor

Uma vez que um cookie é criado, o cookie é a única fonte de identidade. Se uma conta de usuário estiver desativada em sistemas back-end:

  • O sistema de autenticação do cookie aplicativo continua a processar solicitações com base na autenticação cookie.
  • O usuário permanece conectado ao aplicativo enquanto a autenticação cookie for válida.

O ValidatePrincipal evento pode ser usado para intercetar e sobrepor a validação da cookie identidade. Validar o cookie em cada solicitação reduz o risco de usuários revogados acessarem o aplicativo.

Uma abordagem para a cookie validação baseia-se em manter o controle de quando o banco de dados de usuários muda. Se o banco de dados não tiver sido alterado desde que o credencial do usuário cookie foi emitido, não há necessidade de reautenticar o usuário se a credencial cookie ainda for válida. 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 LastChanged valor é definido para a hora atual.

Para invalidar um cookie quando o banco de dados for alterado com base no LastChanged valor, crie o cookie com uma LastChanged declaração contendo o valor atual LastChanged 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 ValidatePrincipal evento, escreva um método com a seguinte assinatura em uma classe que deriva de CookieAuthenticationEvents:

ValidatePrincipal(CookieValidatePrincipalContext)

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

Registe a instância de eventos durante o cookie registo do serviço. Forneça um registo de serviço com escopo para a sua CustomCookieAuthenticationEvents classe.

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 usuário, chame context.ReplacePrincipal e defina a context.ShouldRenew propriedade como true.

Warning

A abordagem descrita aqui é acionada em cada solicitação. A validação de cookies de autenticação para todos os usuários em cada solicitação pode resultar em uma grande penalidade de desempenho para o aplicativo.

Cookies persistentes

Você pode querer que o cookie persista nas sessões do navegador. Esta persistência só deve ser ativada com o consentimento explícito do utilizador com uma caixa de verificação "Lembrar-me" no início de sessão ou um mecanismo semelhante.

O trecho de código a seguir cria uma identidade e o correspondente cookie que perdura durante os encerramentos do navegador. Todas as configurações de expiração deslizante configuradas anteriormente são respeitadas. Se o cookie expirar enquanto o navegador estiver fechado, o navegador limpará o cookie assim que for reiniciado.

Definir IsPersistent para true em AuthenticationProperties.

// using Microsoft.AspNetCore.Authentication;

await HttpContext.SignInAsync(
    CookieAuthenticationDefaults.AuthenticationScheme,
    new ClaimsPrincipal(claimsIdentity),
    new AuthenticationProperties
    {
        IsPersistent = true
    });

Um tempo de expiração absoluto pode ser definido com ExpiresUtc. Para criar um persistente cookie, IsPersistent também deve ser definido. Caso contrário, o cookie é criado com um tempo de vida baseado em sessão e pode expirar antes ou depois do tíquete de autenticação que ele mantém. Quando ExpiresUtc é definido, ele sobrepõe o valor da opção ExpireTimeSpan de CookieAuthenticationOptions, se definido.

O trecho de código a seguir cria uma identidade e correspondente cookie que dura 20 minutos. Isso ignora todas as configurações de expiração deslizante configuradas anteriormente.

// using Microsoft.AspNetCore.Authentication;

await HttpContext.SignInAsync(
    CookieAuthenticationDefaults.AuthenticationScheme,
    new ClaimsPrincipal(claimsIdentity),
    new AuthenticationProperties
    {
        IsPersistent = true,
        ExpiresUtc = DateTime.UtcNow.AddMinutes(20)
    });

ASP.NET Core Identity é um provedor de autenticação completo para criar e manter acessos. No entanto, um provedor de autenticação com base em cookie sem ASP.NET Core Identity pode ser usado. Para obter mais informações, consulte Introdução ao Identity em ASP.NET Core.

Visualizar ou descarregar amostra de código (como descarregar)

Para fins de demonstração no aplicativo de exemplo, a conta de usuário para o usuário hipotético, Maria Rodriguez, é codificada no aplicativo. Use o endereço maria.rodriguez@contoso.com e qualquer senha para entrar no usuário. O utilizador é autenticado no método AuthenticateUser no arquivo Pages/Account/Login.cshtml.cs. Em um exemplo do mundo real, o usuário seria autenticado em um banco de dados.

Configuration

No método Startup.ConfigureServices, crie os serviços de 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 para o aplicativo. AuthenticationScheme é útil quando há várias instâncias de cookie autenticação e você deseja autorizar com um esquema específico. Definir o AuthenticationScheme para CookieAuthenticationDefaults.AuthenticationScheme fornece um valor de "Cookies" para o esquema. Você pode fornecer qualquer valor de cadeia de caracteres que distinga o esquema.

O esquema de autenticação do aplicativo é diferente do cookie esquema de autenticação do aplicativo. Quando um cookie esquema de autenticação não é fornecido ao AddCookie, ele usa CookieAuthenticationDefaults.AuthenticationScheme ("Cookies").

Por padrão, a propriedade cookie da autenticação IsEssential é definida como true. Os cookies de autenticação são permitidos quando um visitante do site não consentiu com a recolha de dados. Para obter mais informações, consulte Suporte do Regulamento Geral sobre a Proteção de Dados (RGPD) no ASP.NET Core.

No Startup.Configure, chame UseAuthentication e UseAuthorization para definir a propriedade HttpContext.User e execute o Middleware de Autorização para os pedidos. Chame UseAuthentication e os métodos UseAuthorization antes de chamar UseEndpoints:

A CookieAuthenticationOptions classe é usada para configurar as opções do provedor de autenticação.

Defina CookieAuthenticationOptions na configuração do serviço para autenticação no Startup.ConfigureServices método:

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(options =>
    {
        ...
    });

Cookie O Policy Middleware permite cookie recursos de política. Adicionar o middleware ao pipeline de processamento de aplicativos é sensível à ordem — afeta apenas os componentes downstream registrados no pipeline, e Cookie o Policy Middleware deve ser adicionado antes cookie do middleware de autenticação.

Use o CookiePolicyOptions fornecido ao Middleware de Política para controlar as Cookie características globais de processamento e integre-se com os manipuladores de processamento cookie ao anexar ou excluir cookies.

O valor padrão MinimumSameSitePolicy é SameSiteMode.Lax para permitir a autenticação OAuth2. Para aplicar estritamente uma política de mesmo domínio do SameSiteMode.Strict, defina o MinimumSameSitePolicy. Embora essa configuração quebre o OAuth2 e outros esquemas de autenticação entre origens, ela eleva o nível de segurança para outros tipos de aplicativos que não dependem do processamento de cookie solicitações entre origens.

O exemplo a seguir mostra como configurar cookie autenticação com Cookie Policy Middleware.

var cookiePolicyOptions = new CookiePolicyOptions
{
    MinimumSameSitePolicy = SameSiteMode.Strict,
};

app.UseCookiePolicy(cookiePolicyOptions);

A configuração de Middleware de Política em Cookie para MinimumSameSitePolicy pode afetar a configuração de Cookie.SameSite nas definições de CookieAuthenticationOptions de acordo com a matriz abaixo.

MínimoSameSitePolicy Cookie. SameSite Resultado Cookie. Configuração SameSite
SameSiteMode.Nenhum SameSiteMode.Nenhum
SameSiteMode.Lax
SameSiteMode.Strict
SameSiteMode.Nenhum
SameSiteMode.Lax
SameSiteMode.Strict
SameSiteMode.Lax SameSiteMode.Nenhum
SameSiteMode.Lax
SameSiteMode.Strict
SameSiteMode.Lax
SameSiteMode.Lax
SameSiteMode.Strict
SameSiteMode.Strict SameSiteMode.Nenhum
SameSiteMode.Lax
SameSiteMode.Strict
SameSiteMode.Strict
SameSiteMode.Strict
SameSiteMode.Strict

Para criar um cookie que contenha informações do usuário, crie um ClaimsPrincipal. As informações do usuário são serializadas e armazenadas no cookie.

Crie um ClaimsIdentity com todos os Claim necessários e chame SignInAsync para fazer login no utilizador.

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 quiser ver os comentários de código traduzidos para outros idiomas além do inglês, avise-nos nesta discussão do GitHub .

SignInAsync cria um criptografado cookie e o adiciona à 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 login e os caminhos de logout. Para obter mais informações, consulte a fonte CookieAuthenticationHandler.

O sistema de Proteção de Dados do ASP.NET Core é usado para criptografia. Para um aplicativo hospedado em várias máquinas, balanceamento de carga entre aplicativos ou usando uma web farm, configure a proteção de dados para usar o mesmo conjunto de chaves e identificador de aplicativo.

Terminar sessão

Para terminar a sessão do utilizador atual e eliminar o cookie, chame SignOutAsync:

await HttpContext.SignOutAsync(
    CookieAuthenticationDefaults.AuthenticationScheme);

Se CookieAuthenticationDefaults.AuthenticationScheme (valor padrão: "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 é usado. Por exemplo, se "ContosoCookie" for usado como o esquema, forneça o esquema usado ao configurar o provedor de autenticação.

Quando o navegador fecha, elimina automaticamente os cookies baseados na sessão (cookies não persistentes), mas nenhum cookie é apagado quando um separador individual é fechado. O servidor não é notificado de eventos de fechamento de guias ou navegadores.

Reaja a alterações no servidor

Uma vez que um cookie é criado, o cookie é a única fonte de identidade. Se uma conta de usuário estiver desativada em sistemas back-end:

  • O sistema de autenticação do cookie aplicativo continua a processar solicitações com base na autenticação cookie.
  • O usuário permanece conectado ao aplicativo enquanto a autenticação cookie for válida.

O ValidatePrincipal evento pode ser usado para intercetar e sobrepor a validação da cookie identidade. Validar o cookie em cada solicitação reduz o risco de usuários revogados acessarem o aplicativo.

Uma abordagem para a cookie validação baseia-se em manter o controle de quando o banco de dados de usuários muda. Se o banco de dados não tiver sido alterado desde que o credencial do usuário cookie foi emitido, não há necessidade de reautenticar o usuário se a credencial cookie ainda for válida. 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 LastChanged valor é definido para a hora atual.

Para invalidar um cookie quando o banco de dados for alterado com base no LastChanged valor, crie o cookie com uma LastChanged declaração contendo o valor atual LastChanged 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 ValidatePrincipal evento, escreva um método com a seguinte assinatura em uma classe que deriva de CookieAuthenticationEvents:

ValidatePrincipal(CookieValidatePrincipalContext)

Segue-se 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 cookie o registro do Startup.ConfigureServices serviço no método. Forneça um registo de serviço com escopo para a sua CustomCookieAuthenticationEvents classe.

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 usuário, chame context.ReplacePrincipal e defina a context.ShouldRenew propriedade como true.

Warning

A abordagem descrita aqui é acionada em cada solicitação. A validação de cookies de autenticação para todos os usuários em cada solicitação pode resultar em uma grande penalidade de desempenho para o aplicativo.

Cookies persistentes

Você pode querer que o cookie persista nas sessões do navegador. Esta persistência só deve ser ativada com o consentimento explícito do utilizador com uma caixa de verificação "Lembrar-me" no início de sessão ou um mecanismo semelhante.

O trecho de código a seguir cria uma identidade e o correspondente cookie que perdura durante os encerramentos do navegador. Todas as configurações de expiração deslizante configuradas anteriormente são respeitadas. Se o cookie expirar enquanto o navegador estiver fechado, o navegador limpará o cookie assim que for reiniciado.

Definir IsPersistent para true em AuthenticationProperties.

// using Microsoft.AspNetCore.Authentication;

await HttpContext.SignInAsync(
    CookieAuthenticationDefaults.AuthenticationScheme,
    new ClaimsPrincipal(claimsIdentity),
    new AuthenticationProperties
    {
        IsPersistent = true
    });

Um tempo de expiração absoluto pode ser definido com ExpiresUtc. Para criar um persistente cookie, IsPersistent também deve ser definido. Caso contrário, o cookie é criado com um tempo de vida baseado em sessão e pode expirar antes ou depois do tíquete de autenticação que ele mantém. Quando ExpiresUtc é definido, ele sobrepõe o valor da opção ExpireTimeSpan de CookieAuthenticationOptions, se definido.

O trecho de código a seguir cria uma identidade e correspondente cookie que dura 20 minutos. Isso ignora todas as configurações de expiração deslizante configuradas anteriormente.

// using Microsoft.AspNetCore.Authentication;

await HttpContext.SignInAsync(
    CookieAuthenticationDefaults.AuthenticationScheme,
    new ClaimsPrincipal(claimsIdentity),
    new AuthenticationProperties
    {
        IsPersistent = true,
        ExpiresUtc = DateTime.UtcNow.AddMinutes(20)
    });