Delen via


Verificatiecookies delen tussen ASP.NET apps

Door Rick Anderson

Websites bestaan vaak uit afzonderlijke web-apps die samenwerken. Om eenmalige aanmelding (SSO) te bieden, moeten web-apps binnen een site verificatiecookies delen. Ter ondersteuning van dit scenario maakt de gegevensbeveiligingsstack het delen van Katana-verificatie cookie en ASP.NET Core-verificatietickets cookie mogelijk.

In de volgende voorbeelden:

  • De verificatienaam cookie wordt ingesteld op een gemeenschappelijke waarde van .AspNet.SharedCookie.
  • De AuthenticationType is ingesteld op Identity.Application expliciet of standaard.
  • Een algemene app-naam, SharedCookieAppwordt gebruikt om het gegevensbeveiligingssysteem in staat te stellen sleutels voor gegevensbeveiliging te delen.
  • Identity.Application wordt gebruikt als verificatieschema. Welk schema ook wordt gebruikt, het moet consistent in en tussen de gedeelde cookie apps worden gebruikt als het standaardschema of door het expliciet in te stellen. Het schema wordt gebruikt bij het versleutelen en ontsleutelen van cookies, dus een consistent schema moet worden gebruikt in alle apps.
  • Er wordt een algemene opslaglocatie voor gegevensbeveiligingssleutels gebruikt.
  • DataProtectionProvider vereist het NuGet-pakket Microsoft.AspNetCore.DataProtection.Extensions :
  • SetApplicationName hiermee stelt u de algemene app-naam in.

Verificatiecookies delen met ASP.NET Core Identity

Wanneer u ASP.NET Core gebruikt Identity:

  • Gegevensbeveiligingssleutels en de naam van de app moeten worden gedeeld tussen apps. In de volgende voorbeelden wordt een algemene opslaglocatie voor sleutelopslag verstrekt aan de PersistKeysToFileSystem methode. Gebruik SetApplicationName dit om een algemene naam voor een gedeelde app te configureren (SharedCookieApp in de volgende voorbeelden). Zie ASP.NET Core Data Protection configurerenvoor meer informatie.
  • Gebruik de ConfigureApplicationCookie extensiemethode om de gegevensbeschermingsservice voor cookies in te stellen.
  • Het standaardverificatietype is 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();

Notitie: De voorgaande instructies werken niet met ITicketStore (CookieAuthenticationOptions.SessionStore). Zie dit GitHub-probleem voor meer informatie.

Om veiligheidsredenen worden verificatiecookies niet gecomprimeerd in ASP.NET Core. Bij het gebruik van verificatiecookies moeten ontwikkelaars het aantal opgenomen claimgegevens minimaliseren tot slechts datgene wat nodig is voor hun behoeften.

Verificatiecookies delen zonder ASP.NET Core Identity

Wanneer u cookies rechtstreeks zonder ASP.NET Core Identitygebruikt, configureert u gegevensbeveiliging en -verificatie. In het volgende voorbeeld is het verificatietype ingesteld op 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();

Om veiligheidsredenen worden verificatiecookies niet gecomprimeerd in ASP.NET Core. Bij het gebruik van verificatiecookies moeten ontwikkelaars het aantal opgenomen claimgegevens minimaliseren tot slechts datgene wat nodig is voor hun behoeften.

Cookies delen via verschillende basispaden

Een verificatie cookie maakt gebruik van HttpRequest.PathBase als standaardCookie.Path. Als de app cookie moet worden gedeeld via verschillende basispaden, moet Path worden overschreven.

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

Cookies delen tussen subdomeinen

Bij het hosten van apps die cookies delen tussen subdomeinen, geeft u een gemeenschappelijk domein op in de Cookie. Domeineigenschap . Als u cookies wilt delen tussen apps op contoso.com, zoals first_subdomain.contoso.com en second_subdomain.contoso.com, specificeer de Cookie.Domain als .contoso.com:

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

Gegevensbeveiligingssleutels in rust versleutelen

Voor productie-implementaties configureert u de DataProtectionProvider om sleutels in opgeslagen toestand te versleutelen met DPAPI of een X509Certificate. Zie Sleutelversleuteling-at-rest in Windows en Azure met behulp van ASP.NET Core voor meer informatie. In het volgende voorbeeld wordt een vingerafdruk van het certificaat opgegeven voor ProtectKeysWithCertificate:

using Microsoft.AspNetCore.DataProtection;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

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

Een algemene gebruikersdatabase gebruiken

Wanneer apps hetzelfde Identity schema (dezelfde versie van Identity) gebruiken, controleert u of het Identity systeem voor elke app naar dezelfde gebruikersdatabase verwijst. Anders produceert het identiteitssysteem tijdens runtime fouten wanneer wordt geprobeerd de informatie in de verificatie cookie te vergelijken met de gegevens in de database.

Wanneer het Identity schema verschilt tussen apps, meestal omdat apps verschillende Identity versies gebruiken, is het niet mogelijk om een gemeenschappelijke database te delen op basis van de nieuwste versie van Identity zonder kolommen opnieuw toe te wijzen en toe te voegen in de schema's van Identity andere apps. Het is vaak efficiënter om de andere apps te upgraden om de nieuwste Identity versie te gebruiken, zodat een gemeenschappelijke database kan worden gedeeld door de apps.

