Condividi tramite


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 una posizione di persistenza della chiave esplicita, il sistema di protezione dei dati annulla la registrazione della crittografia della chiave predefinita nel rest meccanismo, quindi le chiavi non vengono più crittografate in rest. È 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), prendere in considerazione l'uso di DPAPI di Windows (in Windows) per crittografare le chiavi in rest. In caso contrario, prendere in considerazione l'uso di un certificato X.509 per crittografare le chiavi in rest.

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 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 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 della password del proprietario della risorsa (ROPC) è un rischio per la sicurezza che deve essere 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

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 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 è in esecuzione come account del servizio virtuale , ad esempio il pool identitydi app di w3wp.exe . In questi casi, l'amministratore può effettuare il provisioning di una chiave del Registro di sistema accessibile dall'account identitydel 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 in rest.

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)nullo
Xml string nvarchar(MAX)nullo

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.