Övning – Få tillgång till hemligheter i Azure Key Vault

Slutförd

Du vet hur aktivering av hanterade identiteter för Azure-resurser skapar en identitet som appen kan använda för autentisering. Skapa nu en app som använder den identiteten för att komma åt hemligheter i valvet.

Läsa hemligheter i en ASP.NET Core-app

Azure Key Vault API är ett REST-API som hanterar all hantering och användning av nycklar och valv. Varje hemlighet i ett valv har en unik URL. Hemliga värden hämtas med HTTP GET-begäranden.

Den officiella Key Vault-klienten för .NET Core är SecretClient klassen i Azure.Security.KeyVault.Secrets NuGet-paketet. Du behöver dock inte använda den direkt. Med ASP.NET Core-metoden AddAzureKeyVault kan du läsa in alla hemligheter från ett valv till konfigurations-API:et vid start. Med den här tekniken kan du komma åt alla dina hemligheter med hjälp av samma IConfiguration gränssnitt som du använder för resten av konfigurationen. Appar som använder AddAzureKeyVault kräver både Get och List behörigheter till valvet.

Dricks

Oavsett vilket ramverk eller språk du använder för att skapa din app bör du utforma den för att cachelagma hemliga värden lokalt eller läsa in dem i minnet vid start, såvida du inte har en specifik anledning att inte göra det. Det är onödigt långsamt och dyrt att läsa dem direkt från valvet varje gång du behöver dem.

AddAzureKeyVault kräver bara valvnamnet som indata, som du får från din lokala appkonfiguration. Den hanterar också automatiskt hanterad identitetsautentisering. När den används i en app som distribueras till Azure App Service med hanterade identiteter för Azure-resurser aktiverade identifierar den tokentjänsten för hanterade identiteter och använder den för att autentisera. Det passar bra för de flesta scenarier och implementerar alla metodtips. Du använder den i den här lektionens övning.

Läsa hemligheter i en Node.js-app

Azure Key Vault API är ett REST-API som hanterar all hantering och användning av nycklar och valv. Varje hemlighet i ett valv har en unik URL. Hemliga värden hämtas med HTTP GET-begäranden.

Den officiella Key Vault-klienten för Node.js-appar är SecretClient-klassen i @azure/keyvault-secrets npm-paketet. Appar som innehåller hemliga namn i sin konfiguration eller kod använder vanligtvis sin getSecret metod, som läser in ett hemligt värde med namnet. getSecret kräver att appens identitet har behörigheten Get för valvet. Appar som är utformade för att läsa in alla hemligheter från ett valv använder listPropertiesOfSecrets också metoden, som läser in en lista med hemligheter och kräver behörigheten List .

Innan din app kan skapa en SecretClient-instans måste den få ett autentiseringsobjekt genom att autentisera till valvet. Autentisera genom att använda den DefaultAzureCredential som tillhandahålls av npm-paketet @azure/identity. DefaultAzureCredential Är lämpligt för de flesta scenarier där programmet är avsett att köras i Azure Cloud eftersom kombinerar autentiseringsuppgifter som ofta används för att autentisera när det distribueras, med autentiseringsuppgifter som används för att autentisera DefaultAzureCredential i en utvecklingsmiljö. Försöken DefaultAzureCredential att autentisera med hjälp av följande mekanismer i ordning:

  • Miljö. Läser DefaultAzureCredential kontoinformationen som anges med hjälp av miljövariabler och använder den för att autentisera.
  • Hanterad identitet. Om programmet distribueras till en Azure-värd med hanterad identitet aktiverad autentiseras DefaultAzureCredential med det kontot.
  • Visual Studio Code. Om utvecklaren autentiseras med hjälp av plugin-programmet Visual Studio Code Azure Account autentiseras DefaultAzureCredential med det kontot.
  • Azure CLI. Om utvecklaren autentiserade ett konto med hjälp av Azure CLI-kommandot az login autentiseras DefaultAzureCredential kontot.

Mer information finns i dokumentationen.

Dricks

Oavsett vilket ramverk eller språk du använder för att skapa din app bör du utforma den för att cachelagma hemliga värden lokalt eller läsa in dem i minnet vid start, såvida du inte har en specifik anledning att inte göra det. Det är onödigt långsamt och dyrt att läsa dem direkt från valvet varje gång du behöver dem.

Hantera hemligheter i en app

