Øvelse – Tilgangshemmeligheter lagret i Azure Key Vault

Fullført

Du vet hvordan aktivering av administrerte identiteter for Azure-ressurser oppretter en identitet som appen kan bruke til godkjenning. Opprett nå en app som bruker denne identiteten til å få tilgang til hemmeligheter i hvelvet.

Les hemmeligheter i en ASP.NET Core-app

Azure Key Vault API er en REST-API som håndterer all administrasjon og bruk av nøkler og hvelv. Hver hemmelighet i et hvelv har en unik NETTADRESSE. Hemmelige verdier hentes med HTTP GET-forespørsler.

Den offisielle Key Vault-klienten for .NET Core er SecretClient klassen i Azure.Security.KeyVault.Secrets NuGet-pakken. Du trenger imidlertid ikke å bruke den direkte. Med ASP.NET Cores AddAzureKeyVault metode kan du laste alle hemmelighetene fra et hvelv inn i konfigurasjons-API-en ved oppstart. Med denne teknikken får du tilgang til alle hemmelighetene dine ved å bruke samme IConfiguration grensesnitt som du bruker for resten av konfigurasjonen. Apper som bruker AddAzureKeyVault krever både Get og List tillatelser til hvelvet.

Tips

Uavhengig av rammeverket eller språket du bruker til å bygge appen, bør du utforme den for å bufre hemmelige verdier lokalt eller laste dem inn i minnet ved oppstart, med mindre du har en bestemt grunn til ikke å gjøre det. Lese dem direkte fra hvelvet hver gang du trenger dem er unødvendig treg og dyrt.

AddAzureKeyVault krever bare hvelvnavnet som inndata, som du får fra den lokale appkonfigurasjonen. Den håndterer også automatisk administrert identitetsgodkjenning. Når API-en brukes i en app som distribueres til Azure App Service med administrerte identiteter for Azure-ressurser aktivert. Den oppdager tokentjenesten for administrerte identiteter og bruker den til å godkjenne. Den passer godt til de fleste scenarioer og implementerer alle anbefalte fremgangsmåter. Du bruker den i denne enhetens øvelse.

Les hemmeligheter i en Node.js app

Azure Key Vault API er en REST-API som håndterer all administrasjon og bruk av nøkler og hvelv. Hver hemmelighet i et hvelv har en unik NETTADRESSE. Hemmelige verdier hentes med HTTP GET-forespørsler.

Den offisielle Key Vault-klienten for Node.js-apper er SecretClient-klassen i @azure/keyvault-secrets npm-pakken. Apper som inkluderer hemmelige navn i konfigurasjonen eller koden, bruker vanligvis getSecret metoden, som laster inn en hemmelig verdi gitt navnet. getSecret krever at appens identitet har Get tillatelse i hvelvet. Apper som er utformet for å laste inn alle hemmeligheter fra et hvelv, bruker også listPropertiesOfSecrets metoden, som laster inn en liste over hemmeligheter og krever List tillatelse.

Før appen kan opprette en SecretClient forekomst, må den få et legitimasjonsobjekt for godkjenning til hvelvet. Hvis du vil godkjenne, bruker du DefaultAzureCredential som leveres av @azure/identity npm-pakken. Den DefaultAzureCredential passer for de fleste scenarioer der programmet er ment å kjøre i Azure Cloud, fordi DefaultAzureCredential kombinerer legitimasjon som vanligvis brukes til å godkjenne når den distribueres, med legitimasjon som brukes til å godkjenne i et utviklingsmiljø. DefaultAzureCredential forsøker å godkjenne ved hjelp av følgende mekanismer i rekkefølge:

  • Miljø. DefaultAzureCredential leser kontoinformasjon angitt ved hjelp av miljøvariabler og bruker den til å godkjenne.
  • Administrert identitet. Hvis programmet distribueres til en Azure-vert med administrert identitet aktivert, godkjenner DefaultAzureCredential med denne kontoen.
  • Visual Studio Code. Hvis utvikleren godkjente ved hjelp av plugin-modulen Visual Studio Code Azure-konto, godkjenner DefaultAzureCredential med denne kontoen.
  • Azure CLI. Hvis utvikleren godkjente en konto ved hjelp av Azure CLI az login-kommandoen, godkjenner DefaultAzureCredential med denne kontoen.

Hvis du vil ha mer informasjon, kan du se dokumentasjonen.

Tips

Uavhengig av rammeverket eller språket du bruker til å bygge appen, bør du utforme den for å bufre hemmelige verdier lokalt eller laste dem inn i minnet ved oppstart, med mindre du har en bestemt grunn til ikke å gjøre det. Lese dem direkte fra hvelvet hver gang du trenger dem er unødvendig treg og dyrt.

Håndtere hemmeligheter i en app

