Partilhar via


Partilhar cookies de autenticação entre aplicações ASP.NET

Por Rick Anderson

Os sites geralmente consistem em aplicativos Web individuais trabalhando juntos. Para fornecer uma experiência de logon único (SSO), os aplicativos Web dentro de um site devem compartilhar cookies de autenticação. Para dar suporte a este cenário, a pilha de proteção de dados permite compartilhar os bilhetes de autenticação do Katana cookie e do ASP.NET Core cookie.

Nos exemplos que se seguem:

  • O nome de autenticação cookie é definido como um valor comum de .AspNet.SharedCookie.
  • O AuthenticationType é definido como Identity.Application explicitamente ou por padrão.
  • Um nome de aplicativo comum, SharedCookieApp, é usado para permitir que o sistema de proteção de dados compartilhe chaves de proteção de dados.
  • Identity.Application é usado como o esquema de autenticação. Seja qual for o esquema usado, ele deve ser usado de forma consistente dentro e entre os aplicativos cookie compartilhados, seja como o esquema padrão ou definindo-o explicitamente. O esquema é usado ao criptografar e descriptografar cookies, portanto, um esquema consistente deve ser usado em todos os aplicativos.
  • É utilizada uma localização de armazenamento comum para a chave de proteção de dados .
  • DataProtectionProvider requer o pacote NuGet Microsoft.AspNetCore.DataProtection.Extensions.
  • SetApplicationName define o nome comum do aplicativo.

Partilhar cookies de autenticação com o ASP.NET Core Identity

Ao usar ASP.NET Core Identity:

  • As chaves de proteção de dados e o nome do aplicativo devem ser compartilhados entre os aplicativos. Um local comum de armazenamento de chaves é fornecido para o método PersistKeysToFileSystem nos exemplos a seguir. Use SetApplicationName para configurar um nome de aplicativo compartilhado comum (SharedCookieApp nos exemplos a seguir). Para obter mais informações, consulte Configurar a proteção de dados do ASP.NET Core.
  • Use o método de extensão ConfigureApplicationCookie para configurar o serviço de proteção de dados para cookies.
  • O tipo de autenticação padrão é Identity.Application.

Em 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: As instruções anteriores não funcionam com ITicketStore (CookieAuthenticationOptions.SessionStore). Para obter mais informações, consulte este problema do GitHub.

Por razões de segurança, os cookies de autenticação não são comprimidos no ASP.NET Core. Ao usar cookies de autenticação, os desenvolvedores devem minimizar o número de informações de reivindicação incluídas apenas para o necessário para suas necessidades.

Partilhe cookies de autenticação sem ASP.NET Core Identity

Ao usar cookies diretamente sem ASP.NET Core Identity, configure a proteção de dados e autenticação. No exemplo a seguir, o tipo de autenticação é definido como 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();

Por razões de segurança, os cookies de autenticação não são comprimidos no ASP.NET Core. Ao usar cookies de autenticação, os desenvolvedores devem minimizar o número de informações de reivindicação incluídas apenas para o necessário para suas necessidades.

Partilhar cookies em diferentes percursos de base

Um cookie de autenticação usa o HttpRequest.PathBase como seu Cookiepadrão. Caminho. Se a cookie do aplicativo precisar ser compartilhada entre caminhos base diferentes, Path deverá ser substituída:

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

Partilhar cookies entre subdomínios

Ao hospedar aplicativos que compartilham cookies entre subdomínios, especifique um domínio comum no Cookie. Domínio propriedade. Para partilhar cookies entre aplicações em contoso.com, como first_subdomain.contoso.com e second_subdomain.contoso.com, especifique o Cookie.Domain como .contoso.com:

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

Criptografar chaves de proteção de dados em repouso

Para implantações de produção, configure o DataProtectionProvider para criptografar chaves em repouso com DPAPI ou um X509Certificate. Para obter mais informações, consulte criptografia de chave em repouso no Windows e no Azure usando ASP.NET Core. No exemplo a seguir, uma impressão digital de certificado é fornecida a ProtectKeysWithCertificate:

using Microsoft.AspNetCore.DataProtection;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

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

Usar um banco de dados de usuário comum

Quando os aplicativos usam o mesmo esquema de Identity (mesma versão do Identity), confirme se o sistema de Identity de cada aplicativo está apontado para o mesmo banco de dados de usuários. Caso contrário, o sistema de identidade produz falhas em tempo de execução quando tenta fazer a correspondência entre as informações no cookie de autenticação e as informações na sua base de dados.

Quando o esquema Identity é diferente entre aplicativos, geralmente porque os aplicativos estão usando versões Identity diferentes, compartilhar um banco de dados comum com base na versão mais recente do Identity não é possível sem remapear e adicionar colunas nos esquemas Identity de outros aplicativos. Muitas vezes, é mais eficiente atualizar os outros aplicativos para usar a versão mais recente do Identity para que um banco de dados comum possa ser compartilhado pelos aplicativos.