Naam van de applicatie wijzigen

In .NET 6 WebApplicationBuilder normaliseert u het hoofdpad van de inhoud om te eindigen met een DirectorySeparatorChar. De meeste apps die worden gemigreerd van HostBuilder of WebHostBuilder hebben niet dezelfde app-naam omdat ze niet zijn genormaliseerd. Zie SetApplicationName voor meer informatie

Verificatiecookies delen tussen ASP.NET 4.x en ASP.NET Core-apps

ASP.NET 4.x-apps die gebruikmaken van Microsoft.Owin Cookie Authentication Middleware, kunnen worden geconfigureerd voor het genereren van verificatiecookies die compatibel zijn met de ASP.NET Core Cookie Authentication Middleware. Dit kan handig zijn als een webtoepassing bestaat uit zowel ASP.NET 4.x-apps als ASP.NET Core-apps die een ervaring met eenmalige aanmelding moeten delen. Een specifiek voorbeeld van een dergelijk scenario is het incrementeel migreren van een web-app van ASP.NET naar ASP.NET Core. In dergelijke scenario's is het gebruikelijk dat sommige onderdelen van een app worden bediend door de oorspronkelijke ASP.NET-app, terwijl andere worden bediend door de nieuwe ASP.NET Core-app. Gebruikers moeten zich echter maar één keer aanmelden. Dit kan worden bereikt door een van de volgende methoden:

  • Gebruik de externe verificatiefunctie van System.Web-adapters, die gebruikmaakt van de ASP.NET-app om gebruikers aan te melden.
  • De ASP.NET-app configureren voor het gebruik van Microsoft.Owin Cookie Authentication Middleware, zodat verificatiecookies worden gedeeld met de ASP.NET Core-app.

Als u ASP.NET Microsoft.Owin Cookie Authentication Middleware wilt configureren voor het delen van cookies met een ASP.NET Core-app, volgt u de voorgaande instructies om de ASP.NET Core-app te configureren voor het gebruik van een specifieke cookie naam, app-naam en om gegevensbeveiligingssleutels op een bekende locatie te behouden. Zie Configureren ASP.NET Core Data Protection voor meer informatie over het behouden van gegevensbeveiligingssleutels.

Installeer het Microsoft.Owin.Security.Interop pakket in de ASP.NET-app.

Werk de UseCookieAuthentication aanroep in Startup.Auth.cs bij om een AspNetTicketDataFormat zo te configureren dat deze overeenkomt met de instellingen van de ASP.NET Core-app:

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

Belangrijke items die hier zijn geconfigureerd, zijn onder andere:

  • De cookie naam is ingesteld op dezelfde naam als in de ASP.NET Core-app.
  • Er wordt een provider voor gegevensbescherming gemaakt met hetzelfde sleutelringpad. In deze voorbeelden worden gegevensbeveiligingssleutels opgeslagen op schijf, maar andere providers voor gegevensbeveiliging kunnen worden gebruikt. Redis of Azure Blob Storage kan bijvoorbeeld worden gebruikt voor providers van gegevensbeveiliging zolang de configuratie overeenkomt met de apps. Zie Configureren ASP.NET Core Data Protection voor meer informatie over het behouden van gegevensbeveiligingssleutels.
  • De app-naam is ingesteld op dezelfde als de app-naam die wordt gebruikt in de ASP.NET Core-app.
  • Het verificatietype is ingesteld op de naam van het verificatieschema in de ASP.NET Core-app.
  • System.Web.Helpers.AntiForgeryConfig.UniqueClaimTypeIdentifier is ingesteld op een claim van de ASP.NET Core-identiteit die uniek is voor een gebruiker.

Omdat het verificatietype is gewijzigd zodat het overeenkomt met het verificatieschema van de ASP.NET Core-app, moet u ook bijwerken hoe de ASP.NET-app nieuwe identiteiten genereert om dezelfde naam te gebruiken. Dit wordt meestal gedaan 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;
    }
}

Met deze wijzigingen kunnen de ASP.NET en ASP.NET Core-apps dezelfde verificatiecookies gebruiken, zodat gebruikers zich aanmelden of afmelden bij de ene app in de andere app.

Omdat er verschillen zijn tussen ASP.NET en Identity ASP.NET Core-databaseschema's Identity, is het raadzaam dat gebruikers zich alleen aanmelden met behulp van een van de apps: de ASP.NET of ASP.NET Core-app . Zodra gebruikers zijn aangemeld, kunnen de stappen in deze sectie ervoor zorgen dat de authenticatie cookie door een van beide apps gebruikt kan worden en dat beide apps gebruikers moeten kunnen afmelden.

Aanvullende bronnen

