Condividi tramite


Condividere i cookie di autenticazione tra le app ASP.NET

Di Rick Anderson

I siti Web sono spesso costituiti da singole app Web che interagiscono. Per offrire un'esperienza Single Sign-On (SSO), le app Web all'interno di un sito devono condividere i cookie di autenticazione. Per supportare questo scenario, lo stack di protezione dei dati consente di condividere l'autenticazione Katana cookie e ASP.NET ticket di autenticazione core cookie .

Negli esempi seguenti:

  • Il nome dell'autenticazione cookie è impostato su un valore comune di .AspNet.SharedCookie.
  • l'oggetto AuthenticationType è impostato su Identity.Application in modo esplicito o per impostazione predefinita.
  • Un nome di app comune, SharedCookieApp, viene usato per consentire al sistema di protezione dei dati di condividere le chiavi di protezione dei dati.
  • Identity.Application viene usato come schema di autenticazione. Qualsiasi schema venga usato, deve essere usato in modo coerente all'interno e tra le app condivise cookie come schema predefinito o impostandolo in modo esplicito. Lo schema viene usato per crittografare e decrittografare i cookie, quindi è necessario usare uno schema coerente tra le app.
  • Viene usata una posizione comune di archiviazione delle chiavi di protezione dei dati.
  • DataProtectionProvider richiede il pacchetto NuGet Microsoft.AspNetCore.DataProtection.Extensions :
  • SetApplicationName imposta il nome dell'app comune.

Condividere i cookie di autenticazione con ASP.NET Core Identity

Quando si usa ASP.NET Core Identity:

  • Le chiavi di protezione dei dati e il nome dell'app devono essere condivisi tra le app. Un percorso di archiviazione delle chiavi comune viene fornito al PersistKeysToFileSystem metodo negli esempi seguenti. Usare SetApplicationName per configurare un nome comune di app condivisa (SharedCookieApp negli esempi seguenti). Per altre informazioni, vedere Configurare ASP.NET Protezione dati di base.
  • Usare il ConfigureApplicationCookie metodo di estensione per configurare il servizio di protezione dei dati per i cookie.
  • Il tipo di autenticazione predefinito è Identity.Application.

In Program.cs:

using Microsoft.AspNetCore.DataProtection;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.AddDataProtection()
    .PersistKeysToFileSystem(new DirectoryInfo(@"c:\PATH TO COMMON KEY RING FOLDER"))
    .SetApplicationName("SharedCookieApp");

builder.Services.ConfigureApplicationCookie(options => {
    options.Cookie.Name = ".AspNet.SharedCookie";
});

var app = builder.Build();

Nota: le istruzioni precedenti non funzionano con ITicketStore (CookieAuthenticationOptions.SessionStore). Per altre informazioni, vedere questo problema in GitHub.

Per motivi di sicurezza, i cookie di autenticazione non vengono compressi in ASP.NET Core. Quando si usano i cookie di autenticazione, gli sviluppatori devono ridurre al minimo il numero di informazioni sull'attestazione incluse in quanto necessarie per le proprie esigenze.

Condividere i cookie di autenticazione senza ASP.NET Core Identity

Quando si usano i cookie direttamente senza ASP.NET Core Identity, configurare la protezione e l'autenticazione dei dati. Nell'esempio seguente il tipo di autenticazione è impostato su Identity.Application:

using Microsoft.AspNetCore.DataProtection;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.AddDataProtection()
    .PersistKeysToFileSystem(new DirectoryInfo(@"c:\PATH TO COMMON KEY RING FOLDER"))
    .SetApplicationName("SharedCookieApp");

builder.Services.AddAuthentication("Identity.Application")
    .AddCookie("Identity.Application", options =>
    {
        options.Cookie.Name = ".AspNet.SharedCookie";
    });

var app = builder.Build();

Per motivi di sicurezza, i cookie di autenticazione non vengono compressi in ASP.NET Core. Quando si usano i cookie di autenticazione, gli sviluppatori devono ridurre al minimo il numero di informazioni sull'attestazione incluse in quanto necessarie per le proprie esigenze.

Condividere i cookie tra percorsi di base diversi

Un'autenticazione cookie usa HttpRequest.PathBase come predefinitoCookie. Percorso. Se l'app deve essere condivisa tra percorsi di base diversi, Path è necessario eseguire l'overridecookie:

using Microsoft.AspNetCore.DataProtection;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.AddDataProtection()
    .PersistKeysToFileSystem(new DirectoryInfo(@"c:\PATH TO COMMON KEY RING FOLDER"))
    .SetApplicationName("SharedCookieApp");

