Condividi tramite


Usare cookie l'autenticazione senza ASP.NET Core Identity

Di Rick Anderson

ASP.NET Core Identity è un provider di autenticazione completo completo per la creazione e la gestione degli account di accesso. Tuttavia, è possibile usare un cookieprovider di autenticazione basato su -senza ASP.NET Core Identity . Per altre informazioni, vedere Introduzione a Identity in ASP.NET Core.

Visualizzare o scaricare il codice di esempio (procedura per il download)

A scopo dimostrativo nell'app di esempio, l'account utente per l'utente ipotetico Maria Rodriguez è hardcoded nell'app. Usare l'indirizzo maria.rodriguez@contoso.com di posta elettronica e qualsiasi password per accedere all'utente. L'utente viene autenticato nel AuthenticateUser metodo nel Pages/Account/Login.cshtml.cs file. In un esempio reale, l'utente verrà autenticato in un archivio dati.

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 passato a AddAuthentication imposta lo schema di autenticazione predefinito per l'app. AuthenticationScheme è utile quando sono presenti più istanze di cookie autenticazione e l'app deve autorizzare con uno schema specifico. L'impostazione di su AuthenticationScheme CookieAuthenticationDefaults.AuthenticationScheme fornisce il valore per "Cookies" lo schema. È possibile usare qualsiasi valore stringa che distingue lo schema.

Lo schema di autenticazione dell'app è diverso dallo schema di autenticazione dell'app cookie . Quando uno cookie schema di autenticazione non viene fornito a AddCookie, usa CookieAuthenticationDefaults.AuthenticationScheme. L'origine CookieAuthenticationDefaults.AuthenticationScheme GitHub mostra che è impostato su "Cookies".

La proprietà dell'autenticazione cookieIsEssential è impostata su per true impostazione predefinita. I cookie di autenticazione sono consentiti quando un visitatore del sito non ha acconsentito alla raccolta dati. Per altre informazioni, vedere il supporto per il Regolamento generale sulla protezione dei dati in ASP.NET Core.

La CookieAuthenticationOptions classe viene usata per configurare le opzioni del provider di autenticazione.

Configurare CookieAuthenticationOptions nel AddCookie metodo :

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

Il Cookie middleware dei criteri (origine GitHub) UseCookiePolicy abilita cookie le funzionalità dei criteri. Il middleware viene elaborato nell'ordine in cui viene aggiunto:

app.UseCookiePolicy(cookiePolicyOptions);

Usare CookiePolicyOptions il Cookie middleware dei criteri per controllare le caratteristiche globali di elaborazione e hook nei cookie gestori di cookie elaborazione quando i cookie vengono aggiunti o eliminati.

Il valore predefinito MinimumSameSitePolicy consiste SameSiteMode.Lax nel consentire l'autenticazione OAuth2. Per applicare rigorosamente un criterio dello stesso sito di SameSiteMode.Strict, impostare .MinimumSameSitePolicy Anche se questa impostazione interrompe OAuth2 e altri schemi di autenticazione tra origini, eleva il livello di cookie sicurezza per altri tipi di app che non si basano sull'elaborazione delle richieste tra le origini.

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

L'impostazione Cookie del middleware dei criteri per MinimumSameSitePolicy può influire sull'impostazione di Cookie.SameSite nelle CookieAuthenticationOptions impostazioni in base alla matrice seguente.

MinimumSameSitePolicy Cookie. SameSite Risultante Cookie. Impostazione 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

Per creare un oggetto contenente cookie le informazioni utente, creare un oggetto ClaimsPrincipal. Le informazioni utente vengono serializzate e archiviate cookiein .

Creare un ClaimsIdentity oggetto con qualsiasi s necessario Claime chiamare SignInAsync per accedere all'utente. Login.cshtml.cs nell'app di esempio contiene il codice seguente:

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

Per visualizzare i commenti del codice tradotti in lingue diverse dall'inglese, segnalarlo in questo problema di discussione su GitHub.

SignInAsync crea un oggetto crittografato cookie e lo aggiunge alla risposta corrente. Se AuthenticationScheme non viene specificato, viene usato lo schema predefinito.

RedirectUri viene usato solo in alcuni percorsi specifici per impostazione predefinita, ad esempio il percorso di accesso e i percorsi di disconnessione. Per altre informazioni, vedere l'origine CookieAuthenticationHandler.

ASP.NET core viene usato il sistema di protezione dei dati di ASP.NET per la crittografia. Per un'app ospitata in più computer, il bilanciamento del carico tra app o una Web farm, configurare la protezione dei dati in modo da usare lo stesso anello di chiave e l'identificatore dell'app.