När en hemlighet har lästs in i din app är det upp till din app att hantera den på ett säkert sätt. I appen som du skapar i den här modulen skriver du ut ditt hemliga värde till klientsvaret och för att visa att det har lästs in kan du visa det i en webbläsare. Att returnera en hemlighet till klienten är inte något som du normalt sett gör! Vanligtvis använder du hemligheter för att göra saker som att initiera klientbibliotek för databaser eller fjärranslutna API:er.

Viktigt!

Granska alltid koden noggrant för att säkerställa att din app aldrig skriver hemligheter till någon form av utdata, inklusive loggar, lagring och svar.

Övning

Om du vill läsa in hemligheten från vårt valv skapar du ett nytt ASP.NET Core-webb-API och använder AddAzureKeyVault.

Skapa appen

  1. Om du vill skapa en ny ASP.NET Core-webb-API-app och öppna den i redigeraren kör du följande kommandon i Azure Cloud Shell.

    dotnet new webapi -o KeyVaultDemoApp
    cd KeyVaultDemoApp
    code .
    
  2. När redigeraren har lästs in lägger du till NuGet-paketet som innehåller AddAzureKeyVault och återställer alla appens beroenden. Kör följande kommandon i Azure Cloud Shell.

    dotnet add package Azure.Identity
    dotnet add package Azure.Extensions.AspNetCore.Configuration.Secrets
    dotnet restore
    

Lägga till kod för att läsa in och använda hemligheter

Om du vill visa god användning av Key Vault ändrar du appen så att den läser in hemligheter från valvet vid start. Du lägger också till en ny kontrollant med en slutpunkt som hämtar din SecretPassword hemlighet från valvet.

  1. För appstarten anger du följande kommando för att starta redigeraren.

    code .
    
  2. Öppna Program.cs, ta bort innehållet och ersätt dem med följande kod.

    using System;
    using Azure.Identity;
    using Microsoft.AspNetCore;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.Hosting;
    
    namespace KeyVaultDemoApp
    {
        public class Program
        {
            public static void Main(string[] args)
            {
                CreateHostBuilder(args).Build().Run();
            }
    
            public static IHostBuilder CreateHostBuilder(string[] args) =>
                Host.CreateDefaultBuilder(args)
                    .ConfigureWebHostDefaults(webBuilder =>
                    {
                        webBuilder.UseStartup<Startup>();
                    })
                    .ConfigureAppConfiguration((context, config) =>
                    {
                        // Build the current set of configuration to load values from
                        // JSON files and environment variables, including VaultName.
                        var builtConfig = config.Build();
    
                        // Use VaultName from the configuration to create the full vault URI.
                        var vaultName = builtConfig["VaultName"];
                        Uri vaultUri = new Uri($"https://{vaultName}.vault.azure.net/");
    
                        // Load all secrets from the vault into configuration. This will automatically
                        // authenticate to the vault using a managed identity. If a managed identity
                        // is not available, it will check if Visual Studio and/or the Azure CLI are
                        // installed locally and see if they are configured with credentials that can
                        // access the vault.
                        config.AddAzureKeyVault(vaultUri, new DefaultAzureCredential());
                    });
        }
    }
    

    Viktigt!

    Spara filerna när du är klar med redigeringen. Du kan spara filer antingen via "..." eller acceleratornyckeln (Ctrl+S i Windows och Linux, Cmd+S på macOS).

    Den enda ändringen i startkoden är att vi lägger till ConfigureAppConfiguration. Det är i det här elementet vi läser in valvnamnet från konfigurationen och anropar AddAzureKeyVault med det.

  3. För kontrollanten skapar du en ny fil i Controllers mappen med namnet SecretTestController.csoch klistrar in följande kod.

    Dricks

    Om du vill skapa en ny fil använder du touch kommandot i Cloud Shell. I det här fallet kör du touch Controllers/SecretTestController.cs kommandot . Om du vill hitta den i det övre högra hörnet i fönstret Filer i redigeraren väljer du ikonen Uppdatera.

    using System;
    using Microsoft.AspNetCore.Http;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Extensions.Configuration;
    
    namespace KeyVaultDemoApp.Controllers
    {
        [Route("api/[controller]")]
        public class SecretTestController : ControllerBase
        {
            private readonly IConfiguration _configuration;
    
            public SecretTestController(IConfiguration configuration)
            {
                _configuration = configuration;
            }
    
            [HttpGet]
            public IActionResult Get()
            {
                // Get the secret value from configuration. This can be done anywhere
                // we have access to IConfiguration. This does not call the Key Vault
                // API, because the secrets were loaded at startup.
                var secretName = "SecretPassword";
                var secretValue = _configuration[secretName];
    
                if (secretValue == null)
                {
                    return StatusCode(
                        StatusCodes.Status500InternalServerError,
                        $"Error: No secret named {secretName} was found...");
                }
                else {
                    return Content($"Secret value: {secretValue}" +
                        Environment.NewLine + Environment.NewLine +
                        "This is for testing only! Never output a secret " +
                        "to a response or anywhere else in a real app!");
                }
            }
        }
    }
    
  4. dotnet build Kör kommandot i Azure Cloud Shell för att se till att allt kompileras. Appen är redo att köras. Nu är det dags att få in den i Azure!