builder.Services.ConfigureApplicationCookie(options => {
    options.Cookie.Name = ".AspNet.SharedCookie";
    options.Cookie.Path = "/";
});

var app = builder.Build();

Condividere i cookie tra sottodomini

Quando si ospitano app che condividono cookie tra sottodomini, specificare un dominio comune in Cookie. Proprietà di dominio . Per condividere i cookie tra le app in contoso.com, ad esempio first_subdomain.contoso.com e second_subdomain.contoso.com, specificare come Cookie.Domain .contoso.com:

options.Cookie.Domain = ".contoso.com";

Crittografare le chiavi di protezione dei dati in rest

Per le distribuzioni di produzione, configurare per DataProtectionProvider crittografare le chiavi in rest con DPAPI o X509Certificate. Per altre informazioni, vedere Crittografia delle chiavi in rest Windows e Azure con ASP.NET Core. Nell'esempio seguente viene fornita un'identificazione personale del certificato a ProtectKeysWithCertificate:

using Microsoft.AspNetCore.DataProtection;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.AddDataProtection()
    .ProtectKeysWithCertificate("{CERTIFICATE THUMBPRINT}");

Usare un database utente comune

Quando le app usano lo stesso Identity schema (stessa versione di Identity), verificare che il Identity sistema per ogni app punti allo stesso database utente. In caso contrario, il identity sistema genera errori in fase di esecuzione quando tenta di trovare una corrispondenza con le informazioni nell'autenticazione cookie rispetto alle informazioni nel relativo database.

Quando lo Identity schema è diverso tra le app, in genere perché le app usano versioni diverse Identity , la condivisione di un database comune basato sulla versione più recente di Identity non è possibile senza eseguire il mapping e l'aggiunta di colonne negli schemi di Identity altre app. Spesso è più efficiente aggiornare le altre app per usare la versione più recente Identity in modo che un database comune possa essere condiviso dalle app.

Modifica del nome dell'applicazione

In .NET 6 WebApplicationBuilder normalizza il percorso radice del contenuto per terminare con un oggetto DirectorySeparatorChar. La maggior parte delle app che eseguono la migrazione da HostBuilder o WebHostBuilder non avrà lo stesso nome dell'app perché non sono normalizzate. Per altre informazioni, vedere SetApplicationName

Condividere i cookie di autenticazione tra app ASP.NET 4.x e ASP.NET Core

ASP.NET app 4.x che usano il middleware di autenticazione Microsoft.Owin Cookie possono essere configurate per generare cookie di autenticazione compatibili con il middleware di autenticazione principale ASP.NET Cookie . Ciò può essere utile se un'applicazione Web è costituita sia da app ASP.NET 4.x che da app ASP.NET Core che devono condividere un'esperienza single sign-on. Un esempio specifico di questo scenario è la migrazione incrementale di un'app Web da ASP.NET a ASP.NET Core. In questi scenari, è comune che alcune parti di un'app vengano gestite dall'app ASP.NET originale, mentre altre vengono gestite dalla nuova app ASP.NET Core. Tuttavia, gli utenti devono eseguire l'accesso una sola volta. Questa operazione può essere eseguita con uno degli approcci seguenti:

  • Uso della funzionalità di autenticazione remota degli adapter System.Web, che usa l'app ASP.NET per consentire agli utenti di accedere.
  • Configurazione dell'app ASP.NET per l'uso del middleware di autenticazione Microsoft.Owin Cookie in modo che i cookie di autenticazione vengano condivisi con l'app ASP.NET Core.

Per configurare ASP.NET middleware di autenticazione Microsoft.Owin Cookie per condividere i cookie con un'app ASP.NET Core, seguire le istruzioni precedenti per configurare l'app ASP.NET Core per usare un nome specifico, un cookie nome dell'app e per rendere persistenti le chiavi di protezione dei dati in una posizione nota. Per altre informazioni sulla persistenza delle chiavi di protezione dei dati, vedere Configurare ASP.NET Core Data Protection .

Nell'app ASP.NET installare il Microsoft.Owin.Security.Interop pacchetto.

