Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
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 Azure.Extensions.AspNetCore.DataProtection.Blobs
pacchetto NuGet fornisce l'API per l'archiviazione delle 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.
Nota
Per indicazioni sull'aggiunta di pacchetti alle app .NET, vedere gli articoli sotto Installare e gestire pacchetti in Flusso di lavoro dell'utilizzo di pacchetti (documentazione di NuGet). Verificare le versioni corrette dei pacchetti in NuGet.org.
Per interagire con Azure Key Vault in locale usando le credenziali dello sviluppatore, accedere all'account di archiviazione in Visual Studio o accedere con l'interfaccia della riga di comando di Azure. Se l'interfaccia della riga di comando di Azure non è già stata installata, vedere Come installare l'interfaccia della riga di comando di Azure. È possibile eseguire il comando seguente nel pannello Developer PowerShell in Visual Studio o da una shell dei comandi quando non si usa Visual Studio:
az login
Per altre informazioni, vedere Accedere ad Azure usando gli strumenti per sviluppatori.
Configurare Archiviazione BLOB di Azure per gestire le chiavi di protezione dei dati:
Creare un account di archiviazione di Azure.
Creare un contenitore per contenere il file della chiave di protezione dei dati.
Per accedere al blob di archiviazione delle chiavi, è consigliabile utilizzare Azure Managed Identity e il controllo degli accessi in base al ruolo (RBAC). Non è necessario creare un file di chiave e caricarlo nel contenitore dell'account di archiviazione. Il framework crea automaticamente il file. Per esaminare il contenuto di un file di chiave, usare il comando Visualizza/modifica del menu di scelta rapida alla fine di una riga di chiave nel portale.
![NOTA] Se si prevede di usare un URI blob con una firma di accesso condiviso (SAS) invece di un Managed Identity, usare un editor di testo per creare un file di chiave XML nel computer locale.
<?xml version="1.0" encoding="utf-8"?> <repository> </repository>
Caricare il file di chiave nel contenitore dell'account di archiviazione. Usare il comando Visualizza/modifica del menu di scelta rapida alla fine della riga chiave nel portale per confermare che il blob contiene il contenuto precedente. Creando il file manualmente, è possibile ottenere l'URI del blob con SAS (firma di accesso condiviso) dal portale per configurare l'applicazione in un passaggio successivo.
Creare un'istanza di Managed Identity di Azure (o aggiungere un ruolo all'istanza di Managed Identity esistente che si prevede di utilizzare) con il ruolo Contributore ai dati del BLOB di archiviazione. Assegna il Gestito Identity al servizio App di Azure che ospita la distribuzione: Impostazioni>Identity>Utente assegnato>Aggiungi.
Nota
Se prevedi di eseguire un'app localmente con un utente autorizzato per l'accesso ai blob utilizzando l'Azure CLI o l'autenticazione del servizio Azure di Visual Studio, aggiungi il tuo account utente sviluppatore di Azure in Access Control (IAM) con il ruolo Storage Blob Data Contributor. Se si vuole usare l'interfaccia della riga di comando di Azure tramite Visual Studio, eseguire il
az login
comando dal pannello Developer PowerShell e seguire le istruzioni per l'autenticazione con il tenant.
Per configurare il provider di Archiviazione BLOB di Azure, chiamare uno degli PersistKeysToAzureBlobStorage overload nell'applicazione. L'esempio seguente usa l'overload che accetta un URI BLOB e una credenziale del token (TokenCredential), basandosi su un servizio gestito Identity di Azure per il controllo degli accessi in base al ruolo.
Altri sovraccarichi sono basati su:
- URI del blob e credenziale della chiave condivisa per l'archiviazione (StorageSharedKeyCredential).
- URI del blob con una firma di accesso condiviso.
- Stringa di connessione, nome del contenitore e nome del BLOB.
- Client BLOB (BlobClient).
Per altre informazioni sull'API e sull'autenticazione di Azure SDK, vedere Autenticare le app .NET nei servizi di Azure usando la libreria di AzureIdentity. Per indicazioni sulla registrazione, vedere Registrazione con Azure SDK per .NET: Registrazione senza registrazione client. Per le app che usano l'iniezione delle dipendenze, un'app può chiamare AddAzureClientsCore, passando true
per enableLogForwarding
, per creare e collegare l'infrastruttura di registrazione.
Program
Nel file in cui sono registrati i servizi:
TokenCredential? credential;
if (builder.Environment.IsProduction())
{
credential = new ManagedIdentityCredential("{MANAGED IDENTITY CLIENT ID}");
}
else
{
// Local development and testing only
DefaultAzureCredentialOptions options = new()
{
// Specify the tenant ID to use the dev credentials when running the app locally
// in Visual Studio.
VisualStudioTenantId = "{TENANT ID}",
SharedTokenCacheTenantId = "{TENANT ID}"
};
credential = new DefaultAzureCredential(options);
}
builder.Services.AddDataProtection()
.SetApplicationName("{APPLICATION NAME}")
.PersistKeysToAzureBlobStorage(new Uri("{BLOB URI}"), credential);
{MANAGED IDENTITY CLIENT ID}
: ID client gestito di Identity Azure (GUID).
{TENANT ID}
: ID del tenant.
{APPLICATION NAME}
: SetApplicationName imposta il nome univoco dell'app all'interno del sistema di protezione dei dati. Il valore deve corrispondere tra le distribuzioni dell'app.
{BLOB URI}
: URI completo del file di chiave. L'URI viene generato da Azure Storage quando si crea il file della chiave. Non usare un SAS.
Approccio alternativo alla firma di accesso condiviso (SAS): in alternativa all'uso di un'istanza gestita Identity per l'accesso al BLOB di chiavi in Archiviazione Blob di Azure, è possibile chiamare l'overload PersistKeysToAzureBlobStorage che accetta un URI del blob con un token SAS:
builder.Services.AddDataProtection()
.SetApplicationName("{APPLICATION NAME}")
.PersistKeysToAzureBlobStorage(new Uri("{BLOB URI WITH SAS}"));
In Startup.ConfigureServices
:
TokenCredential? credential;
if (_env.IsProduction())
{
credential = new ManagedIdentityCredential("{MANAGED IDENTITY CLIENT ID}");
}
else
{
// Local development and testing only
DefaultAzureCredentialOptions options = new()
{
// Specify the tenant ID to use the dev credentials when running the app locally
// in Visual Studio.
VisualStudioTenantId = "{TENANT ID}",
SharedTokenCacheTenantId = "{TENANT ID}"
};
credential = new DefaultAzureCredential(options);
}
services.AddDataProtection()
.SetApplicationName("{APPLICATION NAME}")
.PersistKeysToAzureBlobStorage(new Uri("{BLOB URI}"), credential);
{MANAGED IDENTITY CLIENT ID}
: ID client gestito di Identity Azure (GUID).
{TENANT ID}
: ID del tenant.
{APPLICATION NAME}
: SetApplicationName imposta il nome univoco dell'app all'interno del sistema di protezione dei dati. Il valore deve corrispondere tra le distribuzioni dell'app.
{BLOB URI}
: URI completo del file di chiave. L'URI viene generato da Azure Storage quando si crea il file della chiave. Non usare un SAS.
Esempio:
https://contoso.blob.core.windows.net/data-protection/keys.xml
Approccio alternativo alla firma di accesso condiviso (SAS): in alternativa all'uso di un'istanza gestita Identity per l'accesso al BLOB di chiavi in Archiviazione Blob di Azure, è possibile chiamare l'overload PersistKeysToAzureBlobStorage che accetta un URI del blob con un token SAS:
services.AddDataProtection()
.SetApplicationName("{APPLICATION NAME}")
.PersistKeysToAzureBlobStorage(new Uri("{BLOB URI WITH SAS}"));
{APPLICATION NAME}
: SetApplicationName imposta il nome univoco dell'app all'interno del sistema di protezione dei dati. Il valore deve corrispondere tra le distribuzioni dell'app.
{BLOB URI WITH SAS}
: URI completo in cui deve essere archiviato il file di chiave con il token di firma di accesso condiviso come parametro della stringa di query. L'URI viene generato da Archiviazione di Azure quando si richiede una firma di accesso condiviso per il file di chiave caricato. Nell'esempio seguente il nome del contenitore è data-protection
e il nome dell'account di archiviazione è contoso
. Il file di chiave è denominato keys.xml
. La stringa di query della firma di accesso condiviso (SAS) si trova alla fine dell'URI ({SHARED ACCESS SIGNATURE}
segnaposto).
Esempio:
https://contoso.blob.core.windows.net/data-protection/keys.xml{SHARED ACCESS SIGNATURE}
Se l'app Web è in esecuzione come servizio di Azure, è possibile usare una stringa di connessione per eseguire l'autenticazione in Archiviazione di Azure usando BlobContainerClient, come illustrato nell'esempio seguente.
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.
La chiamata facoltativa a CreateIfNotExistsAsync effettua automaticamente il provisioning del contenitore se questo non esiste.
La stringa di connessione ({CONNECTION STRING}
segnaposto) all'account di archiviazione è disponibile nella sezione Entra o nel portale di Azure nella sezione "Chiavi di accesso" o eseguendo il comando seguente dell'interfaccia della riga di comando di Azure:
az storage account show-connection-string --name <account_name> --resource-group <resource_group>
Program
Nel file in cui sono registrati i servizi:
string connectionString = "{CONNECTION STRING}";
string containerName = "{CONTAINER NAME}";
string blobName = "keys.xml";
var container = new BlobContainerClient(connectionString, containerName);
await container.CreateIfNotExistsAsync();
BlobClient blobClient = container.GetBlobClient(blobName);
builder.Services.AddDataProtection().PersistKeysToAzureBlobStorage(blobClient);
In Startup.ConfigureServices
:
string connectionString = "{CONNECTION STRING}";
string containerName = "{CONTAINER NAME}";
string blobName = "keys.xml";
var container = new BlobContainerClient(connectionString, containerName);
await container.CreateIfNotExistsAsync();
BlobClient blobClient = container.GetBlobClient(blobName);
services.AddDataProtection().PersistKeysToAzureBlobStorage(blobClient);
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:
- StackExchange.Redis ConnectionMultiplexer
- Cache Redis di Azure
- Esempi di ASP.NET Core DataProtection
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 (un framework ORM per la gestione dei database nello sviluppo software)
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) 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 meccanismo personalizzato IXmlRepository.