In de volgende voorbeelden:

  • De verificatienaam cookie wordt ingesteld op een gemeenschappelijke waarde van .AspNet.SharedCookie.
  • De AuthenticationType is ingesteld op Identity.Application expliciet of standaard.
  • Een algemene app-naam wordt gebruikt om het gegevensbeveiligingssysteem in staat te stellen gegevensbeveiligingssleutels (SharedCookieApp) te delen.
  • Identity.Application wordt gebruikt als verificatieschema. Welk schema ook wordt gebruikt, het moet consistent in en tussen de gedeelde cookie apps worden gebruikt als het standaardschema of door het expliciet in te stellen. Het schema wordt gebruikt bij het versleutelen en ontsleutelen van cookies, dus een consistent schema moet worden gebruikt in alle apps.
  • Er wordt een algemene opslaglocatie voor gegevensbeveiligingssleutels gebruikt.
  • DataProtectionProvider vereist het NuGet-pakket Microsoft.AspNetCore.DataProtection.Extensions :
  • SetApplicationName hiermee stelt u de algemene app-naam in.

Verificatiecookies delen met ASP.NET Core Identity

Wanneer u ASP.NET Core gebruikt Identity:

  • Gegevensbeveiligingssleutels en de naam van de app moeten worden gedeeld tussen apps. In de volgende voorbeelden wordt een algemene opslaglocatie voor sleutelopslag verstrekt aan de PersistKeysToFileSystem methode. Gebruik SetApplicationName dit om een algemene naam voor een gedeelde app te configureren (SharedCookieApp in de volgende voorbeelden). Zie ASP.NET Core Data Protection configurerenvoor meer informatie.
  • Gebruik de ConfigureApplicationCookie extensiemethode om de gegevensbeschermingsservice voor cookies in te stellen.
  • Het standaardverificatietype is Identity.Application.

In Startup.ConfigureServices:

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

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

Notitie: De voorgaande instructies werken niet met ITicketStore (CookieAuthenticationOptions.SessionStore). Zie dit GitHub-probleem voor meer informatie.

Om veiligheidsredenen worden verificatiecookies niet gecomprimeerd in ASP.NET Core. Bij het gebruik van verificatiecookies moeten ontwikkelaars het aantal opgenomen claimgegevens minimaliseren tot slechts datgene wat nodig is voor hun behoeften.

Verificatiecookies delen zonder ASP.NET Core Identity

Wanneer u cookies rechtstreeks zonder ASP.NET Core Identitygebruikt, configureert u gegevensbeveiliging en -verificatie in Startup.ConfigureServices. In het volgende voorbeeld is het verificatietype ingesteld op 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";
    });

Om veiligheidsredenen worden verificatiecookies niet gecomprimeerd in ASP.NET Core. Bij het gebruik van verificatiecookies moeten ontwikkelaars het aantal opgenomen claimgegevens minimaliseren tot slechts datgene wat nodig is voor hun behoeften.

Cookies delen via verschillende basispaden

Een verificatie cookie maakt gebruik van HttpRequest.PathBase als standaardCookie.Path. Als de app cookie moet worden gedeeld via verschillende basispaden, moet Path worden overschreven.

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

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

Cookies delen tussen subdomeinen

Bij het hosten van apps die cookies delen tussen subdomeinen, geeft u een gemeenschappelijk domein op in de Cookie. Domeineigenschap . Als u cookies wilt delen tussen apps op contoso.com, zoals first_subdomain.contoso.com en second_subdomain.contoso.com, specificeer de Cookie.Domain als .contoso.com:

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

Gegevensbeveiligingssleutels in rust versleutelen

Voor productie-implementaties configureert u de DataProtectionProvider om sleutels in opgeslagen toestand te versleutelen met DPAPI of een X509Certificate. Zie Sleutelversleuteling-at-rest in Windows en Azure met behulp van ASP.NET Core voor meer informatie. In het volgende voorbeeld wordt een vingerafdruk van het certificaat opgegeven voor ProtectKeysWithCertificate:

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

Verificatiecookies delen tussen ASP.NET 4.x en ASP.NET Core-apps

ASP.NET 4.x-apps die gebruikmaken van Katana Cookie Authentication Middleware, kunnen worden geconfigureerd voor het genereren van verificatiecookies die compatibel zijn met de ASP.NET Core Cookie Authentication Middleware. Zie Verificatiecookies delen tussen ASP.NET 4.x en ASP.NET Core-apps (dotnet/AspNetCore.Docs #21987) voor meer informatie.

Een algemene gebruikersdatabase gebruiken

Wanneer apps hetzelfde Identity schema (dezelfde versie van Identity) gebruiken, controleert u of het Identity systeem voor elke app naar dezelfde gebruikersdatabase verwijst. Anders produceert het identiteitssysteem tijdens runtime fouten wanneer wordt geprobeerd de informatie in de verificatie cookie te vergelijken met de gegevens in de database.

Wanneer het Identity schema verschilt tussen apps, meestal omdat apps verschillende Identity versies gebruiken, is het niet mogelijk om een gemeenschappelijke database te delen op basis van de nieuwste versie van Identity zonder kolommen opnieuw toe te wijzen en toe te voegen in de schema's van Identity andere apps. Het is vaak efficiënter om de andere apps te upgraden om de nieuwste Identity versie te gebruiken, zodat een gemeenschappelijke database kan worden gedeeld door de apps.

Aanvullende bronnen