Partilhar via


Principais provedores de armazenamento no ASP.NET Core

O sistema de proteção de dados emprega um mecanismo de descoberta por padrão para determinar onde as chaves criptográficas devem ser persistentes. O desenvolvedor pode substituir o mecanismo de descoberta padrão e especificar manualmente o local.

Advertência

Se você especificar um local explícito de persistência de chave, o sistema de proteção de dados cancelará o registro do mecanismo padrão de criptografia de chave em repouso, para que as chaves não sejam mais criptografadas em repouso. É recomendável que você também especifique um mecanismo de criptografia de chave explícito para implantações de produção.

Sistema de ficheiros

Para configurar um repositório de chaves baseado no sistema de arquivos, chame a rotina de configuração PersistKeysToFileSystem, conforme mostrado abaixo. Forneça um DirectoryInfo apontando para o repositório onde as chaves devem ser armazenadas:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDataProtection()
        .PersistKeysToFileSystem(new DirectoryInfo(@"c:\temp-keys\"));
}

O DirectoryInfo pode apontar para um diretório na máquina local ou pode apontar para uma pasta em um compartilhamento de rede. Se apontar para um diretório na máquina local (e o cenário é que apenas aplicativos na máquina local exigem acesso para usar esse repositório), considere usar DPAPI do Windows (no Windows) para criptografar as chaves em repouso. Caso contrário, considere usar um certificado X.509 para criptografar chaves em repouso.

Armazenamento do Azure

O pacote Azure.Extensions.AspNetCore.DataProtection.Blobs permite o armazenamento de chaves de proteção de dados nos Blobs de Armazenamento do Azure. As chaves podem ser compartilhadas entre várias instâncias de um aplicativo Web. Os aplicativos podem compartilhar cookies de autenticação ou proteção CSRF em vários servidores.

Para configurar o provedor de Armazenamento de Blob do Azure, invoque uma das PersistKeysToAzureBlobStorage sobrecargas.

public void ConfigureServices(IServiceCollection services)
{
    services.AddDataProtection()
        .PersistKeysToAzureBlobStorage(new Uri("<blob URI including SAS token>"));
}

Se o aplicativo Web estiver sendo executado como um serviço do Azure, a cadeia de conexão poderá ser usada para autenticar no armazenamento do Azure usando Azure.Storage.Blobs.

Advertência

Este artigo mostra o uso de cadeias de conexão. Com um banco de dados local, o usuário não precisa ser autenticado, mas na produção, as cadeias de conexão às vezes incluem uma senha para autenticar. Uma credencial de senha de proprietário de recurso (ROPC) é um risco de segurança que deve ser evitado em bancos de dados de produção. Os aplicativos de produção devem usar o fluxo de autenticação mais seguro disponível. Para obter mais informações sobre autenticação para aplicativos implantados em ambientes de teste ou produção, consulte Fluxos de autenticação segura.

string connectionString = "<connection_string>";
string containerName = "my-key-container";
string blobName = "keys.xml";
BlobContainerClient container = new BlobContainerClient(connectionString, containerName);

// optional - provision the container automatically
await container.CreateIfNotExistsAsync();

BlobClient blobClient = container.GetBlobClient(blobName);

services.AddDataProtection()
    .PersistKeysToAzureBlobStorage(blobClient);

Observação

A cadeia de conexão para sua conta de armazenamento pode ser encontrada no Portal do Azure na seção "Chaves de acesso" ou executando o seguinte comando da CLI:

az storage account show-connection-string --name <account_name> --resource-group <resource_group>

Redis

O pacote Microsoft.AspNetCore.DataProtection.StackExchangeRedis permite armazenar chaves de proteção de dados numa cache Redis. As chaves podem ser compartilhadas entre várias instâncias de um aplicativo Web. Os aplicativos podem compartilhar cookies de autenticação ou proteção CSRF em vários servidores.

O pacote Microsoft.AspNetCore.DataProtection.Redis permite armazenar chaves de proteção de dados numa cache Redis. As chaves podem ser compartilhadas entre várias instâncias de um aplicativo Web. Os aplicativos podem compartilhar cookies de autenticação ou proteção CSRF em vários servidores.

Para configurar no Redis, chame uma das PersistKeysToStackExchangeRedis sobrecargas:

public void ConfigureServices(IServiceCollection services)
{
    var redis = ConnectionMultiplexer.Connect("<URI>");
    services.AddDataProtection()
        .PersistKeysToStackExchangeRedis(redis, "DataProtection-Keys");
}

Para configurar no Redis, utilize uma das sobrecargas PersistKeysToRedis:

public void ConfigureServices(IServiceCollection services)
{
    var redis = ConnectionMultiplexer.Connect("<URI>");
    services.AddDataProtection()
        .PersistKeysToRedis(redis, "DataProtection-Keys");
}

Para obter mais informações, consulte os seguintes tópicos:

Registo

Aplica-se apenas a implantações do Windows.

Às vezes, a aplicação pode não ter acesso de gravação ao sistema de arquivos. Considere um cenário em que um aplicativo esteja sendo executado como uma conta de serviço virtual (como a identidade do pool de aplicativos do w3wp.exe). Nesses casos, o administrador pode provisionar uma chave do Registro acessível pela identidade da conta de serviço. Chame o método de extensão PersistKeysToRegistry como mostrado abaixo. Forneça um RegistryKey apontando para o local onde as chaves criptográficas devem ser armazenadas:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDataProtection()
        .PersistKeysToRegistry(Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Sample\keys", true));
}

Importante

Recomendamos usar DPAPI do Windows para criptografar as chaves em repouso.

Núcleo do Entity Framework

O pacote Microsoft.AspNetCore.DataProtection.EntityFrameworkCore fornece um mecanismo para armazenar chaves de proteção de dados numa base de dados usando o Entity Framework Core. O pacote NuGet Microsoft.AspNetCore.DataProtection.EntityFrameworkCore deve ser adicionado ao arquivo de projeto, pois não faz parte do metapacote Microsoft.AspNetCore.App.

Com este pacote, as chaves podem ser compartilhadas em várias instâncias de um aplicativo Web.

Para configurar o provedor de EF Core, chame o método PersistKeysToDbContext:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<CookiePolicyOptions>(options =>
    {
        options.CheckConsentNeeded = context => true;
        options.MinimumSameSitePolicy = SameSiteMode.None;
    });

    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(
            Configuration.GetConnectionString("DefaultConnection")));

    // Add a DbContext to store your Database Keys
    services.AddDbContext<MyKeysContext>(options =>
        options.UseSqlServer(
            Configuration.GetConnectionString("MyKeysConnection")));

    // using Microsoft.AspNetCore.DataProtection;
    services.AddDataProtection()
        .PersistKeysToDbContext<MyKeysContext>();

    services.AddDefaultIdentity<IdentityUser>()
        .AddDefaultUI(UIFramework.Bootstrap4)
        .AddEntityFrameworkStores<ApplicationDbContext>();
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