Alteração do nome do aplicativo

No .NET 6, o WebApplicationBuilder normaliza o caminho raiz do conteúdo para terminar com um DirectorySeparatorChar. A maioria dos aplicativos que migram do HostBuilder ou WebHostBuilder não terá o mesmo nome de aplicativo porque eles não são normalizados. Para obter mais informações, consulte SetApplicationName

Partilhar cookies de autenticação entre as aplicações ASP.NET 4.x e ASP.NET Core

ASP.NET aplicativos 4.x que usam o Microsoft.Owin Cookie Authentication Middleware podem ser configurados para gerar cookies de autenticação compatíveis com o ASP.NET Core Cookie Authentication Middleware. Isso pode ser útil se um aplicativo Web consistir em aplicativos ASP.NET 4.x e aplicativos ASP.NET Core que devem compartilhar uma experiência de logon único. Um exemplo específico desse cenário é incrementalmente migrando um aplicativo web do ASP.NET para o ASP.NET Core. Nesses cenários, é comum que algumas partes de um aplicativo sejam atendidas pelo aplicativo ASP.NET original, enquanto outras são atendidas pelo novo aplicativo ASP.NET Core. No entanto, os utilizadores só devem ter de iniciar sessão uma vez. Isso pode ser feito por uma das seguintes abordagens:

  • Usando o recurso de autenticação remota dos adaptadores System.Web, que utiliza a aplicação ASP.NET para autenticar os utilizadores.
  • Configurar o aplicativo ASP.NET para usar o Microsoft.Owin Cookie Authentication Middleware para que os cookies de autenticação sejam compartilhados com o aplicativo ASP.NET Core.

Para configurar o ASP.NET Microsoft.Owin Cookie Authentication Middleware para compartilhar cookies com um aplicativo ASP.NET Core, siga as instruções anteriores para configurar o aplicativo ASP.NET Core para usar um nome cookie específico, nome do aplicativo e para persistir chaves de proteção de dados para um local bem conhecido. Consulte Configure ASP.NET Core Data Protection para obter mais informações sobre chaves de proteção de dados persistentes.

No aplicativo ASP.NET, instale o pacote Microsoft.Owin.Security.Interop.

Atualize a chamada UseCookieAuthentication no Startup.Auth.cs para configurar um AspNetTicketDataFormat de modo a alinhar com as definições da aplicação 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()
});

Os itens importantes configurados aqui incluem:

  • O nome cookie é definido com o mesmo nome que na aplicação ASP.NET Core.
  • Um provedor de proteção de dados é criado usando o mesmo caminho do anel de chaves. Observe que, nesses exemplos, as chaves de proteção de dados são armazenadas no disco, mas outros provedores de proteção de dados podem ser usados. Por exemplo, o Redis ou o Armazenamento de Blobs do Azure podem ser usados para provedores de proteção de dados, desde que a configuração corresponda entre os aplicativos. Consulte Configure ASP.NET Core Data Protection para obter mais informações sobre chaves de proteção de dados persistentes.
  • O nome do aplicativo é definido como o mesmo que o nome do aplicativo usado no aplicativo ASP.NET Core.
  • O tipo de autenticação é definido como o nome do esquema de autenticação no aplicativo ASP.NET Core.
  • System.Web.Helpers.AntiForgeryConfig.UniqueClaimTypeIdentifier é definido como uma declaração da identidade ASP.NET Core que será exclusiva para um usuário.

Como o tipo de autenticação foi alterado para corresponder ao esquema de autenticação do aplicativo ASP.NET Core, também é necessário atualizar como o aplicativo ASP.NET gera novas identidades para usar esse mesmo nome. Isso geralmente é feito em 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;
    }
}

Com essas alterações, os aplicativos ASP.NET e ASP.NET Core podem usar os mesmos cookies de autenticação para que os usuários que entram ou saem de um aplicativo sejam refletidos no outro aplicativo.

Observe que, como há diferenças entre os esquemas de banco de dados do ASP.NET Identity e do ASP.NET Core Identity, é recomendável que os usuários só de entrada usando um dos aplicativos - o aplicativo ASP.NET ou o aplicativo ASP.NET Core. Depois que os utilizadores tiverem iniciado sessão, as etapas documentadas nesta seção permitirão que a autenticação cookie seja usada por qualquer aplicação e ambas as aplicações poderão terminar a sessão dos utilizadores.

Recursos adicionais