Disconnettersi

Per disconnettere l'utente corrente ed eliminarlo cookie, chiamare 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 o "Cookies" non viene usato come schema, specificare lo schema usato durante la configurazione del provider di autenticazione. In caso contrario, viene usato lo schema predefinito. Ad esempio, se "ContosoCookie" viene usato come schema, specificare lo schema usato durante la configurazione del provider di autenticazione.

Quando il browser lo chiude, elimina automaticamente i cookie basati su sessione (cookie non persistenti), ma nessun cookie viene cancellato quando viene chiusa una singola scheda. Il server non riceve una notifica degli eventi di chiusura della scheda o del browser.

Reagire alle modifiche back-end

Dopo aver creato un oggetto cookie , cookie è l'unica origine di identity. Se un account utente è disabilitato nei sistemi back-end:

  • Il sistema di autenticazione dell'app cookie continua a elaborare le richieste in base all'autenticazione cookie.
  • L'utente rimane connesso all'app purché l'autenticazione cookie sia valida.

L'evento ValidatePrincipal può essere usato per intercettare ed eseguire l'override cookieidentitydella convalida di . La convalida di cookie in ogni richiesta riduce il rischio che gli utenti revocati accedano all'app.

Un approccio alla cookie convalida si basa su come tenere traccia delle modifiche apportate al database utente. Se il database non è stato modificato dopo l'emissione dell'utente cookie , non è necessario ripetere l'autenticazione dell'utente se cookie è ancora valido. Nell'app di esempio il database viene implementato in IUserRepository e archivia un LastChanged valore. Quando un utente viene aggiornato nel database, il LastChanged valore viene impostato sull'ora corrente.

Per invalidare un oggetto cookie quando il database cambia in base al LastChanged valore, creare con un'attestazione cookie LastChanged contenente il valore corrente LastChanged dal database:

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

Per implementare un override per l'evento ValidatePrincipal , scrivere un metodo con la firma seguente in una classe che deriva da CookieAuthenticationEvents:

ValidatePrincipal(CookieValidatePrincipalContext)

Di seguito è riportato un esempio di implementazione di 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);
        }
    }
}

Registrare l'istanza degli eventi durante cookie la registrazione del servizio. Fornire una registrazione del servizio con ambito per la 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();

Si consideri una situazione in cui il nome dell'utente viene aggiornato, ovvero una decisione che non influisce sulla sicurezza in alcun modo. Se si desidera aggiornare in modo non distruttivo l'entità utente, chiamare context.ReplacePrincipal e impostare la context.ShouldRenew proprietà su true.

Avviso

L'approccio descritto di seguito viene attivato in ogni richiesta. La convalida dei cookie di autenticazione per tutti gli utenti su ogni richiesta può comportare una notevole riduzione delle prestazioni per l'app.

Cookie permanenti

Potrebbe essere necessario rendere persistente l'oggetto cookie tra le sessioni del browser. Questa persistenza deve essere abilitata solo con il consenso esplicito dell'utente con una casella di controllo "Memorizzami" all'accesso o a un meccanismo simile.

Il frammento di codice seguente crea un oggetto identity e corrispondente cookie che sopravvive tramite le chiusura del browser. Tutte le impostazioni di scadenza scorrevoli configurate in precedenza vengono rispettate. Se scade cookie mentre il browser è chiuso, il browser cancella l'oggetto cookie dopo il riavvio.

Impostare IsPersistent su true in AuthenticationProperties:

// using Microsoft.AspNetCore.Authentication;

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

È possibile impostare una scadenza assoluta con ExpiresUtc. Per creare un oggetto permanente cookie, IsPersistent è necessario impostare anche . In caso contrario, viene cookie creato con una durata basata su sessione e può scadere prima o dopo il ticket di autenticazione che contiene. Quando ExpiresUtc è impostata, esegue l'override del valore dell'opzione ExpireTimeSpan di CookieAuthenticationOptions, se impostata.

Il frammento di codice seguente crea un oggetto identity e corrispondente cookie che dura 20 minuti. In questo modo vengono ignorate le impostazioni di scadenza scorrevoli configurate in precedenza.

// 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 è un provider di autenticazione completo completo per la creazione e la gestione degli account di accesso. Tuttavia, è possibile usare un cookieprovider di autenticazione basato su -senza ASP.NET Core Identity . Per altre informazioni, vedere Introduzione a Identity in ASP.NET Core.

