Tutorial: Uso de una identidad administrada para conectar Key Vault a una aplicación web de Azure en .NET

Azure Key Vault proporciona una manera de almacenar credenciales y otros secretos con mayor seguridad. Pero el código debe autenticarse en Key Vault para recuperarlos. Identidades administradas para recursos de Azure ayudan a resolver este problema al proporcionar a los servicios de Azure una identidad administrada automáticamente en Microsoft Entra ID. Puede usar esta identidad para autenticarse en cualquier servicio que admita la autenticación de Microsoft Entra, incluida la Key Vault, sin tener que mostrar credenciales en el código.

En este tutorial, crearás e implementarás la aplicación web de Azure en Azure App Service. Usará una identidad administrada para autenticar su aplicación web de Azure con un Azure Key Vault mediante la biblioteca de cliente secreto de Azure Key Vault para .NET y la CLI de Azure. Se aplican los mismos principios básicos al usar el lenguaje de desarrollo que prefiera, Azure PowerShell o el portal de Azure.

Para obtener más información sobre App de Azure aplicaciones web de servicio e implementación presentadas en este tutorial, consulte:

Prerrequisitos

Para completar este tutorial, necesita lo siguiente:

Si ya tiene la aplicación web implementada en Azure App Service, puede ir directamente a las secciones de configurar el acceso de la aplicación web a un almacén de claves y modificar el código de la aplicación web.

Creación de una aplicación .NET Core

En este paso, configurará el proyecto local .NET Core.

En una ventana de terminal de la máquina, cree un directorio llamado akvwebapp y conviértalo en el directorio actual.

mkdir akvwebapp
cd akvwebapp

Cree una aplicación .NET Core mediante el comando dotnet new web:

dotnet new web

Ejecute la aplicación localmente para saber cómo debe tener el aspecto que debe tener al implementarla en Azure:

dotnet run

En un explorador web, vaya a la aplicación en http://localhost:5000.

Verá el mensaje "Hola mundo!" de la aplicación de ejemplo que se muestra en la página.

Para obtener más información sobre cómo crear aplicaciones web para Azure, consulte Crear una aplicación web de ASP.NET Core en Azure App Service

Implementación de la aplicación en Azure

En este paso, implementará la aplicación .NET Core en el servicio de aplicaciones de Azure mediante Git Local. Para obtener más información sobre cómo crear e implementar aplicaciones, consulte Crear una aplicación web de ASP.NET Core en Azure.

Configuración de la implementación de Git local

En la ventana de terminal, seleccione Ctrl + C para cerrar el servidor Web. Inicialice un repositorio de Git para el proyecto de .NET Core:

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

Puede usar FTP y Git local para implementar una aplicación web de Azure mediante un usuario deployment. Después de configurar el usuario de implementación, puede usarlo para todas las implementaciones de Azure. El nombre de usuario y la contraseña de implementación de nivel de cuenta son diferentes de las credenciales de suscripción de Azure.

Para configurar el usuario de implementación, ejecute el comando az webapp deployment user set. Elija un nombre de usuario y una contraseña que sigan estas siguientes directrices:

  • El nombre de usuario debe ser único en Azure. Para las inserciones locales de Git, no puede contener el símbolo de arroba (@).
  • La contraseña debe tener al menos ocho caracteres de longitud y contener dos de los tres elementos siguientes: letras, números y símbolos.
az webapp deployment user set --user-name "<username>" --password "<password>"

La salida JSON muestra la contraseña como null. Si se produce un error 'Conflict'. Details: 409, cambie el nombre de usuario. Si se produce un error 'Bad Request'. Details: 400, use una contraseña más segura.

Anote el nombre de usuario y la contraseña que se usarán para implementar las aplicaciones web.

Creación de un grupo de recursos

Un grupo de recursos es un contenedor lógico en el cual implementas y administras recursos de Azure. Cree un grupo de recursos para contener tanto almacén de claves como la aplicación web mediante el comando az group create:

az group create --name "<resource-group>" -l "EastUS"

Creación de un plan de App Service

Cree un plan App Service mediante el comando CLI de Azure az appservice plan create. En el siguiente ejemplo, se crea un plan de App Service denominado myAppServicePlan con el plan de tarifa FREE:

az appservice plan create --name myAppServicePlan --resource-group <resource-group> --sku FREE

Cuando se crea el plan de App Service, el CLI de Azure muestra información similar a la que ve aquí:

{ 
  "adminSiteName": null,
  "appServicePlanName": "myAppServicePlan",
  "geoRegion": "West Europe",
  "hostingEnvironmentProfile": null,
  "id": "/subscriptions/0000-0000/resourceGroups/<resource-group>/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
} 

Para obtener más información, consulte Administrar un plan de App Service en Azure.

Creación de una aplicación web

Cree una aplicación web de Azure en el plan de myAppServicePlan App Service.

Importante

Al igual que un almacén de claves, una aplicación web Azure debe tener un nombre único. Reemplace <webapp-name> por el nombre de la aplicación web en los ejemplos siguientes.

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

