Esercitazione: usare un'identità gestita per connettere Key Vault a un'app Web di Azure in .NET

Azure Key Vault consente di archiviare credenziali e altri segreti con un maggiore livello di sicurezza. Per recuperare questi elementi, è tuttavia necessario eseguire l'autenticazione del codice con Key Vault. Nella Identità gestite per le risorse di Azure viene spiegato come risolvere il problema, assegnando ai servizi di Azure un'identità gestita automaticamente in Microsoft Entra ID. È possibile usare questa identità per l'autenticazione a qualsiasi servizio che supporti l'autenticazione di Microsoft Entra, incluso Key Vault, senza visualizzare le credenziali nel codice.

In questa esercitazione si crea e si distribuisce un'applicazione Web di Azure nel servizio app di Azure. Si userà un'identità gestita per autenticare l'app Web di Azure con un insieme di credenziali delle chiavi di Azure usando la libreria client di segreti di Azure Key Vault per .NET e l'interfaccia della riga di comando di Azure. Valgono gli stessi principi di base se si usa il linguaggio di programmazione preferito, Azure PowerShell e/o il portale di Azure.

Per altre informazioni sulle applicazioni Web del servizio app di Azure e sulla distribuzione presentate in questa esercitazione, vedere:

Prerequisiti

Per completare questa esercitazione è necessario:

Se l'applicazione Web è già stata distribuita nel servizio app di Azure, è possibile passare direttamente alle sezioni Configurare l'accesso dell'app Web all'insieme di credenziali delle chiavi e Modificare il codice dell'applicazione Web.

Creare un'app .NET Core

In questo passaggio si configurerà il progetto .NET Core locale.

In una finestra del terminale nel computer creare una directory denominata akvwebapp e impostarla come directory corrente:

mkdir akvwebapp
cd akvwebapp

Creare un'app .NET Core con il comando dotnet new web:

dotnet new web

Eseguire l'applicazione in locale in modo da vedere l'aspetto che avrà dopo la distribuzione in Azure:

dotnet run

In un Web browser passare all'app all'indirizzo http://localhost:5000.

Nella pagina verrà visualizzato il messaggio “Hello World” dell'app di esempio.

Per altre informazioni sulla creazione di applicazioni Web per Azure, vedere Creare un'app Web ASP.NET Core nel servizio app di Azure

Distribuire l'app in Azure

In questo passaggio l'applicazione .NET Core viene distribuita nel servizio app di Azure tramite Git locale. Per altre informazioni su come creare e distribuire applicazioni, vedere Creare un'app Web ASP.NET Core in Azure.

Configurare la distribuzione con Git locale

Nella finestra del terminale premere CTRL+C per chiudere il server Web. Inizializzare un repository Git per il progetto .NET Core:

git init --initial-branch=main
git add .
git commit -m "first commit"

È possibile usare FTP e l'istanza Git locale per distribuire un'app Web di Azure tramite un utente della distribuzione. Dopo averlo configurato, l'utente della distribuzione può essere usato per tutte le distribuzioni di Azure. Il nome utente e la password della distribuzione a livello di account sono diversi dalle credenziali della sottoscrizione di Azure.

Per configurare l'utente della distribuzione, eseguire il comando az webapp deployment user set. Scegliere un nome utente e una password che rispettino le linee guida seguenti:

  • Il nome utente deve essere univoco in Azure. Per i push nell'istanza Git locale, non può contenere il simbolo di chiocciola (@).
  • La password deve essere composta da almeno otto caratteri e contenere due dei tre elementi seguenti: lettere, numeri e simboli.
az webapp deployment user set --user-name "<username>" --password "<password>"

L'output JSON mostra la password come null. Se viene visualizzato un errore 'Conflict'. Details: 409, cambiare il nome utente. Se viene visualizzato un errore 'Bad Request'. Details: 400, usare una password più complessa.

Registrare il nome utente e la password in modo da poterle usare per distribuire le app Web.

Creare un gruppo di risorse

Un gruppo di risorse è un contenitore logico in cui si distribuiscono e si gestiscono le risorse di Azure. Creare un gruppo di risorse in cui inserire sia l'insieme di credenziali delle chiavi che l'app Web usando il comando az group create:

az group create --name "myResourceGroup" -l "EastUS"

Creare un piano di servizio app

Creare un piano di servizio app usando il comando az appservice plan create dell'interfaccia della riga di comando di Azure. L'esempio seguente crea un piano di servizio app denominato myAppServicePlan nel piano tariffario FREE:

az appservice plan create --name myAppServicePlan --resource-group myResourceGroup --sku FREE