Aggiornare la UseCookieAuthentication chiamata in Startup.Auth.cs per configurare aspNetTicketDataFormat in modo che corrisponda alle impostazioni dell'app ASP.NET Core:

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    LoginPath = new PathString("/Account/Login"),
    Provider = new CookieAuthenticationProvider
    { 
        OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
            validateInterval: TimeSpan.FromMinutes(30),
            regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
    },

    // Settings to configure shared cookie with ASP.NET Core app
    CookieName = ".AspNet.ApplicationCookie",
    AuthenticationType = "Identity.Application",                
    TicketDataFormat = new AspNetTicketDataFormat(
        new DataProtectorShim(
            DataProtectionProvider.Create(new DirectoryInfo(@"c:\PATH TO COMMON KEY RING FOLDER"),
            builder => builder.SetApplicationName("SharedCookieApp"))
            .CreateProtector(
                "Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware",
                // Must match the Scheme name used in the ASP.NET Core app, i.e. IdentityConstants.ApplicationScheme
                "Identity.Application",
                "v2"))),
    CookieManager = new ChunkingCookieManager()
});

Gli elementi importanti configurati includono:

  • Il cookie nome è impostato sullo stesso nome dell'app ASP.NET Core.
  • Un provider di protezione dati viene creato usando lo stesso percorso dell'anello di chiave. Si noti che in questi esempi le chiavi di protezione dei dati vengono archiviate su disco, ma è possibile usare altri provider di protezione dei dati. Ad esempio, Redis o Archiviazione BLOB di Azure può essere usato per i provider di protezione dei dati, purché la configurazione corrisponda tra le app. Per altre informazioni sulla persistenza delle chiavi di protezione dei dati, vedere Configurare ASP.NET Core Data Protection .
  • Il nome dell'app è impostato come il nome dell'app usato nell'app ASP.NET Core.
  • Il tipo di autenticazione è impostato sul nome dello schema di autenticazione nell'app ASP.NET Core.
  • System.Web.Helpers.AntiForgeryConfig.UniqueClaimTypeIdentifier è impostato su un'attestazione da ASP.NET Core identity che sarà univoca per un utente.

Poiché il tipo di autenticazione è stato modificato in modo che corrisponda allo schema di autenticazione dell'app ASP.NET Core, è anche necessario aggiornare il modo in cui l'app ASP.NET genera nuove identità per usare lo stesso nome. Questa operazione viene in genere eseguita in Models/IdentityModels.cs:

public class ApplicationUser : IdentityUser
{
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
    {
        // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
        var userIdentity = await manager.CreateIdentityAsync(this, "Identity.Application");
        
        // Add custom user claims here
        return userIdentity;
    }
}

Con queste modifiche, le app ASP.NET e ASP.NET Core possono usare gli stessi cookie di autenticazione in modo che gli utenti che eseguono l'accesso o l'uscita da un'app si riflettano nell'altra app.

Si noti che poiché esistono differenze tra gli schemi di database di ASP.NET Identity e ASP.NET CoreIdentity, è consigliabile che gli utenti eseseguono l'accesso solo usando una delle app, ovvero l'app ASP.NET o ASP.NET Core. Dopo l'accesso degli utenti, la procedura descritta in questa sezione consentirà di usare l'autenticazione cookie da entrambe le app e entrambe le app dovrebbero essere in grado di disconnettere gli utenti.

Risorse aggiuntive

Negli esempi seguenti:

  • Il nome dell'autenticazione cookie è impostato su un valore comune di .AspNet.SharedCookie.
  • l'oggetto AuthenticationType è impostato su Identity.Application in modo esplicito o per impostazione predefinita.
  • Un nome di app comune viene usato per consentire al sistema di protezione dei dati di condividere le chiavi di protezione dei dati (SharedCookieApp).
  • Identity.Application viene usato come schema di autenticazione. Qualsiasi schema venga usato, deve essere usato in modo coerente all'interno e tra le app condivise cookie come schema predefinito o impostandolo in modo esplicito. Lo schema viene usato per crittografare e decrittografare i cookie, quindi è necessario usare uno schema coerente tra le app.
  • Viene usata una posizione comune di archiviazione delle chiavi di protezione dei dati.
  • DataProtectionProvider richiede il pacchetto NuGet Microsoft.AspNetCore.DataProtection.Extensions :
  • SetApplicationName imposta il nome dell'app comune.

Condividere i cookie di autenticazione con ASP.NET Core Identity

Quando si usa ASP.NET Core Identity:

  • Le chiavi di protezione dei dati e il nome dell'app devono essere condivisi tra le app. Un percorso di archiviazione delle chiavi comune viene fornito al PersistKeysToFileSystem metodo negli esempi seguenti. Usare SetApplicationName per configurare un nome comune di app condivisa (SharedCookieApp negli esempi seguenti). Per altre informazioni, vedere Configurare ASP.NET Protezione dati di base.
  • Usare il ConfigureApplicationCookie metodo di estensione per configurare il servizio di protezione dei dati per i cookie.
  • Il tipo di autenticazione predefinito è Identity.Application.

