Provider di configurazione di Azure Key Vault in ASP.NET CoreAzure Key Vault Configuration Provider in ASP.NET Core

Di Luke Latham e Andrew Stanton-NurseBy Luke Latham and Andrew Stanton-Nurse

Questo documento illustra come usare il provider di configurazione Microsoft Azure Key Vault per caricare i valori di configurazione dell'app da Azure Key Vault segreti.This document explains how to use the Microsoft Azure Key Vault Configuration Provider to load app configuration values from Azure Key Vault secrets. Azure Key Vault è un servizio basato sul cloud che aiuta a proteggere le chiavi crittografiche e i segreti usati da app e servizi.Azure Key Vault is a cloud-based service that assists in safeguarding cryptographic keys and secrets used by apps and services. Gli scenari comuni per l'uso di Azure Key Vault con le app ASP.NET Core includono:Common scenarios for using Azure Key Vault with ASP.NET Core apps include:

  • Controllo dell'accesso ai dati di configurazione riservati.Controlling access to sensitive configuration data.
  • Soddisfare i requisiti per i moduli di protezione hardware convalidati FIPS 140-2 Level 2 (HSM) quando si archiviano i dati di configurazione.Meeting the requirement for FIPS 140-2 Level 2 validated Hardware Security Modules (HSM's) when storing configuration data.

Questo scenario è disponibile per le app destinate a ASP.NET Core 2,1 o versioni successive.This scenario is available for apps that target ASP.NET Core 2.1 or later.

Visualizzare o scaricare il codice di esempio (procedura per il download)View or download sample code (how to download)

PacchettiPackages

Per usare il provider di configurazione Azure Key Vault, aggiungere un riferimento al pacchetto Microsoft. Extensions. Configuration. AzureKeyVault .To use the Azure Key Vault Configuration Provider, add a package reference to the Microsoft.Extensions.Configuration.AzureKeyVault package.

Per adottare lo scenario delle identità gestite per le risorse di Azure , aggiungere un riferimento al pacchetto Microsoft. Azure. Services. AppAuthentication .To adopt the Managed identities for Azure resources scenario, add a package reference to the Microsoft.Azure.Services.AppAuthentication package.

Nota

Al momento della stesura di questo articolo, la versione Microsoft.Azure.Services.AppAuthentication 1.0.3stabile più recente di, fornisce il supporto per le identità gestite assegnate dal sistema.At the time of writing, the latest stable release of Microsoft.Azure.Services.AppAuthentication, version 1.0.3, provides support for system-assigned managed identities. Il supporto per le 1.2.0-preview2 identità gestite assegnate dall'utente è disponibile nel pacchetto.Support for user-assigned managed identities is available in the 1.2.0-preview2 package. Questo argomento illustra l'uso delle identità gestite dal sistema e l'app 1.0.3 Microsoft.Azure.Services.AppAuthentication di esempio fornita usa la versione del pacchetto.This topic demonstrates the use of system-managed identities, and the provided sample app uses version 1.0.3 of the Microsoft.Azure.Services.AppAuthentication package.

App di esempioSample app

L'app di esempio viene eseguita in una delle due modalità determinate #define dall'istruzione all'inizio del file Program.cs :The sample app runs in either of two modes determined by the #define statement at the top of the Program.cs file:

  • Certificate– Viene illustrato l'uso di un ID client Azure Key Vault e di un certificato X. 509 per accedere ai segreti archiviati nel Azure Key Vault.Certificate – Demonstrates the use of an Azure Key Vault Client ID and X.509 certificate to access secrets stored in Azure Key Vault. Questa versione dell'esempio può essere eseguita da qualsiasi posizione, distribuita nel servizio app Azure o in qualsiasi host in grado di servire un'app ASP.NET Core.This version of the sample can be run from any location, deployed to Azure App Service or any host capable of serving an ASP.NET Core app.
  • ManagedIllustra come usare le identità gestite per le risorse di Azure per autenticare l'app Azure Key Vault con Azure ad l'autenticazione senza credenziali archiviate nel codice o nella configurazione dell'app. –Managed – Demonstrates how to use Managed identities for Azure resources to authenticate the app to Azure Key Vault with Azure AD authentication without credentials stored in the app's code or configuration. Quando si usano identità gestite per l'autenticazione, non è necessario un Azure AD ID applicazione e una password (segreto client).When using managed identities to authenticate, an Azure AD Application ID and Password (Client Secret) aren't required. La Managed versione dell'esempio deve essere distribuita in Azure.The Managed version of the sample must be deployed to Azure. Seguire le istruzioni riportate nella sezione usare le identità gestite per le risorse di Azure .Follow the guidance in the Use the Managed identities for Azure resources section.

Per ulteriori informazioni su come configurare un'app di esempio utilizzando le direttive per il preprocessore#define( Introduzione a ASP.NET Core), vedere.For more information on how to configure a sample app using preprocessor directives (#define), see Introduzione a ASP.NET Core.

Archiviazione segreta nell'ambiente di sviluppoSecret storage in the Development environment

Impostare i segreti in locale usando lo strumento di gestione dei segreti.Set secrets locally using the Secret Manager tool. Quando l'app di esempio viene eseguita nel computer locale nell'ambiente di sviluppo, i segreti vengono caricati dall'archivio di gestione dei segreti locali.When the sample app runs on the local machine in the Development environment, secrets are loaded from the local Secret Manager store.

Lo strumento di gestione dei segreti <UserSecretsId> richiede una proprietà nel file di progetto dell'app.The Secret Manager tool requires a <UserSecretsId> property in the app's project file. Impostare il valore della proprietà{GUID}() su un GUID univoco:Set the property value ({GUID}) to any unique GUID:

<PropertyGroup>
  <UserSecretsId>{GUID}</UserSecretsId>
</PropertyGroup>

I segreti vengono creati come coppie nome/valore.Secrets are created as name-value pairs. I valori gerarchici (sezioni di configurazione) : utilizzano un (due punti) come separatore nei nomi delle chiavi di configurazione ASP.NET Core .Hierarchical values (configuration sections) use a : (colon) as a separator in ASP.NET Core configuration key names.

Il gestore del segreto viene usato da una shell dei comandi aperta alla radice del contenuto del progetto {SECRET NAME} , dove è il {SECRET VALUE} nome e è il valore:The Secret Manager is used from a command shell opened to the project's content root, where {SECRET NAME} is the name and {SECRET VALUE} is the value:

dotnet user-secrets set "{SECRET NAME}" "{SECRET VALUE}"

Eseguire i comandi seguenti in una shell dei comandi dalla radice del contenuto del progetto per impostare i segreti per l'app di esempio:Execute the following commands in a command shell from the project's content root to set the secrets for the sample app:

dotnet user-secrets set "SecretName" "secret_value_1_dev"
dotnet user-secrets set "Section:SecretName" "secret_value_2_dev"

Quando questi segreti vengono archiviati in Azure Key Vault nell' archiviazione segreta nell'ambiente di produzione con Azure Key Vault sezione, il _dev suffisso viene modificato in. _prodWhen these secrets are stored in Azure Key Vault in the Secret storage in the Production environment with Azure Key Vault section, the _dev suffix is changed to _prod. Il suffisso fornisce un segnale visivo nell'output dell'app che indica l'origine dei valori di configurazione.The suffix provides a visual cue in the app's output indicating the source of the configuration values.

Archiviazione segreta nell'ambiente di produzione con Azure Key VaultSecret storage in the Production environment with Azure Key Vault

Le istruzioni fornite dalla Guida introduttiva: Impostare e recuperare un segreto da Azure Key Vault usando l'interfaccia della riga di comando di Azure sono riepilogati di seguito per la creazione di un Azure Key Vault e l'archiviazione di segreti usati dall'app di esempio.The instructions provided by the Quickstart: Set and retrieve a secret from Azure Key Vault using Azure CLI topic are summarized here for creating an Azure Key Vault and storing secrets used by the sample app. Per ulteriori informazioni, vedere l'argomento.Refer to the topic for further details.

  1. Aprire Azure cloud shell usando uno dei metodi seguenti nel portale di Azure:Open Azure Cloud shell using any one of the following methods in the Azure portal:

    • Selezionare try it nell'angolo superiore destro di un blocco di codice.Select Try It in the upper-right corner of a code block. Usare la stringa di ricerca "interfaccia della riga di comando di Azure" nella casella di testo.Use the search string "Azure CLI" in the text box.
    • Aprire Cloud Shell nel browser con il pulsante avvia cloud Shell .Open Cloud Shell in your browser with the Launch Cloud Shell button.
    • Selezionare il pulsante cloud Shell nel menu nell'angolo in alto a destra del portale di Azure.Select the Cloud Shell button on the menu in the upper-right corner of the Azure portal.

    Per altre informazioni, vedere interfaccia della riga di comando di Azure e Panoramica di Azure cloud Shell.For more information, see Azure Command-Line Interface (CLI) and Overview of Azure Cloud Shell.

  2. Se non è già stato eseguito l'autenticazione, effettuare l' az login accesso con il comando.If you aren't already authenticated, sign in with the az login command.

  3. Creare un gruppo di risorse con il comando seguente, {RESOURCE GROUP NAME} dove è il nome del gruppo di risorse per il nuovo {LOCATION} gruppo di risorse e è l'area di Azure (Datacenter):Create a resource group with the following command, where {RESOURCE GROUP NAME} is the resource group name for the new resource group and {LOCATION} is the Azure region (datacenter):

    az group create --name "{RESOURCE GROUP NAME}" --location {LOCATION}
    
  4. Creare un insieme di credenziali delle chiavi nel gruppo di risorse con il comando {KEY VAULT NAME} seguente, dove è il nome del nuovo insieme {LOCATION} di credenziali delle chiavi e è l'area di Azure (Datacenter):Create a key vault in the resource group with the following command, where {KEY VAULT NAME} is the name for the new key vault and {LOCATION} is the Azure region (datacenter):

    az keyvault create --name "{KEY VAULT NAME}" --resource-group "{RESOURCE GROUP NAME}" --location {LOCATION}
    
  5. Creare segreti nell'insieme di credenziali delle chiavi come coppie nome/valore.Create secrets in the key vault as name-value pairs.

    Azure Key Vault nomi di segreto sono limitati a caratteri alfanumerici e trattini.Azure Key Vault secret names are limited to alphanumeric characters and dashes. I valori gerarchici (sezioni di configurazione -- ) usano (due trattini) come separatore.Hierarchical values (configuration sections) use -- (two dashes) as a separator. I due punti, che in genere vengono usati per delimitare una sezione da una sottochiave in ASP.NET Core configurazione, non sono consentiti nei nomi dei segreti di Key Vault.Colons, which are normally used to delimit a section from a subkey in ASP.NET Core configuration, aren't allowed in key vault secret names. Pertanto, vengono usati due trattini e scambiati per i due punti quando i segreti vengono caricati nella configurazione dell'app.Therefore, two dashes are used and swapped for a colon when the secrets are loaded into the app's configuration.

    I segreti seguenti sono da usare con l'app di esempio.The following secrets are for use with the sample app. I valori includono un _prod suffisso per distinguerli _dev dai valori dei suffissi caricati nell'ambiente di sviluppo da segreti utente.The values include a _prod suffix to distinguish them from the _dev suffix values loaded in the Development environment from User Secrets. Sostituire {KEY VAULT NAME} con il nome dell'insieme di credenziali delle chiavi creato nel passaggio precedente:Replace {KEY VAULT NAME} with the name of the key vault that you created in the prior step:

    az keyvault secret set --vault-name "{KEY VAULT NAME}" --name "SecretName" --value "secret_value_1_prod"
    az keyvault secret set --vault-name "{KEY VAULT NAME}" --name "Section--SecretName" --value "secret_value_2_prod"
    

Usare l'ID applicazione e il certificato X. 509 per le app non ospitate in AzureUse Application ID and X.509 certificate for non-Azure-hosted apps

Configurare Azure AD, Azure Key Vault e l'app per usare un ID applicazione Azure Active Directory e un certificato X. 509 per l'autenticazione in un insieme di credenziali delle chiavi quando l'app è ospitata all'esterno di Azure.Configure Azure AD, Azure Key Vault, and the app to use an Azure Active Directory Application ID and X.509 certificate to authenticate to a key vault when the app is hosted outside of Azure. Per ulteriori informazioni, vedere informazioni su chiavi, segreti e certificati.For more information, see About keys, secrets, and certificates.

Nota

Sebbene l'uso di un ID applicazione e di un certificato X. 509 sia supportato per le app ospitate in Azure, è consigliabile usare identità gestite per le risorse di Azure quando si ospita un'app in Azure.Although using an Application ID and X.509 certificate is supported for apps hosted in Azure, we recommend using Managed identities for Azure resources when hosting an app in Azure. Le identità gestite non richiedono l'archiviazione di un certificato nell'app o nell'ambiente di sviluppo.Managed identities don't require storing a certificate in the app or in the development environment.

L'app di esempio usa un ID applicazione e un certificato X. 509 #define quando l'istruzione all'inizio del file Program.cs è impostata su Certificate.The sample app uses an Application ID and X.509 certificate when the #define statement at the top of the Program.cs file is set to Certificate.

  1. Creare un certificato di archivio PKCS # 12 ( . pfx).Create a PKCS#12 archive (.pfx) certificate. Le opzioni per la creazione di certificati includono Makecert in Windows e openssl.Options for creating certificates include MakeCert on Windows and OpenSSL.
  2. Installare il certificato nell'archivio certificati personale dell'utente corrente.Install the certificate into the current user's personal certificate store. Contrassegnare la chiave come esportabile è facoltativa.Marking the key as exportable is optional. Prendere nota dell'identificazione personale del certificato, che verrà usato più avanti in questo processo.Note the certificate's thumbprint, which is used later in this process.
  3. Esportare il certificato di archiviazione PKCS # 12 ( . pfx) come certificato con codifica der ( . cer).Export the PKCS#12 archive (.pfx) certificate as a DER-encoded certificate (.cer).
  4. Registrare l'app con Azure AD (registrazioni app).Register the app with Azure AD (App registrations).
  5. Caricare il certificato con codifica DER ( . cer) in Azure ad:Upload the DER-encoded certificate (.cer) to Azure AD:
    1. Selezionare l'app in Azure AD.Select the app in Azure AD.
    2. Passare a certificati & segreti.Navigate to Certificates & secrets.
    3. Selezionare Carica certificato per caricare il certificato, che contiene la chiave pubblica.Select Upload certificate to upload the certificate, which contains the public key. Un certificato con estensione cer, PEMo CRT è accettabile.A .cer, .pem, or .crt certificate is acceptable.
  6. Archiviare il nome dell'insieme di credenziali delle chiavi, l'ID applicazione e l'identificazione personale del certificato nel file appSettings. JSON dell'app.Store the key vault name, Application ID, and certificate thumbprint in the app's appsettings.json file.
  7. Passare a insiemi di credenziali delle chiavi nella portale di Azure.Navigate to Key vaults in the Azure portal.
  8. Selezionare l'insieme di credenziali delle chiavi creato nell' Archivio Secret nell'ambiente di produzione con Azure Key Vault sezione.Select the key vault that you created in the Secret storage in the Production environment with Azure Key Vault section.
  9. Selezionare criteri di accesso.Select Access policies.
  10. Selezionare Aggiungi nuovo.Select Add new.
  11. Selezionare Seleziona entità e selezionare l'app registrata in base al nome.Select Select principal and select the registered app by name. Selezionare il pulsante Seleziona .Select the Select button.
  12. Aprire autorizzazioni segrete e fornire all'app le autorizzazioni Get ed List .Open Secret permissions and provide the app with Get and List permissions.
  13. Selezionare OK.Select OK.
  14. Selezionare Salva.Select Save.
  15. Distribuire l'app.Deploy the app.

L' Certificate app di esempio ottiene i valori di configurazione IConfigurationRoot da con lo stesso nome del nome del segreto:The Certificate sample app obtains its configuration values from IConfigurationRoot with the same name as the secret name:

  • Valori non gerarchici: Il valore per SecretName viene ottenuto con config["SecretName"].Non-hierarchical values: The value for SecretName is obtained with config["SecretName"].
  • Valori gerarchici (sezioni): Usare : la notazione (due punti) GetSection o il metodo di estensione.Hierarchical values (sections): Use : (colon) notation or the GetSection extension method. Per ottenere il valore di configurazione, usare uno di questi approcci:Use either of these approaches to obtain the configuration value:
    • config["Section:SecretName"]
    • config.GetSection("Section")["SecretName"]

Il certificato X. 509 è gestito dal sistema operativo.The X.509 certificate is managed by the OS. L'app chiama AddAzureKeyVault con i valori forniti dal file appSettings. JSON :The app calls AddAzureKeyVault with values supplied by the appsettings.json file:

// using System.Linq;
// using System.Security.Cryptography.X509Certificates;
// using Microsoft.Extensions.Configuration;
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .ConfigureAppConfiguration((context, config) =>
        {
            if (context.HostingEnvironment.IsProduction())
            {
                var builtConfig = config.Build();

                using (var store = new X509Store(StoreName.My,
                    StoreLocation.CurrentUser))
                {
                    store.Open(OpenFlags.ReadOnly);
                    var certs = store.Certificates
                        .Find(X509FindType.FindByThumbprint,
                            builtConfig["AzureADCertThumbprint"], false);

                    config.AddAzureKeyVault(
                        $"https://{builtConfig["KeyVaultName"]}.vault.azure.net/",
                        builtConfig["AzureADApplicationId"],
                        certs.OfType<X509Certificate2>().Single());

                    store.Close();
                }
            }
        })
        .UseStartup<Startup>();

Valori di esempio:Example values:

  • Nome dell'insieme di credenziali delle chiavi:contosovaultKey vault name: contosovault
  • ID applicazione:627e911e-43cc-61d4-992e-12db9c81b413Application ID: 627e911e-43cc-61d4-992e-12db9c81b413
  • Identificazione personale del certificato:fe14593dd66b2406c5269d742d04b6e1ab03adb1Certificate thumbprint: fe14593dd66b2406c5269d742d04b6e1ab03adb1

appsettings.json:appsettings.json:

{
  "KeyVaultName": "Key Vault Name",
  "AzureADApplicationId": "Azure AD Application ID",
  "AzureADCertThumbprint": "Azure AD Certificate Thumbprint"
}

Quando si esegue l'app, in una pagina Web vengono visualizzati i valori dei segreti caricati.When you run the app, a webpage shows the loaded secret values. Nell'ambiente di sviluppo, i valori Secret vengono caricati _dev con il suffisso.In the Development environment, secret values load with the _dev suffix. Nell'ambiente di produzione, i valori vengono caricati con _prod il suffisso.In the Production environment, the values load with the _prod suffix.

Usare identità gestite per le risorse di AzureUse Managed identities for Azure resources

Un'app distribuita in Azure può sfruttare le identità gestite per le risorse di Azure, che consentono all'app di eseguire l'autenticazione con Azure Key Vault usando l'autenticazione Azure ad senza credenziali (ID applicazione e password/segreto client) archiviati nell'app.An app deployed to Azure can take advantage of Managed identities for Azure resources, which allows the app to authenticate with Azure Key Vault using Azure AD authentication without credentials (Application ID and Password/Client Secret) stored in the app.

L'app di esempio usa le identità gestite per le risorse di #define Azure quando l'istruzione all'inizio del file Program.cs è impostata Managedsu.The sample app uses Managed identities for Azure resources when the #define statement at the top of the Program.cs file is set to Managed.

Immettere il nome dell'insieme di credenziali nel file appSettings. JSON dell'app.Enter the vault name into the app's appsettings.json file. L'app di esempio non richiede un ID applicazione e una password (segreto client) quando è Managed impostata sulla versione, in modo che sia possibile ignorare tali voci di configurazione.The sample app doesn't require an Application ID and Password (Client Secret) when set to the Managed version, so you can ignore those configuration entries. L'app viene distribuita in Azure e Azure autentica l'app per accedere Azure Key Vault solo usando il nome dell'insieme di credenziali archiviato nel file appSettings. JSON .The app is deployed to Azure, and Azure authenticates the app to access Azure Key Vault only using the vault name stored in the appsettings.json file.

Distribuire l'app di esempio nel servizio app Azure.Deploy the sample app to Azure App Service.

Un'app distribuita nel servizio app Azure viene registrata automaticamente con Azure AD quando viene creato il servizio.An app deployed to Azure App Service is automatically registered with Azure AD when the service is created. Ottenere l'ID oggetto dalla distribuzione per utilizzarlo nel comando seguente.Obtain the Object ID from the deployment for use in the following command. L'ID oggetto viene visualizzato nella portale di Azure nel pannello identità del servizio app.The Object ID is shown in the Azure portal on the Identity panel of the App Service.

Usando l'interfaccia della riga di comando di Azure e l'ID oggetto dell' list app get , fornire all'app le autorizzazioni e per accedere all'insieme di credenziali delle chiavi:Using Azure CLI and the app's Object ID, provide the app with list and get permissions to access the key vault:

az keyvault set-policy --name '{KEY VAULT NAME}' --object-id {OBJECT ID} --secret-permissions get list

Riavviare l'app usando l'interfaccia della riga di comando di Azure, PowerShell o la portale di Azure.Restart the app using Azure CLI, PowerShell, or the Azure portal.

App di esempio:The sample app:

  • Crea un'istanza della AzureServiceTokenProvider classe senza una stringa di connessione.Creates an instance of the AzureServiceTokenProvider class without a connection string. Quando non viene specificata una stringa di connessione, il provider tenta di ottenere un token di accesso dalle identità gestite per le risorse di Azure.When a connection string isn't provided, the provider attempts to obtain an access token from Managed identities for Azure resources.
  • Viene creato KeyVaultClient un nuovo oggetto con AzureServiceTokenProvider il callback del token dell'istanza.A new KeyVaultClient is created with the AzureServiceTokenProvider instance token callback.
  • L' KeyVaultClient istanza viene utilizzata con un'implementazione predefinita di IKeyVaultSecretManager che carica tutti i valori del segreto e sostituisce i doppi trattini (--) con i:due punti () nei nomi delle chiavi.The KeyVaultClient instance is used with a default implementation of IKeyVaultSecretManager that loads all secret values and replaces double-dashes (--) with colons (:) in key names.
// using Microsoft.Azure.KeyVault;
// using Microsoft.Azure.Services.AppAuthentication;
// using Microsoft.Extensions.Configuration.AzureKeyVault;

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .ConfigureAppConfiguration((context, config) =>
        {
            if (context.HostingEnvironment.IsProduction())
            {
                var builtConfig = config.Build();

                    var azureServiceTokenProvider = new AzureServiceTokenProvider();
                    var keyVaultClient = new KeyVaultClient(
                        new KeyVaultClient.AuthenticationCallback(
                            azureServiceTokenProvider.KeyVaultTokenCallback));

                    config.AddAzureKeyVault(
                        $"https://{builtConfig["KeyVaultName"]}.vault.azure.net/",
                        keyVaultClient,
                        new DefaultKeyVaultSecretManager());
            }
        })
        .UseStartup<Startup>();

Quando si esegue l'app, in una pagina Web vengono visualizzati i valori dei segreti caricati.When you run the app, a webpage shows the loaded secret values. Nell'ambiente di sviluppo i valori Secret hanno il _dev suffisso perché sono forniti da segreti utente.In the Development environment, secret values have the _dev suffix because they're provided by User Secrets. Nell'ambiente di produzione, i valori vengono caricati con _prod il suffisso perché sono forniti da Azure Key Vault.In the Production environment, the values load with the _prod suffix because they're provided by Azure Key Vault.

Se viene visualizzato un Access denied errore, verificare che l'app sia registrata con Azure ad e che l'accesso sia stato fornito all'insieme di credenziali delle chiavi.If you receive an Access denied error, confirm that the app is registered with Azure AD and provided access to the key vault. Confermare di aver riavviato il servizio in Azure.Confirm that you've restarted the service in Azure.

Usa prefisso nome chiaveUse a key name prefix

AddAzureKeyVaultfornisce un overload che accetta un'implementazione di IKeyVaultSecretManager, che consente di controllare la modalità di conversione dei segreti dell'insieme di credenziali delle chiavi in chiavi di configurazione.AddAzureKeyVault provides an overload that accepts an implementation of IKeyVaultSecretManager, which allows you to control how key vault secrets are converted into configuration keys. Ad esempio, è possibile implementare l'interfaccia per caricare i valori dei segreti in base a un valore di prefisso fornito all'avvio dell'app.For example, you can implement the interface to load secret values based on a prefix value you provide at app startup. Questo consente, ad esempio, di caricare i segreti in base alla versione dell'app.This allows you, for example, to load secrets based on the version of the app.

Avviso

Non usare i prefissi sui segreti dell'insieme di credenziali delle chiavi per collocare i segreti per più app nello stesso insieme di credenziali delle chiavi o per collocare i segreti ambientali (ad esempio, sviluppo rispetto ai segreti di produzione ) nello stesso insieme di credenziali.Don't use prefixes on key vault secrets to place secrets for multiple apps into the same key vault or to place environmental secrets (for example, development versus production secrets) into the same vault. È consigliabile che app e ambienti di sviluppo/produzione diversi usino insiemi di credenziali delle chiavi distinti per isolare gli ambienti app per il massimo livello di sicurezza.We recommend that different apps and development/production environments use separate key vaults to isolate app environments for the highest level of security.

Nell'esempio seguente viene stabilito un segreto nell'insieme di credenziali delle chiavi (e usando lo strumento di gestione dei segreti per l'ambiente di 5000-AppSecret sviluppo) per (i periodi non sono consentiti nei nomi dei segreti dell'insieme di credenziali delle chiavi).In the following example, a secret is established in the key vault (and using the Secret Manager tool for the Development environment) for 5000-AppSecret (periods aren't allowed in key vault secret names). Questo segreto rappresenta un segreto app per la versione 5.0.0.0 dell'app.This secret represents an app secret for version 5.0.0.0 of the app. Per un'altra versione dell'app, 5.1.0.0, viene aggiunto un segreto all'insieme di credenziali delle chiavi (e usando lo strumento di gestione 5100-AppSecretdei segreti) per.For another version of the app, 5.1.0.0, a secret is added to the key vault (and using the Secret Manager tool) for 5100-AppSecret. Ogni versione dell'app carica il valore del segreto con versione nella configurazione AppSecretcome, rimuovendo la versione durante il caricamento del segreto.Each app version loads its versioned secret value into its configuration as AppSecret, stripping off the version as it loads the secret.

AddAzureKeyVaultviene chiamato con un oggetto IKeyVaultSecretManagerpersonalizzato:AddAzureKeyVault is called with a custom IKeyVaultSecretManager:

// using System.Reflection;
// using Microsoft.Azure.KeyVault;
// using Microsoft.Azure.Services.AppAuthentication;
// using Microsoft.Extensions.Configuration;
// using Microsoft.Extensions.Configuration.AzureKeyVault;

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .ConfigureAppConfiguration((context, config) =>
        {
            if (context.HostingEnvironment.IsProduction())
            {
                // The appVersion obtains the app version (5.0.0.0), which 
                // is set in the project file and obtained from the entry 
                // assembly. The versionPrefix holds the version without 
                // dot notation for the PrefixKeyVaultSecretManager.
                var appVersion = Assembly.GetEntryAssembly().GetName().Version.ToString();
                var versionPrefix = appVersion.Replace(".", string.Empty);

                var builtConfig = config.Build();

                using (var store = new X509Store(StoreName.My,
                    StoreLocation.CurrentUser))
                {
                    store.Open(OpenFlags.ReadOnly);
                    var certs = store.Certificates
                        .Find(X509FindType.FindByThumbprint,
                            builtConfig["AzureADCertThumbprint"], false);

                    config.AddAzureKeyVault(
                        $"https://{builtConfig["KeyVaultName"]}.vault.azure.net/",
                        builtConfig["AzureADApplicationId"],
                        certs.OfType<X509Certificate2>().Single(),
                        new PrefixKeyVaultSecretManager(versionPrefix));

                    store.Close();
                }
            }
        })
        .UseStartup<Startup>();

L' IKeyVaultSecretManager implementazione reagisce ai prefissi di versione dei segreti per caricare il segreto appropriato nella configurazione:The IKeyVaultSecretManager implementation reacts to the version prefixes of secrets to load the proper secret into configuration:

public class PrefixKeyVaultSecretManager : IKeyVaultSecretManager
{
    private readonly string _prefix;

    public PrefixKeyVaultSecretManager(string prefix)
    {
        _prefix = $"{prefix}-";
    }

    public bool Load(SecretItem secret)
    {
        // Load a vault secret when its secret name starts with the 
        // prefix. Other secrets won't be loaded.
        return secret.Identifier.Name.StartsWith(_prefix);
    }

    public string GetKey(SecretBundle secret)
    {
        // Remove the prefix from the secret name and replace two 
        // dashes in any name with the KeyDelimiter, which is the 
        // delimiter used in configuration (usually a colon). Azure 
        // Key Vault doesn't allow a colon in secret names.
        return secret.SecretIdentifier.Name
            .Substring(_prefix.Length)
            .Replace("--", ConfigurationPath.KeyDelimiter);
    }
}

Il Load metodo viene chiamato da un algoritmo del provider che scorre i segreti dell'insieme di credenziali per trovare quelli con il prefisso della versione.The Load method is called by a provider algorithm that iterates through the vault secrets to find the ones that have the version prefix. Quando viene trovato un prefisso di versione Loadcon, l'algoritmo usa GetKey il metodo per restituire il nome della configurazione del nome del segreto.When a version prefix is found with Load, the algorithm uses the GetKey method to return the configuration name of the secret name. Rimuove il prefisso della versione dal nome del segreto e restituisce il resto del nome del segreto per il caricamento nelle coppie nome-valore della configurazione dell'app.It strips off the version prefix from the secret's name and returns the rest of the secret name for loading into the app's configuration name-value pairs.

Quando viene implementato questo approccio:When this approach is implemented:

  1. La versione dell'app specificata nel file di progetto dell'app.The app's version specified in the app's project file. Nell'esempio seguente la versione dell'app è impostata su 5.0.0.0:In the following example, the app's version is set to 5.0.0.0:

    <PropertyGroup>
      <Version>5.0.0.0</Version>
    </PropertyGroup>
    
  2. Verificare che sia <UserSecretsId> presente una proprietà nel file di progetto dell'app, dove {GUID} è un GUID fornito dall'utente:Confirm that a <UserSecretsId> property is present in the app's project file, where {GUID} is a user-supplied GUID:

    <PropertyGroup>
      <UserSecretsId>{GUID}</UserSecretsId>
    </PropertyGroup>
    

    Salvare i segreti seguenti localmente con lo strumento di gestione dei segreti:Save the following secrets locally with the Secret Manager tool:

    dotnet user-secrets set "5000-AppSecret" "5.0.0.0_secret_value_dev"
    dotnet user-secrets set "5100-AppSecret" "5.1.0.0_secret_value_dev"
    
  3. I segreti vengono salvati in Azure Key Vault usando i comandi dell'interfaccia della riga di comando di Azure seguenti:Secrets are saved in Azure Key Vault using the following Azure CLI commands:

    az keyvault secret set --vault-name "{KEY VAULT NAME}" --name "5000-AppSecret" --value "5.0.0.0_secret_value_prod"
    az keyvault secret set --vault-name "{KEY VAULT NAME}" --name "5100-AppSecret" --value "5.1.0.0_secret_value_prod"
    
  4. Quando l'app viene eseguita, vengono caricati i segreti dell'insieme di credenziali delle chiavi.When the app is run, the key vault secrets are loaded. La stringa segreta per 5000-AppSecret viene confrontata con la versione dell'app specificata nel file di progetto dell'app5.0.0.0().The string secret for 5000-AppSecret is matched to the app's version specified in the app's project file (5.0.0.0).

  5. La versione 5000 (con il trattino) viene rimossa dal nome della chiave.The version, 5000 (with the dash), is stripped from the key name. In tutta l'app, la lettura della configurazione AppSecret con la chiave carica il valore del segreto.Throughout the app, reading configuration with the key AppSecret loads the secret value.

  6. Se la versione dell'app viene modificata nel file di 5.1.0.0 progetto in e l'app viene nuovamente eseguita, il valore del segreto restituito è 5.1.0.0_secret_value_dev nell'ambiente di sviluppo 5.1.0.0_secret_value_prod e in produzione.If the app's version is changed in the project file to 5.1.0.0 and the app is run again, the secret value returned is 5.1.0.0_secret_value_dev in the Development environment and 5.1.0.0_secret_value_prod in Production.

Nota

È anche possibile fornire un'implementazione KeyVaultClient personalizzata a AddAzureKeyVault.You can also provide your own KeyVaultClient implementation to AddAzureKeyVault. Un client personalizzato consente la condivisione di una singola istanza del client nell'app.A custom client permits sharing a single instance of the client across the app.

Associare una matrice a una classeBind an array to a class

Il provider è in grado di leggere i valori di configurazione in una matrice per l'associazione a una matrice POCO.The provider is capable of reading configuration values into an array for binding to a POCO array.

Quando si legge da un'origine di configurazione che consente alle chiavi di:contenere separatori di due punti (), viene usato un segmento di chiave numerico per distinguere le chiavi:0:che :1:costituiscono una matrice (,,...When reading from a configuration source that allows keys to contain colon (:) separators, a numeric key segment is used to distinguish the keys that make up an array (:0:, :1:, … :{n}:).:{n}:). Per ulteriori informazioni, vedere la pagina relativa alla configurazione. Associare una matrice a una classe.For more information, see Configuration: Bind an array to a class.

Azure Key Vault chiavi non possono utilizzare i due punti come separatore.Azure Key Vault keys can't use a colon as a separator. L'approccio descritto in questo argomento USA trattini doppi (--) come separatore per i valori gerarchici (sezioni).The approach described in this topic uses double dashes (--) as a separator for hierarchical values (sections). Le chiavi di matrice vengono archiviate in Azure Key Vault con trattini doppi e segmenti--0--di --1--chiave … numerica (,, --{n}--).Array keys are stored in Azure Key Vault with double dashes and numeric key segments (--0--, --1--, … --{n}--).

Esaminare la seguente configurazione del provider di registrazione Serilog fornita da un file JSON.Examine the following Serilog logging provider configuration provided by a JSON file. Nella matrice sono definiti due valori letterali di WriteTo oggetto che riflettono due sinkSerilog, che descrivono le destinazioni per la registrazione dell'output:There are two object literals defined in the WriteTo array that reflect two Serilog sinks, which describe destinations for logging output:

"Serilog": {
  "WriteTo": [
    {
      "Name": "AzureTableStorage",
      "Args": {
        "storageTableName": "logs",
        "connectionString": "DefaultEnd...ountKey=Eby8...GMGw=="
      }
    },
    {
      "Name": "AzureDocumentDB",
      "Args": {
        "endpointUrl": "https://contoso.documents.azure.com:443",
        "authorizationKey": "Eby8...GMGw=="
      }
    }
  ]
}

La configurazione mostrata nel file JSON precedente viene archiviata in Azure Key Vault usando la notazione--a doppio trattino () e i segmenti numerici:The configuration shown in the preceding JSON file is stored in Azure Key Vault using double dash (--) notation and numeric segments:

ChiaveKey ValueValue
Serilog--WriteTo--0--Name AzureTableStorage
Serilog--WriteTo--0--Args--storageTableName logs
Serilog--WriteTo--0--Args--connectionString DefaultEnd...ountKey=Eby8...GMGw==
Serilog--WriteTo--1--Name AzureDocumentDB
Serilog--WriteTo--1--Args--endpointUrl https://contoso.documents.azure.com:443
Serilog--WriteTo--1--Args--authorizationKey Eby8...GMGw==

Ricarica segretiReload secrets

I segreti vengono memorizzati IConfigurationRoot.Reload() nella cache finché non viene chiamato.Secrets are cached until IConfigurationRoot.Reload() is called. I segreti scaduti, disabilitati e aggiornati nell'insieme di credenziali delle chiavi non vengono rispettati Reload dall'app fino a quando non viene eseguito.Expired, disabled, and updated secrets in the key vault are not respected by the app until Reload is executed.

Configuration.Reload();

Segreti disabilitati e scadutiDisabled and expired secrets

I segreti disabilitati e scaduti KeyVaultClientException generano un oggetto in fase di esecuzione.Disabled and expired secrets throw a KeyVaultClientException at runtime. Per impedire che l'app venga generata, fornire la configurazione usando un provider di configurazione diverso o aggiornare il segreto disabilitato o scaduto.To prevent the app from throwing, provide the configuration using a different configuration provider or update the disabled or expired secret.

Risolvere problemiTroubleshoot

Quando l'app non riesce a caricare la configurazione usando il provider, viene scritto un messaggio di errore nell' infrastruttura di registrazione ASP.NET Core.When the app fails to load configuration using the provider, an error message is written to the ASP.NET Core Logging infrastructure. Le condizioni seguenti impediranno il caricamento della configurazione:The following conditions will prevent configuration from loading:

  • L'app o il certificato non è configurato correttamente in Azure Active Directory.The app or certificate isn't configured correctly in Azure Active Directory.
  • L'insieme di credenziali delle chiavi non esiste in Azure Key Vault.The key vault doesn't exist in Azure Key Vault.
  • L'app non è autorizzata ad accedere all'insieme di credenziali delle chiavi.The app isn't authorized to access the key vault.
  • Il criterio di accesso non Get include List le autorizzazioni e.The access policy doesn't include Get and List permissions.
  • Nell'insieme di credenziali delle chiavi i dati di configurazione (coppia nome-valore) sono denominati, mancanti, disabilitati o scaduti in modo errato.In the key vault, the configuration data (name-value pair) is incorrectly named, missing, disabled, or expired.
  • L'app presenta il nome dell'insieme di credenzialiKeyVaultNamedelle chiavi errato (),AzureADApplicationIdAzure ad ID applicazione () o l'AzureADCertThumbprintidentificazione personale del certificato Azure ad ().The app has the wrong key vault name (KeyVaultName), Azure AD Application Id (AzureADApplicationId), or Azure AD certificate thumbprint (AzureADCertThumbprint).
  • La chiave di configurazione (nome) non è corretta nell'app per il valore che si sta provando a caricare.The configuration key (name) is incorrect in the app for the value you're trying to load.

Risorse aggiuntiveAdditional resources