Una volta creato il piano di servizio app, l'interfaccia della riga di comando di Azure visualizza informazioni simili a quelle riportate di seguito:

{ 
  "adminSiteName": null,
  "appServicePlanName": "myAppServicePlan",
  "geoRegion": "West Europe",
  "hostingEnvironmentProfile": null,
  "id": "/subscriptions/0000-0000/resourceGroups/myResourceGroup/providers/Microsoft.Web/serverfarms/myAppServicePlan",
  "kind": "app",
  "location": "West Europe",
  "maximumNumberOfWorkers": 1,
  "name": "myAppServicePlan",
  < JSON data removed for brevity. >
  "targetWorkerSizeId": 0,
  "type": "Microsoft.Web/serverfarms",
  "workerTierName": null
} 

Per altre informazioni, vedere Gestire un piano di servizio app in Azure.

Creare un'app Web

Creare un'app Web di Azure nel piano di servizio app myAppServicePlan.

Importante

Analogamente a un insieme di credenziali delle chiavi, un'app Web di Azure deve avere un nome univoco. Negli esempi seguenti sostituire <your-webapp-name> con il nome dell'app Web.

az webapp create --resource-group "myResourceGroup" --plan "myAppServicePlan" --name "<your-webapp-name>" --deployment-local-git

Dopo la creazione dell'app Web, l'interfaccia della riga di comando di Azure mostra un output simile a quello riportato di seguito:

Local git is configured with url of 'https://<username>@<your-webapp-name>.scm.azurewebsites.net/<ayour-webapp-name>.git'
{
  "availabilityState": "Normal",
  "clientAffinityEnabled": true,
  "clientCertEnabled": false,
  "clientCertExclusionPaths": null,
  "cloningInfo": null,
  "containerSize": 0,
  "dailyMemoryTimeQuota": 0,
  "defaultHostName": "<your-webapp-name>.azurewebsites.net",
  "deploymentLocalGitUrl": "https://<username>@<your-webapp-name>.scm.azurewebsites.net/<your-webapp-name>.git",
  "enabled": true,
  < JSON data removed for brevity. >
}

L'URL dell'istanza Git remota è visualizzato nella proprietà deploymentLocalGitUrl, nel formato https://<username>@<your-webapp-name>.scm.azurewebsites.net/<your-webapp-name>.git. Salvare questo URL. in quanto sarà necessario più avanti.

Configurare ora l'app Web per la distribuzione dal ramo main :

 az webapp config appsettings set -g MyResourceGroup --name "<your-webapp-name>" --settings deployment_branch=main

Passare alla nuova app usando il comando seguente. Sostituire <your-webapp-name> con il nome dell'app.

https://<your-webapp-name>.azurewebsites.net

Verrà visualizzata la pagina Web predefinita di una nuova app Web di Azure.

Distribuire l'app locale

Nella finestra del terminale locale aggiungere un'istanza remota di Azure al repository Git locale. Nel comando seguente sostituire <deploymentLocalGitUrl-from-create-step> con l'URL dell'istanza Git remota salvato nella sezione Creare un'app Web.

git remote add azure <deploymentLocalGitUrl-from-create-step>

Usare il comando seguente per eseguire il push all'istanza remota di Azure per distribuire l'app. Quando Git Credential Manager richiede le credenziali, usare quelle create nella sezione Configurare la distribuzione con Git locale.

git push azure main

L'esecuzione del comando può impiegare alcuni minuti. Durante l'esecuzione, il comando visualizza informazioni simili a quelle riportate di seguito:

Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 285 bytes | 95.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0
remote: Deploy Async
remote: Updating branch 'main'.
remote: Updating submodules.
remote: Preparing deployment for commit id 'd6b54472f7'.
remote: Repository path is /home/site/repository
remote: Running oryx build...
remote: Build orchestrated by Microsoft Oryx, https://github.com/Microsoft/Oryx
remote: You can report issues at https://github.com/Microsoft/Oryx/issues
remote:
remote: Oryx Version      : 0.2.20200114.13, Commit: 204922f30f8e8d41f5241b8c218425ef89106d1d, ReleaseTagName: 20200114.13
remote: Build Operation ID: |imoMY2y77/s=.40ca2a87_
remote: Repository Commit : d6b54472f7e8e9fd885ffafaa64522e74cf370e1
.
.
.
remote: Deployment successful.
remote: Deployment Logs : 'https://<your-webapp-name>.scm.azurewebsites.net/newui/jsonviewer?view_url=/api/deployments/d6b54472f7e8e9fd885ffafaa64522e74cf370e1/log'
To https://<your-webapp-name>.scm.azurewebsites.net:443/<your-webapp-name>.git
   d87e6ca..d6b5447  main -> main