In Startup.ConfigureServices:

services.AddDataProtection()
    .PersistKeysToFileSystem("{PATH TO COMMON KEY RING FOLDER}")
    .SetApplicationName("SharedCookieApp");

services.ConfigureApplicationCookie(options => {
    options.Cookie.Name = ".AspNet.SharedCookie";
});

Nota: le istruzioni precedenti non funzionano con ITicketStore (CookieAuthenticationOptions.SessionStore). Per altre informazioni, vedere questo problema in GitHub.

Per motivi di sicurezza, i cookie di autenticazione non vengono compressi in ASP.NET Core. Quando si usano i cookie di autenticazione, gli sviluppatori devono ridurre al minimo il numero di informazioni sull'attestazione incluse in quanto necessarie per le proprie esigenze.

Condividere i cookie di autenticazione senza ASP.NET Core Identity

Quando si usano i cookie direttamente senza ASP.NET Core Identity, configurare la protezione dei dati e l'autenticazione in Startup.ConfigureServices. Nell'esempio seguente il tipo di autenticazione è impostato su Identity.Application:

services.AddDataProtection()
    .PersistKeysToFileSystem("{PATH TO COMMON KEY RING FOLDER}")
    .SetApplicationName("SharedCookieApp");

services.AddAuthentication("Identity.Application")
    .AddCookie("Identity.Application", options =>
    {
        options.Cookie.Name = ".AspNet.SharedCookie";
    });

Per motivi di sicurezza, i cookie di autenticazione non vengono compressi in ASP.NET Core. Quando si usano i cookie di autenticazione, gli sviluppatori devono ridurre al minimo il numero di informazioni sull'attestazione incluse in quanto necessarie per le proprie esigenze.

Condividere i cookie tra percorsi di base diversi

Un'autenticazione cookie usa HttpRequest.PathBase come predefinitoCookie. Percorso. Se l'app deve essere condivisa tra percorsi di base diversi, Path è necessario eseguire l'overridecookie:

services.AddDataProtection()
    .PersistKeysToFileSystem("{PATH TO COMMON KEY RING FOLDER}")
    .SetApplicationName("SharedCookieApp");

services.ConfigureApplicationCookie(options => {
    options.Cookie.Name = ".AspNet.SharedCookie";
    options.Cookie.Path = "/";
});

Condividere i cookie tra sottodomini

Quando si ospitano app che condividono cookie tra sottodomini, specificare un dominio comune in Cookie. Proprietà di dominio . Per condividere i cookie tra le app in contoso.com, ad esempio first_subdomain.contoso.com e second_subdomain.contoso.com, specificare come Cookie.Domain .contoso.com:

options.Cookie.Domain = ".contoso.com";

Crittografare le chiavi di protezione dei dati in rest

Per le distribuzioni di produzione, configurare per DataProtectionProvider crittografare le chiavi in rest con DPAPI o X509Certificate. Per altre informazioni, vedere Crittografia delle chiavi in rest Windows e Azure con ASP.NET Core. Nell'esempio seguente viene fornita un'identificazione personale del certificato a ProtectKeysWithCertificate:

services.AddDataProtection()
    .ProtectKeysWithCertificate("{CERTIFICATE THUMBPRINT}");

Condividere i cookie di autenticazione tra app ASP.NET 4.x e ASP.NET Core

ASP.NET le app 4.x che usano il middleware di autenticazione Katana Cookie possono essere configurate per generare cookie di autenticazione compatibili con il middleware di autenticazione principale ASP.NET Cookie . Per altre informazioni, vedere Condividere i cookie di autenticazione tra ASP.NET 4.x e ASP.NET app Core (dotnet/AspNetCore.Docs #21987)..

Usare un database utente comune

Quando le app usano lo stesso Identity schema (stessa versione di Identity), verificare che il Identity sistema per ogni app punti allo stesso database utente. In caso contrario, il identity sistema genera errori in fase di esecuzione quando tenta di trovare una corrispondenza con le informazioni nell'autenticazione cookie rispetto alle informazioni nel relativo database.

Quando lo Identity schema è diverso tra le app, in genere perché le app usano versioni diverse Identity , la condivisione di un database comune basato sulla versione più recente di Identity non è possibile senza eseguire il mapping e l'aggiunta di colonne negli schemi di Identity altre app. Spesso è più efficiente aggiornare le altre app per usare la versione più recente Identity in modo che un database comune possa essere condiviso dalle app.

Risorse aggiuntive