Provider di archiviazione chiavi in ASP.NET Core

Per impostazione predefinita, il sistema di protezione dei dati usa un meccanismo di individuazione per determinare dove devono essere mantenute le chiavi crittografiche. Lo sviluppatore può eseguire l'override del meccanismo di individuazione predefinito e specificare manualmente il percorso.

Avviso

Se si specifica un percorso esplicito di persistenza della chiave, il sistema di protezione dei dati annulla la registrazione del meccanismo di crittografia della chiave predefinita inattivi, quindi le chiavi non vengono più crittografate inattive. È consigliabile specificare anche un meccanismo di crittografia della chiave esplicito per le distribuzioni di produzione.

File system

Per configurare un repository di chiavi basato su file system, chiamare la PersistKeysToFileSystem routine di configurazione come illustrato di seguito. Specificare un DirectoryInfo punto al repository in cui archiviare le chiavi:

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

DirectoryInfo può puntare a una directory nel computer locale oppure può puntare a una cartella in una condivisione di rete. Se punta a una directory nel computer locale (e lo scenario è che solo le app nel computer locale richiedono l'accesso a questo repository), è consigliabile usare Windows DPAPI (in Windows) per crittografare le chiavi inattive. In caso contrario, prendere in considerazione l'uso di un certificato X.509 per crittografare le chiavi inattive.

Archiviazione di Azure

Il pacchetto Azure.Extensions.AspNetCore.DataProtection.Blobs consente di archiviare le chiavi di protezione dei dati in Archiviazione BLOB di Azure. Le chiavi possono essere condivise tra diverse istanze di un'app Web. Le app possono condividere la protezione csrF o s di autenticazione cookietra più server.

Per configurare il provider di Archiviazione BLOB di Azure, chiamare uno degli PersistKeysToAzureBlobStorage overload.

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

Se l'app Web è in esecuzione come servizio di Azure, stringa di connessione può essere usata per eseguire l'autenticazione in Archiviazione di Azure usando Azure.Archiviazione. BLOB.

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

Nota

Il stringa di connessione all'account di archiviazione è disponibile nel portale di Azure nella sezione "Chiavi di accesso" o eseguendo il comando dell'interfaccia della riga di comando seguente:

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

Redis

Il pacchetto Microsoft.AspNetCore.DataProtection.StackExchangeRedis consente di archiviare le chiavi di protezione dei dati in una cache Redis. Le chiavi possono essere condivise tra diverse istanze di un'app Web. Le app possono condividere la protezione csrF o s di autenticazione cookietra più server.

Il pacchetto Microsoft.AspNetCore.DataProtection.Redis consente di archiviare le chiavi di protezione dei dati in una cache Redis. Le chiavi possono essere condivise tra diverse istanze di un'app Web. Le app possono condividere la protezione csrF o s di autenticazione cookietra più server.

Per configurare in Redis, chiamare uno degli PersistKeysToStackExchangeRedis overload:

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

Per configurare in Redis, chiamare uno degli PersistKeysToRedis overload:

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

Per ulteriori informazioni, vedi gli argomenti seguenti:

Registro

Si applica solo alle distribuzioni di Windows.

A volte l'app potrebbe non avere accesso in scrittura al file system. Si consideri uno scenario in cui un'app è in esecuzione come account del servizio virtuale ,ad esempio l'identità del pool di app w3wp.exe. In questi casi, l'amministratore può effettuare il provisioning di una chiave del Registro di sistema accessibile dall'identità dell'account del servizio. Chiamare il PersistKeysToRegistry metodo di estensione come illustrato di seguito. Specificare un RegistryKey punto verso il percorso in cui archiviare le chiavi crittografiche:

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

Importante

È consigliabile usare Windows DPAPI per crittografare le chiavi inattive.

Entity Framework Core

Il pacchetto Microsoft.AspNetCore.DataProtection.EntityFrameworkCore fornisce un meccanismo per l'archiviazione delle chiavi di protezione dei dati in un database tramite Entity Framework Core. Il Microsoft.AspNetCore.DataProtection.EntityFrameworkCore pacchetto NuGet deve essere aggiunto al file di progetto, non fa parte del metapacchetto Microsoft.AspNetCore.App.

Con questo pacchetto, le chiavi possono essere condivise tra più istanze di un'app Web.

Per configurare il EF Core provider, chiamare il PersistKeysToDbContext metodo :

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

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

Il parametro generico , TContext, deve ereditare da DbContext e implementare 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; }
    }
}

Creare la DataProtectionKeys tabella.

Eseguire i comandi seguenti nella finestra Gestione pacchetti Console (PMC):

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

MyKeysContext è l'oggetto DbContext definito nell'esempio di codice precedente. Se si usa un DbContext oggetto con un nome diverso, sostituire il DbContext nome con MyKeysContext.

La DataProtectionKeys classe/entità adotta la struttura illustrata nella tabella seguente.

Proprietà/Campo Tipo CLR Tipo SQL
Id int int, PK, IDENTITY(1,1), non null
FriendlyName string nvarchar(MAX)Null
Xml string nvarchar(MAX)Null

Repository di chiavi personalizzato

Se i meccanismi predefiniti non sono appropriati, lo sviluppatore può specificare il proprio meccanismo di persistenza delle chiavi fornendo un oggetto personalizzato IXmlRepository.