Condividi tramite


Provider di archiviazione delle 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 deregistra il meccanismo di crittografia della chiave predefinita a riposo, quindi le chiavi non vengono più crittografate a riposo. È consigliabile specificare anche un meccanismo di crittografia della chiave esplicito per le distribuzioni di produzione.

Sistema di gestione dei file

Per configurare un repository di chiavi basato su file system, chiamare la PersistKeysToFileSystem routine di configurazione come illustrato di seguito. Specificare un DirectoryInfo che punti 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 si punta a una directory nel computer locale (nello scenario in cui solo le app sul computer locale richiedono l'accesso a questo repository), è consigliabile usare Windows DPAPI (in Windows) per crittografare le chiavi a riposo. In caso contrario, prendere in considerazione l'uso di un certificato X.509 per crittografare le chiavi a riposo.

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 i cookie di autenticazione o la protezione CSRF tra più server.

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

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 nell'archiviazione di Azure usando Azure.Storage.Blobs.

Avviso

Questo articolo illustra l'uso di stringa di connessione. Con un database locale l'utente non deve essere autenticato, ma nell'ambiente di produzione stringa di connessione talvolta include una password per l'autenticazione. Una credenziale di password del proprietario della risorsa (ROPC) è un rischio per la sicurezza che andrebbe evitato nei database di produzione. Le app di produzione devono usare il flusso di autenticazione più sicuro disponibile. Per altre informazioni sull'autenticazione per le app distribuite in ambienti di test o di produzione, vedere Proteggere i flussi di autenticazione.

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

La stringa di connessione al tuo account di archiviazione è disponibile nel portale di Azure nella sezione "Chiavi di accesso" o eseguendo il seguente comando CLI:

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 i cookie di autenticazione o la protezione CSRF tra 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 i cookie di autenticazione o la protezione CSRF tra 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 viene eseguita come account del servizio virtuale, ad esempio come identità del pool di applicazioni di w3wp.exe. In questi casi, l'amministratore può configurare una chiave di registro accessibile dall'identità dell'account di servizio. Chiamare il PersistKeysToRegistry metodo di estensione come illustrato di seguito. Specificare un RegistryKey che punta al 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 nullo
FriendlyName string nvarchar(MAX)nullo
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 meccanismo personalizzato IXmlRepository.