Visualizzare o scaricare il codice di esempio (procedura per il download)

A scopo dimostrativo nell'app di esempio, l'account utente per l'utente ipotetico Maria Rodriguez è hardcoded nell'app. Usare l'indirizzo maria.rodriguez@contoso.com di posta elettronica e qualsiasi password per accedere all'utente. L'utente viene autenticato nel AuthenticateUser metodo nel Pages/Account/Login.cshtml.cs file. In un esempio reale, l'utente verrà autenticato su un database.

Impostazione

Startup.ConfigureServices Nel metodo creare i servizi middleware di autenticazione con i AddAuthentication metodi e AddCookie :

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie();

AuthenticationScheme passato a AddAuthentication imposta lo schema di autenticazione predefinito per l'app. AuthenticationScheme è utile quando sono presenti più istanze di cookie autenticazione e si vuole autorizzare con uno schema specifico. L'impostazione di su AuthenticationScheme CookieAuthenticationDefaults.AuthenticationScheme fornisce il valore "Cookies" per lo schema. È possibile specificare qualsiasi valore stringa che distingue lo schema.

Lo schema di autenticazione dell'app è diverso dallo schema di autenticazione dell'app cookie . cookie Quando uno schema di autenticazione non viene fornito a AddCookie, usa CookieAuthenticationDefaults.AuthenticationScheme ("Cookie").

La proprietà dell'autenticazione cookieIsEssential è impostata su per true impostazione predefinita. I cookie di autenticazione sono consentiti quando un visitatore del sito non ha acconsentito alla raccolta dati. Per altre informazioni, vedere il supporto per il Regolamento generale sulla protezione dei dati in ASP.NET Core.

In Startup.Configurechiamare UseAuthentication e UseAuthorization per impostare la HttpContext.User proprietà ed eseguire il middleware di autorizzazione per le richieste. Chiamare i UseAuthentication metodi e UseAuthorization prima di chiamare UseEndpoints:

app.UseAuthentication();
app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
    endpoints.MapRazorPages();
});

La CookieAuthenticationOptions classe viene usata per configurare le opzioni del provider di autenticazione.

Impostare CookieAuthenticationOptions nella configurazione del servizio per l'autenticazione nel Startup.ConfigureServices metodo :

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

Cookie Il middleware dei criteri abilita cookie le funzionalità dei criteri. L'aggiunta del middleware alla pipeline di elaborazione dell'app è sensibile all'ordine, ma influisce solo sui componenti downstream registrati nella pipeline.

app.UseCookiePolicy(cookiePolicyOptions);

Usare CookiePolicyOptions il Cookie middleware dei criteri per controllare le caratteristiche globali di elaborazione e hook nei cookie gestori di cookie elaborazione quando i cookie vengono aggiunti o eliminati.

Il valore predefinito MinimumSameSitePolicy consiste SameSiteMode.Lax nel consentire l'autenticazione OAuth2. Per applicare rigorosamente un criterio dello stesso sito di SameSiteMode.Strict, impostare .MinimumSameSitePolicy Anche se questa impostazione interrompe OAuth2 e altri schemi di autenticazione tra origini, eleva il livello di cookie sicurezza per altri tipi di app che non si basano sull'elaborazione delle richieste tra le origini.

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

L'impostazione Cookie del middleware dei criteri per MinimumSameSitePolicy può influire sull'impostazione di Cookie.SameSite nelle CookieAuthenticationOptions impostazioni in base alla matrice seguente.

MinimumSameSitePolicy Cookie. SameSite Risultante Cookie. Impostazione 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

Per creare un oggetto contenente cookie le informazioni utente, creare un oggetto ClaimsPrincipal. Le informazioni utente vengono serializzate e archiviate cookiein .

Creare un ClaimsIdentity oggetto con qualsiasi s necessario Claime chiamare SignInAsync per accedere all'utente:

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

Per visualizzare i commenti del codice tradotti in lingue diverse dall'inglese, segnalarlo in questo problema di discussione su GitHub.

SignInAsync crea un oggetto crittografato cookie e lo aggiunge alla risposta corrente. Se AuthenticationScheme non viene specificato, viene usato lo schema predefinito.

RedirectUri viene usato solo in alcuni percorsi specifici per impostazione predefinita, ad esempio il percorso di accesso e i percorsi di disconnessione. Per altre informazioni, vedere l'origine CookieAuthenticationHandler.

ASP.NET core viene usato il sistema di protezione dei dati di ASP.NET per la crittografia. Per un'app ospitata in più computer, il bilanciamento del carico tra app o una Web farm, configurare la protezione dei dati in modo da usare lo stesso anello di chiave e l'identificatore dell'app.