Når en hemmelighet er lastet inn i appen, er det opp til appen å håndtere den på en sikker måte. I appen du bygger i denne modulen, skriver du den hemmelige verdien ut til klientsvaret, og for å demonstrere at den er lastet inn, kan du vise den i en nettleser. Å returnere en hemmelig verdi til klienten er ikke noe du vanligvis bør gjøre! Vanligvis bruker du hemmeligheter til å gjøre ting som å initialisere klientbiblioteker for databaser eller eksterne API-er.

Viktig

Se alltid nøye gjennom koden for å sikre at appen aldri skriver hemmeligheter til noen form for utdata, inkludert logger, lagring og svar.

Mosjon

Hvis du vil laste inn hemmeligheten fra hvelvet vårt, oppretter du en ny ASP.NET Core-nett-API og bruker AddAzureKeyVault.

Opprett appen

  1. Hvis du vil opprette en ny ASP.NET Core web API-app og åpne den i redigeringsprogrammet, kjører du følgende kommandoer i Azure Cloud Shell.

    dotnet new webapi -o KeyVaultDemoApp
    cd KeyVaultDemoApp
    code .
    
  2. Når redigeringsprogrammet lastes inn, legger du til NuGet-pakken som inneholder AddAzureKeyVault og gjenoppretter alle appens avhengigheter. Kjør følgende kommandoer i Azure Cloud Shell.

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

Legg til kode som laster inn og bruker hemmeligheter

Hvis du vil demonstrere god bruk av Key Vault, endrer du appen for å laste inn hemmeligheter fra hvelvet ved oppstart. Du legger også til en ny kontroller med et endepunkt som får din SecretPassword hemmelighet fra hvelvet.

  1. For oppstart av appen skriver du inn følgende kommando for å starte redigeringsprogrammet.

    code .
    
  2. Åpne Program.cs, slett innholdet og erstatt dem med følgende kode.

    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());
                    });
        }
    }
    

    Viktig

    Pass på å lagre filer når du er ferdig med å redigere dem. Du kan lagre filer enten via "..." eller hurtigtastene (Ctrl+S på Windows og Linux, Cmd+S på macOS).

    Den eneste endringen fra startkoden er tillegg av ConfigureAppConfiguration. Dette elementet er der vi laster inn hvelvnavnet fra konfigurasjonen og kaller AddAzureKeyVault med det.

  3. Opprett en ny fil i Controllers-mappen kalt SecretTestController.csfor kontrolleren, og lim inn i følgende kode.

    Tips

    Hvis du vil opprette en ny fil, bruker du kommandoen touch i Cloud Shell. I dette tilfellet kjører du kommandoen touch Controllers/SecretTestController.cs. Hvis du vil finne den øverst til høyre i Filer-ruten i redigeringsprogrammet, velger du ikonet Oppdater.

    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. Kjør kommandoen dotnet build i Azure Cloud Shell, og kontroller at alt kompileres. Appen er klar til å kjøres. Nå er det på tide å få det inn i Azure!

Opprett en ny nett-API med Express.js og bruk @azure/keyvault-secrets og @azure/identity pakker til å laste inn hemmeligheten fra hvelvet vårt.

Opprett appen

Kjør følgende kode i Azure Cloud Shell for å initialisere en ny Node.js app, installere de nødvendige pakkene og åpne en ny fil i redigeringsprogrammet.

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

Legg til kode som laster inn og bruker hemmeligheter

Appen laster inn hemmeligheter fra hvelvet ved oppstart for å demonstrere god bruk av Key Vault. Hvis du vil vise at hemmelighetene dine er lastet inn, oppretter du et endepunkt som viser verdien av SecretPassword hemmeligheten.

  1. Hvis du vil konfigurere appen, limer du inn følgende kode i redigeringsprogrammet. Denne koden importerer de nødvendige pakkene, konfigurerer port- og hvelv-URI-konfigurasjonen og oppretter et nytt objekt for å inneholde de hemmelige navnene og verdiene.

    // 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 = {};
    

    Viktig

    Pass på å lagre filer mens du arbeider med dem, spesielt når du er ferdig. Du kan lagre filer enten via "..." eller hurtigtastene (Ctrl+S på Windows og Linux, Cmd+S på macOS).

  2. Deretter legger du til koden for å godkjenne i hvelvet og laste inn hemmelighetene. Du legger til denne koden som to separate funksjoner. Sett inn et par tomme linjer etter koden du tidligere har lagt til, og lim deretter inn følgende kode.

    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. Hvis du vil teste om hemmeligheten vår ble lastet inn, oppretter du Express-endepunktet. Lim inn i denne 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. Ring funksjonene dine for å laste inn hemmelighetene fra hvelvet vårt, og start deretter appen. Lim inn i denne siste snutten for å fullføre appen.

    (async () =>  {
      await getKeyVaultSecrets();
      app.listen(port, () => {
        console.log(`Server running at http://localhost:${port}`);
      });
    })().catch(err => console.log(err));
    
  5. Du er ferdig med å skrive kode, så pass på å lagre filen.

Appen er klar til å kjøres. Nå er det på tide å få det inn i Azure!