Skapa ett nytt webb-API med Express.js och använd paketen @azure/keyvault-secrets och @azure/identity för att läsa in hemligheten från vårt valv.

Skapa appen

Kör följande kod i Azure Cloud Shell för att initiera en ny Node.js-app, installera de paket som behövs och öppna en ny fil i redigeraren.

mkdir KeyVaultDemoApp
cd KeyVaultDemoApp
npm init -y
npm install @azure/identity @azure/keyvault-secrets express
touch app.js
code app.js

Lägga till kod för att läsa in och använda hemligheter

För att demonstrera god användning av Key Vault läser din app in hemligheter från valvet vid start. Om du vill visa att dina hemligheter har lästs in skapar du en slutpunkt som visar hemlighetens SecretPassword värde.

  1. Om du vill konfigurera appen klistrar du in följande kod i redigeraren. Den här koden importerar nödvändiga paket, konfigurerar URI-konfigurationen för portar och valv och skapar ett nytt objekt som innehåller de hemliga namnen och värdena.

    // Importing dependencies
    const { DefaultAzureCredential } = require("@azure/identity");
    const { SecretClient } = require("@azure/keyvault-secrets");
    const app = require('express')();
    
    // Initialize port
    const port = process.env.PORT || 3000;
    
    // Create Vault URI from App Settings
    const vaultUri = `https://${process.env.VaultName}.vault.azure.net/`;
    
    // Map of key vault secret names to values
    let vaultSecretsMap = {};
    

    Viktigt!

    Se till att spara filer när du arbetar med dem, särskilt när du är klar. Du kan spara filer antingen via "..." eller acceleratornyckeln (Ctrl+S i Windows och Linux, Cmd+S på macOS).

  2. Lägg sedan till koden för att autentisera till valvet och läsa in hemligheterna. Du lägger till den här koden som två separata funktioner. Infoga ett par tomma rader efter koden som du tidigare lade till och klistra sedan in följande kod.

    const getKeyVaultSecrets = async () => {
      // Create a key vault secret client
      let secretClient = new SecretClient(vaultUri, new DefaultAzureCredential());
      try {
        // Iterate through each secret in the vault
        listPropertiesOfSecrets = secretClient.listPropertiesOfSecrets();
        while (true) {
          let { done, value } = await listPropertiesOfSecrets.next();
          if (done) {
            break;
          }
          // Only load enabled secrets - getSecret will return an error for disabled secrets
          if (value.enabled) {
            const secret = await secretClient.getSecret(value.name);
            vaultSecretsMap[value.name] = secret.value;
          }
        }
      } catch(err) {
        console.log(err.message)
      }
    }
    
  3. Skapa Express-slutpunkten för att testa om vår hemlighet lästes in. Klistra in den här koden.

    app.get('/api/SecretTest', (req, res) => {
      let secretName = 'SecretPassword';
      let response;
      if (secretName in vaultSecretsMap) {
        response = `Secret value: ${vaultSecretsMap[secretName]}\n\nThis is for testing only! Never output a secret to a response or anywhere else in a real app!`;
      } else {
        response = `Error: No secret named ${secretName} was found...`
      }
      res.type('text');
      res.send(response);
    });
    
  4. Anropa dina funktioner för att läsa in hemligheterna från vårt valv och starta sedan appen. Klistra in det senaste kodfragmentet för att slutföra appen.

    (async () =>  {
      await getKeyVaultSecrets();
      app.listen(port, () => {
        console.log(`Server running at http://localhost:${port}`);
      });
    })().catch(err => console.log(err));
    
  5. Du är nu klar med att skriva kod, så se till att spara filen.

Appen är redo att köras. Nu är det dags att få in den i Azure!