Nos exemplos que se seguem:

  • O nome de autenticação cookie é definido para um valor comum de .AspNet.SharedCookie.
  • O AuthenticationType é definido como Identity.Application explicitamente ou por padrão.
  • Um nome de aplicativo comum é usado para permitir que o sistema de proteção de dados compartilhe chaves de proteção de dados (SharedCookieApp).
  • Identity.Application é usado como o esquema de autenticação. Seja qual for o esquema usado, ele deve ser usado de forma consistente dentro e entre os aplicativos de cookie compartilhados, seja como o esquema padrão ou definindo-o explicitamente. O esquema é usado ao criptografar e descriptografar cookies, portanto, um esquema consistente deve ser usado em todos os aplicativos.
  • É utilizado um local de armazenamento comum para a chave de proteção de dados .
  • DataProtectionProvider requer o Microsoft.AspNetCore.DataProtection.Extensions pacote NuGet:
  • SetApplicationName define o nome comum do aplicativo.

Partilhar cookies de autenticação com o ASP.NET Core Identity

Ao usar ASP.NET Core Identity:

  • As chaves de proteção de dados e o nome do aplicativo devem ser compartilhados entre os aplicativos. Um local comum de armazenamento de chaves é fornecido para o método PersistKeysToFileSystem nos exemplos a seguir. Use SetApplicationName para configurar um nome de aplicativo compartilhado comum (SharedCookieApp nos exemplos a seguir). Para obter mais informações, consulte Configurar a proteção de dados do ASP.NET Core.
  • Use o método de extensão ConfigureApplicationCookie para configurar o serviço de proteção de dados para cookies.
  • O tipo de autenticação padrão é Identity.Application.

Em Startup.ConfigureServices:

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

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

Nota: As instruções anteriores não funcionam com ITicketStore (CookieAuthenticationOptions.SessionStore). Para obter mais informações, consulte este problema do GitHub.

Por razões de segurança, os cookies de autenticação não são comprimidos no ASP.NET Core. Ao usar cookies de autenticação, os desenvolvedores devem minimizar o número de informações de reivindicação incluídas apenas para o necessário para suas necessidades.

Distribuir cookies de autenticação sem utilizar ASP.NET Core Identity

Ao usar cookies diretamente sem ASP.NET Core Identity, configure a proteção de dados e autenticação em Startup.ConfigureServices. No exemplo a seguir, o tipo de autenticação é definido como 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";
    });

Por razões de segurança, os cookies de autenticação não são comprimidos no ASP.NET Core. Ao usar cookies de autenticação, os desenvolvedores devem minimizar o número de informações de reivindicação incluídas apenas para o necessário para suas necessidades.

Partilhar cookies em diferentes caminhos de base

A autenticação cookie usa o HttpRequest.PathBase como seu caminho padrão Cookie. Se a cookie do aplicativo precisar ser compartilhada entre caminhos base diferentes, Path deverá ser substituída:

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

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

Partilhar cookies entre subdomínios

Ao hospedar aplicações que partilham cookies entre subdomínios, especifique um domínio comum na propriedade Cookie.Domain. Para partilhar cookies entre aplicações em contoso.com, como first_subdomain.contoso.com e second_subdomain.contoso.com, especifique o Cookie.Domain como .contoso.com:

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

Criptografar chaves de proteção de dados em repouso

Para implantações de produção, configure o DataProtectionProvider para criptografar chaves em repouso com DPAPI ou um X509Certificate. Para obter mais informações, consulte criptografia de chave em repouso no Windows e no Azure usando ASP.NET Core. No exemplo a seguir, uma impressão digital de um certificado é fornecida para ProtectKeysWithCertificate:

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

Partilhar cookies de autenticação entre as aplicações ASP.NET 4.x e ASP.NET Core

ASP.NET aplicativos 4.x que usam o Katana Cookie Authentication Middleware podem ser configurados para gerar cookies de autenticação compatíveis com o ASP.NET Core Cookie Authentication Middleware. Para obter mais informações, consulte Compartilhar cookies de autenticação entre aplicativos ASP.NET 4.x e ASP.NET Core (dotnet/AspNetCore.Docs #21987).

Usar um banco de dados de usuário comum

Quando os aplicativos usam o mesmo esquema de Identity (mesma versão do Identity), confirme se o sistema de Identity de cada aplicativo está apontado para o mesmo banco de dados de usuários. Caso contrário, o sistema de identidade produz falhas em tempo de execução quando tenta fazer a correspondência entre as informações no cookie de autenticação e as informações em seu banco de dados.

Quando o esquema Identity é diferente entre aplicativos, geralmente porque os aplicativos estão usando versões Identity diferentes, compartilhar um banco de dados comum com base na versão mais recente do Identity não é possível sem remapear e adicionar colunas nos esquemas Identity de outros aplicativos. Muitas vezes, é mais eficiente atualizar os outros aplicativos para usar a versão mais recente do Identity para que um banco de dados comum possa ser compartilhado pelos aplicativos.

Recursos adicionais