Oefening; geheimen openen in Azure Key Vault

Voltooid

U weet hoe het inschakelen van beheerde identiteiten voor Azure-resources een identiteit voor uw app maakt die moet worden gebruikt voor verificatie. Maak nu een app die die identiteit gebruikt voor toegang tot geheimen in de kluis.

Geheimen lezen in een ASP.NET Core-app

Azure Key Vault-API is een REST API die alle beheer en het gebruik van sleutels en kluizen afhandelt. Elk geheim in een kluis heeft een unieke URL. Geheime waarden worden opgehaald met HTTP GET-aanvragen.

De officiële Key Vault-client voor .NET Core is de SecretClient klasse in het Azure.Security.KeyVault.Secrets NuGet-pakket. U hoeft deze echter niet rechtstreeks te gebruiken. U kunt met de AddAzureKeyVault-methode van ASP.NET Core bij het starten alle geheimen uit een kluis laden naar de configuratie-API. Met deze techniek hebt u toegang tot al uw geheimen op naam met behulp van dezelfde IConfiguration interface die u voor de rest van uw configuratie gebruikt. Apps die gebruikmaken AddAzureKeyVault van zowel als List Get machtigingen voor de kluis.

Tip

Ongeacht het framework of de taal die u gebruikt om uw app te bouwen, moet u deze ontwerpen om geheime waarden lokaal in de cache op te slaan of in het geheugen te laden tijdens het opstarten, tenzij u een specifieke reden hebt om dat niet te doen. Het rechtstreeks lezen van geheimen uit de kluis telkens wanneer u ze nodig hebt, is onnodig traag en duur.

AddAzureKeyVault vereist alleen de kluisnaam als invoer, die u ophaalt uit uw lokale app-configuratie. Het verwerkt ook automatisch verificatie van beheerde identiteiten. Wanneer deze wordt gebruikt in een app die is geïmplementeerd in Azure-app Service met beheerde identiteiten voor Azure-resources ingeschakeld, wordt de tokenservice voor beheerde identiteiten gedetecteerd en gebruikt voor verificatie. Het is geschikt voor de meeste scenario's en implementeert alle aanbevolen procedures. U gebruikt deze in de oefening van deze les.

Geheimen lezen in een Node.js-app

Azure Key Vault-API is een REST API die alle beheer en het gebruik van sleutels en kluizen afhandelt. Elk geheim in een kluis heeft een unieke URL. Geheime waarden worden opgehaald met HTTP GET-aanvragen.

De officiële Key Vault-client voor Node.js-apps in de klasse SecretClient in het npm-pakket @azure/keyvault-secrets. Apps die geheime namen bevatten in hun configuratie of code, gebruiken doorgaans de getSecret methode, waarmee een geheime waarde wordt geladen op basis van de naam. getSecret vereist dat de identiteit van uw app over de Get machtiging voor de kluis beschikt. Apps die zijn ontworpen om alle geheimen uit een kluis te laden, gebruiken ook de listPropertiesOfSecrets methode, waarmee een lijst met geheimen wordt geladen en waarvoor de List machtiging is vereist.

Voordat uw app een SecretClient-exemplaar kan maken, moet deze een referentieobject ophalen voor verificatie bij de kluis. Gebruik de DefaultAzureCredential van het NPM-pakket @azure/identity om te verifiëren. Dit DefaultAzureCredential is geschikt voor de meeste scenario's waarbij de toepassing uiteindelijk wordt uitgevoerd in de Azure Cloud, omdat de DefaultAzureCredential referenties die vaak worden gebruikt voor verificatie bij implementatie worden gecombineerd, met referenties die worden gebruikt voor verificatie in een ontwikkelomgeving. De DefaultAzureCredential pogingen om te verifiëren met behulp van de volgende mechanismen in volgorde:

  • Omgeving. De DefaultAzureCredential accountgegevens lezen die zijn opgegeven met behulp van omgevingsvariabelen en deze gebruiken om te verifiëren.
  • Beheerde identiteit. Als de toepassing wordt geïmplementeerd op een Azure-host waarvoor Beheerde identiteit is ingeschakeld, wordt de DefaultAzureCredential toepassing geverifieerd met dat account.
  • Visual Studio Code. Als de ontwikkelaar is geverifieerd met behulp van de invoegtoepassing Azure-account van Visual Studio Code, wordt het DefaultAzureCredential account geverifieerd met dat account.
  • Azure CLI. Als de ontwikkelaar een account heeft geverifieerd met behulp van de Azure CLI-opdracht az login , wordt het DefaultAzureCredential account geverifieerd met dat account.

Raadpleeg de documentatie voor meer informatie.

Tip

Ongeacht het framework of de taal die u gebruikt om uw app te bouwen, moet u deze ontwerpen om geheime waarden lokaal in de cache op te slaan of in het geheugen te laden tijdens het opstarten, tenzij u een specifieke reden hebt om dat niet te doen. Het rechtstreeks lezen van geheimen uit de kluis telkens wanneer u ze nodig hebt, is onnodig traag en duur.

Geheimen in een app afhandelen