Se você gostaria de ver os comentários de código traduzidos para outros idiomas além do inglês, informe-nos em este problema de discussão do GitHub.

O parâmetro genérico, TContext, deve herdar de DbContext e implementar IDataProtectionKeyContext:

using Microsoft.AspNetCore.DataProtection.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using WebApp1.Data;

namespace WebApp1
{
    class MyKeysContext : DbContext, IDataProtectionKeyContext
    {
        // A recommended constructor overload when using EF Core 
        // with dependency injection.
        public MyKeysContext(DbContextOptions<MyKeysContext> options) 
            : base(options) { }

        // This maps to the table that stores keys.
        public DbSet<DataProtectionKey> DataProtectionKeys { get; set; }
    }
}

Crie a tabela DataProtectionKeys.

Execute os seguintes comandos na janela Package Manager Console (PMC):

Add-Migration AddDataProtectionKeys -Context MyKeysContext
Update-Database -Context MyKeysContext

MyKeysContext é o DbContext definido no exemplo de código anterior. Se estiver a utilizar um DbContext com um nome diferente, substitua o seu nome DbContext por MyKeysContext.

A classe/entidade DataProtectionKeys adota a estrutura mostrada na tabela a seguir.

Propriedade/Campo Tipo CLR Tipo SQL
Id int int, PK, IDENTITY(1,1), não nulo
FriendlyName string nvarchar(MAX), null
Xml string nvarchar(MAX), nulo

Repositório de chaves personalizado

Se os mecanismos da caixa de entrada não forem apropriados, o desenvolvedor poderá especificar seu próprio mecanismo de persistência de chave fornecendo um IXmlRepositorypersonalizado.