Cuando se crea la aplicación web, el CLI de Azure muestra una salida similar a la que se ve aquí:

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. >
}

La dirección URL de Git remoto se muestra en la propiedad deploymentLocalGitUrl, con el formato https://<username>@<webapp-name>.scm.azurewebsites.net/<webapp-name>.git. Guarde esta dirección URL. Lo necesitarás más tarde.

Ahora configure la aplicación web para implementarla desde la rama main:

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

Vaya a la nueva aplicación con el siguiente comando. Reemplace <webapp-name> por el nombre de la aplicación.

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

Verá la página web predeterminada para una nueva aplicación web de Azure.

Implementación de la aplicación local

De nuevo en la ventana del terminal local, agregue un remoto de Azure a su repositorio Git local. En el siguiente comando, reemplace <deployment-url> por la dirección URL de Git remoto que guardó en la sección Creación de una aplicación web.

git remote add azure <deployment-url>

Usa el siguiente comando para hacer push al entorno remoto de Azure y desplegar tu aplicación. Cuando el administrador de credenciales de Git le solicite las credenciales, utilice las que creó en la sección Configuración de la implementación de Git local.

git push azure main

Este comando puede tardar unos minutos en ejecutarse. Mientras se ejecuta, muestra información similar a la que se ve aquí:

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

Vaya a la aplicación implementada, o actualícela, en el explorador web:

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

Verá el mensaje "Hola mundo!" que vio anteriormente cuando visitó http://localhost:5000.

Para obtener más información sobre la implementación de aplicaciones web mediante Git, consulte Implementación de Git local en Azure App Service

Configuración de la aplicación web para conectarse a Key Vault

En esta sección, configurará el acceso web para Key Vault y actualizará el código de la aplicación para recuperar un secreto de Key Vault.

Creación y asignación de acceso a una identidad administrada

En este tutorial, usaremos managed identity para autenticarse en Key Vault. La identidad administrada administra automáticamente las credenciales de la aplicación.

En el CLI de Azure, para crear la identidad de la aplicación, ejecute el comando az webapp-identity assign:

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

El comando devolverá este fragmento de código JSON:

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

Para obtener permisos para la bóveda de claves a través del Control de Acceso Basado en Roles (RBAC), asigne un rol a su "Nombre Principal de Usuario" (UPN) utilizando el comando de CLI de Azure az role assignment create.

az role assignment create --role "Key Vault Secrets User" --assignee "<upn>" --scope "/subscriptions/<subscription-id>/resourceGroups/myResourceGroup/providers/Microsoft.KeyVault/vaults/<vault-name>"

Reemplace <upn>, <subscription-id> y <vault-name> con sus valores reales. Si usó otro nombre de grupo de recursos, reemplace también "myResourceGroup". El UPN normalmente tendrá el formato de una dirección de correo electrónico (por ejemplo, username@domain.com).

Modificación de la aplicación para acceder al almacén de claves

En este tutorial, usará la biblioteca cliente de secretos de Azure Key Vault con fines de demostración. También puede usar Azure Key Vault biblioteca cliente de certificados o Azure Key Vault biblioteca cliente de claves.

Instalación de los paquetes

Desde la ventana del terminal, instale la biblioteca cliente secreta de Azure Key Vault para .NET y paquetes de biblioteca cliente de Azure Identity:

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

Actualización del código

Busque y abra el archivo Startup.cs para .NET 5.0 o versiones anteriores, o bien Program.cs archivo para .NET 6.0 en el proyecto akvwebapp.

Agregue estas líneas al encabezado:

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

Agregue las líneas siguientes antes de la llamada a app.UseEndpoints (.NET 5.0 o anterior) o app.MapGet (.NET 6.0), y actualice el identificador URI para que refleje el valor de vaultUri del almacén de claves. Este código usa DefaultAzureCredential() para autenticarse en Key Vault, que usa un token de la identidad administrada para autenticarse. Para obtener más información sobre la autenticación en Key Vault, consulte la guía de Developer. El código también utiliza el retroceso exponencial para los reintentos en el caso de que se limite el almacén de claves. Para obtener más información sobre los límites de transacciones de Key Vault, consulte la guía sobre limitación de acceso de 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://<vault-name>.vault.azure.net/"), new DefaultAzureCredential(),options);

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

string secretValue = secret.Value;
.NET 5.0 o versiones anteriores

Actualice la línea await context.Response.WriteAsync("Hola mundo!"); para que tenga este aspecto:

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

Actualice la línea app.MapGet("/", () => "Hola mundo!"); para que tenga este aspecto:

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

Asegúrese de guardar los cambios antes de continuar con el siguiente paso.

Nueva implementación de la aplicación web

Ahora que ha actualizado el código, puede volver a implementarlo en Azure mediante estos comandos de Git:

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

Ir a la aplicación web completada

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

Donde antes aparecía "Hola mundo!", ahora debería ver que se muestra el valor del secreto.

Pasos siguientes