Wanneer een geheim in uw app is geladen, moet uw app het veilig verwerken. In de app die u in deze module bouwt, schrijft u de geheime waarde naar het antwoord van de client en om te laten zien dat deze is geladen, bekijkt u deze in een webbrowser. Een geheime waarde retourneren naar de client is niet iets wat u normaal zou doen. Normaal gesproken gebruikt u geheimen om dingen te doen, zoals het initialiseren van clientbibliotheken voor databases of externe API's.

Belangrijk

Controleer altijd zorgvuldig uw code om ervoor te zorgen dat uw app nooit geheimen schrijft naar elk soort uitvoer, inclusief logboeken, opslag en antwoorden.

Oefening

Als u het geheim uit onze kluis wilt laden, maakt u een nieuwe ASP.NET Core-web-API en gebruikt u AddAzureKeyVaultdeze.

De app maken

  1. Als u een nieuwe ASP.NET Core-web-API-app wilt maken en deze wilt openen in de editor, voert u de volgende opdrachten uit in Azure Cloud Shell.

    dotnet new webapi -o KeyVaultDemoApp
    cd KeyVaultDemoApp
    code .
    
  2. Nadat de editor is geladen, voegt u het NuGet-pakket toe dat alle afhankelijkheden van de app bevat AddAzureKeyVault en herstelt. Voer in Azure Cloud Shell de volgende opdrachten uit.

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

Code toevoegen geheimen te laden en gebruiken

Als u een goed gebruik van Key Vault wilt demonstreren, wijzigt u uw app om bij het opstarten geheimen uit de kluis te laden. U voegt ook een nieuwe controller toe met een eindpunt waarmee uw SecretPassword geheim uit de kluis wordt opgehaald.

  1. Voer voor het opstarten van de app de volgende opdracht in om de editor te starten.

    code .
    
  2. Open Program.cs, verwijder de inhoud en vervang deze door de volgende code.

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

    Belangrijk

    Zorg dat u de bestanden opslaat wanneer u klaar bent met het bewerken hiervan. U kunt bestanden opslaan via de "..." menu of de sneltoets (Ctrl+S in Windows en Linux, Cmd+S op macOS).

    De enige wijziging vergeleken met de startcode is de toevoeging van ConfigureAppConfiguration. Dit element is de plek waar we de kluisnaam laden uit de configuratie en ermee aanroepen AddAzureKeyVault .

  3. Maak voor de controller een nieuw bestand in de map met de Controllers naam SecretTestController.csen plak de volgende code.

    Tip

    Als u een nieuw bestand wilt maken, gebruikt u de touch opdracht in Cloud Shell. Voer in dit geval de touch Controllers/SecretTestController.cs opdracht uit. Als u deze in de rechterbovenhoek van het deelvenster Bestanden van de editor wilt vinden, selecteert u het pictogram Vernieuwen.

    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. Voer de dotnet build opdracht uit in Azure Cloud Shell om ervoor te zorgen dat alles wordt gecompileerd. De app kan worden uitgevoerd. Nu is het tijd om het in Azure te krijgen.

Maak een nieuwe web-API met Express.js en gebruik de @azure/keyvault-secrets en @azure/identity pakketten om het geheim uit onze kluis te laden.

De app maken

Voer de volgende code uit in Azure Cloud Shell om een nieuwe Node.js-app te initialiseren, de benodigde pakketten te installeren en een nieuw bestand in de editor te openen.

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

Code toevoegen geheimen te laden en gebruiken

Om een goed gebruik van Key Vault te demonstreren, laadt uw app geheimen uit de kluis bij het opstarten. Als u wilt laten zien dat uw geheimen zijn geladen, maakt u een eindpunt dat de waarde van het SecretPassword geheim weergeeft.

  1. Als u de app wilt instellen, plakt u de volgende code in de editor. Met deze code importeert u de benodigde pakketten, stelt u de poort- en kluis-URI-configuratie in en maakt u een nieuw object voor het opslaan van de geheime namen en waarden.

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

    Belangrijk

    Zorg ervoor dat u bestanden opslaat als u ermee hebt gewerkt, vooral wanneer u klaar bent. U kunt bestanden opslaan via de "..." menu of de sneltoets (Ctrl+S in Windows en Linux, Cmd+S op macOS).

  2. Voeg vervolgens de code toe om te verifiëren bij de kluis en de geheimen te laden. U voegt deze code toe als twee afzonderlijke functies. Voeg een aantal lege regels toe na de code die u eerder hebt toegevoegd en plak vervolgens de volgende code in de editor.

    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. Maak het Express-eindpunt om te testen of ons geheim is geladen. Plak vervolgens deze code in de editor.

    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. Roep uw functies aan om de geheimen uit onze kluis te laden en start vervolgens de app. Plak dit laatste codefragment in de editor om de app te voltooien.

    (async () =>  {
      await getKeyVaultSecrets();
      app.listen(port, () => {
        console.log(`Server running at http://localhost:${port}`);
      });
    })().catch(err => console.log(err));
    
  5. U bent klaar met het schrijven van code, dus vergeet niet om het bestand op te slaan.

De app kan worden uitgevoerd. Nu is het tijd om het in Azure te krijgen.