Passare all'applicazione distribuita (o aggiornare la pagina) usando il Web browser:

http://<your-webapp-name>.azurewebsites.net

Verrà visualizzato il messaggio "Hello World!" visualizzato in precedenza quando si è visitato http://localhost:5000.

Per altre informazioni sulla distribuzione di applicazioni Web tramite Git, vedere Distribuzione dell'archivio Git locale nel servizio app di Azure

Configurare l'app Web per la connessione a Key Vault

In questa sezione si configurerà l'accesso Web a Key Vault e si aggiornerà il codice dell'applicazione per recuperare un segreto da Key Vault.

Creare e assegnare un'identità gestita

In questa esercitazione si userà l'identità gestita per eseguire l'autenticazione con Key Vault. L'identità gestita gestisce automaticamente le credenziali delle applicazioni.

Nell'interfaccia della riga di comando di Azure eseguire il comando az webapp-identity assign per creare l'identità per l'applicazione:

az webapp identity assign --name "<your-webapp-name>" --resource-group "myResourceGroup"

Il comando restituirà il frammento JSON seguente:

{
  "principalId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "tenantId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "type": "SystemAssigned"
}

Per concedere all'app Web l'autorizzazione per eseguire operazioni get e list sull'insieme di credenziali delle chiavi, passare principalId al comando az keyvault set-policy dell'interfaccia della riga di comando di Azure:

az keyvault set-policy --name "<your-keyvault-name>" --object-id "<principalId>" --secret-permissions get list

È anche possibile assegnare criteri di accesso usando il portale di Azure o PowerShell.

Modificare l'app per l'accesso all'insieme di credenziali delle chiavi

In questa esercitazione si userà la libreria client dei segreti di Azure Key Vault a scopo dimostrativo. Si può usare anche la libreria client dei certificati di Azure Key Vault o la libreria client delle chiavi di Azure Key Vault.

Installare i pacchetti

Nella finestra del terminale installare la libreria client dei segreti di Azure Key Vault per .NET e i pacchetti della libreria client delle identità di Azure:

dotnet add package Azure.Identity
dotnet add package Azure.Security.KeyVault.Secrets

Aggiornare il codice

Trovare e aprire il file Startup.cs per .NET 5.0 o versioni precedenti oppure Program.cs file per .NET 6.0 nel progetto akvwebapp.

Aggiungere queste righe all'intestazione:

using Azure.Identity;
using Azure.Security.KeyVault.Secrets;
using Azure.Core;

Aggiungere le righe seguenti prima della chiamata di app.UseEndpoints (.NET 5.0 o precedente), o della chiamata di app.MapGet (.NET 6.0), aggiornando l'URI in modo che rifletta vaultUri dell'insieme di credenziali delle chiavi. Questo codice usa DefaultAzureCredential() per eseguire l'autenticazione con Key Vault, che a sua volta usa un token dell'identità gestita per l'autenticazione. Per altre informazioni sull'autenticazione con Key Vault, vedere la guida per sviluppatori. Il codice usa anche il backoff esponenziale per la ripetizione dei tentativi in caso di limitazione di Key Vault. Per altre informazioni sui limiti di transazioni di Key Vault, vedere Informazioni sui limiti di Azure Key Vault.

SecretClientOptions options = new SecretClientOptions()
    {
        Retry =
        {
            Delay= TimeSpan.FromSeconds(2),
            MaxDelay = TimeSpan.FromSeconds(16),
            MaxRetries = 5,
            Mode = RetryMode.Exponential
         }
    };
var client = new SecretClient(new Uri("https://<your-unique-key-vault-name>.vault.azure.net/"), new DefaultAzureCredential(),options);

KeyVaultSecret secret = client.GetSecret("<mySecret>");

string secretValue = secret.Value;
.NET 5.0 o versioni precedenti

Aggiornare la riga await context.Response.WriteAsync("Hello World!"); in modo che sia simile a questa:

await context.Response.WriteAsync(secretValue);
.NET 6.0

Aggiornare la riga app.MapGet("/", () => "Hello World!"); in modo che sia simile a questa:

app.MapGet("/", () => secretValue);

Assicurarsi di salvare le modifiche prima di continuare con il passaggio successivo.

Ridistribuire l'app Web

Ora che il codice è stato aggiornato, è possibile ridistribuirlo in Azure tramite i comandi Git seguenti:

git add .
git commit -m "Updated web app to access my key vault"
git push azure main

Passare all'app Web completata

http://<your-webapp-name>.azurewebsites.net

Dove prima veniva visualizzato "Hello World", verrà ora visualizzato il valore del segreto.

Passaggi successivi