Disconnettersi

Per disconnettere l'utente corrente ed eliminarlo cookie, chiamare SignOutAsync:

await HttpContext.SignOutAsync(
    CookieAuthenticationDefaults.AuthenticationScheme);

Se CookieAuthenticationDefaults.AuthenticationScheme (o "Cookie") non viene usato come schema (ad esempio, "ContosoCookie"), specificare lo schema usato durante la configurazione del provider di autenticazione. In caso contrario, viene usato lo schema predefinito.

Quando il browser lo chiude, elimina automaticamente i cookie basati su sessione (cookie non persistenti), ma nessun cookie viene cancellato quando viene chiusa una singola scheda. Il server non riceve una notifica degli eventi di chiusura della scheda o del browser.

Reagire alle modifiche back-end

Dopo aver creato un oggetto cookie , cookie è l'unica origine di identity. Se un account utente è disabilitato nei sistemi back-end:

  • Il sistema di autenticazione dell'app cookie continua a elaborare le richieste in base all'autenticazione cookie.
  • L'utente rimane connesso all'app purché l'autenticazione cookie sia valida.

L'evento ValidatePrincipal può essere usato per intercettare ed eseguire l'override cookieidentitydella convalida di . La convalida di cookie in ogni richiesta riduce il rischio che gli utenti revocati accedano all'app.

Un approccio alla cookie convalida si basa su come tenere traccia delle modifiche apportate al database utente. Se il database non è stato modificato dopo l'emissione dell'utente cookie , non è necessario ripetere l'autenticazione dell'utente se cookie è ancora valido. Nell'app di esempio il database viene implementato in IUserRepository e archivia un LastChanged valore. Quando un utente viene aggiornato nel database, il LastChanged valore viene impostato sull'ora corrente.

Per invalidare un oggetto cookie quando il database cambia in base al LastChanged valore, creare con un'attestazione cookie LastChanged contenente il valore corrente LastChanged dal database:

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

Per implementare un override per l'evento ValidatePrincipal , scrivere un metodo con la firma seguente in una classe che deriva da CookieAuthenticationEvents:

ValidatePrincipal(CookieValidatePrincipalContext)

Di seguito è riportato un esempio di implementazione di 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);
        }
    }
}

Registrare l'istanza degli eventi durante cookie la registrazione del Startup.ConfigureServices servizio nel metodo . Fornire una registrazione del servizio con ambito per la CustomCookieAuthenticationEvents classe:

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

services.AddScoped<CustomCookieAuthenticationEvents>();

Si consideri una situazione in cui il nome dell'utente viene aggiornato, ovvero una decisione che non influisce sulla sicurezza in alcun modo. Se si desidera aggiornare in modo non distruttivo l'entità utente, chiamare context.ReplacePrincipal e impostare la context.ShouldRenew proprietà su true.

Avviso

L'approccio descritto di seguito viene attivato in ogni richiesta. La convalida dei cookie di autenticazione per tutti gli utenti su ogni richiesta può comportare una notevole riduzione delle prestazioni per l'app.

Cookie permanenti

Potrebbe essere necessario rendere persistente l'oggetto cookie tra le sessioni del browser. Questa persistenza deve essere abilitata solo con il consenso esplicito dell'utente con una casella di controllo "Memorizzami" all'accesso o a un meccanismo simile.

Il frammento di codice seguente crea un oggetto identity e corrispondente cookie che sopravvive tramite le chiusura del browser. Tutte le impostazioni di scadenza scorrevoli configurate in precedenza vengono rispettate. Se scade cookie mentre il browser è chiuso, il browser cancella l'oggetto cookie dopo il riavvio.

Impostare IsPersistent su true in AuthenticationProperties:

// using Microsoft.AspNetCore.Authentication;

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

È possibile impostare una scadenza assoluta con ExpiresUtc. Per creare un oggetto permanente cookie, IsPersistent è necessario impostare anche . In caso contrario, viene cookie creato con una durata basata su sessione e può scadere prima o dopo il ticket di autenticazione che contiene. Quando ExpiresUtc è impostata, esegue l'override del valore dell'opzione ExpireTimeSpan di CookieAuthenticationOptions, se impostata.

Il frammento di codice seguente crea un oggetto identity e corrispondente cookie che dura 20 minuti. In questo modo vengono ignorate le impostazioni di scadenza scorrevoli configurate in precedenza.

// using Microsoft.AspNetCore.Authentication;

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