Ćwiczenie — uzyskiwanie dostępu do wpisów tajnych przechowywanych w usłudze Azure Key Vault
Wiesz, jak włączenie tożsamości zarządzanych dla zasobów platformy Azure powoduje utworzenie tożsamości używanej przez aplikację do uwierzytelniania. Teraz utwórz aplikację, która używa tej tożsamości do uzyskiwania dostępu do wpisów tajnych w magazynie.
Odczytywanie wpisów tajnych w aplikacji ASP.NET Core
Interfejs API usługi Azure Key Vault to interfejs API REST, który obsługuje wszystkie zarządzanie i użycie kluczy i magazynów. Każdy wpis tajny w magazynie ma unikatowy adres URL. Wartości wpisów tajnych są pobierane za pomocą żądań HTTP GET.
Oficjalny klient usługi Key Vault dla platformy .NET Core jest klasą SecretClient
w pakiecie Azure.Security.KeyVault.Secrets
NuGet. Nie musisz jednak używać go bezpośrednio. Za pomocą metody ASP.NET Core AddAzureKeyVault
możesz załadować wszystkie wpisy tajne z magazynu do interfejsu API konfiguracji podczas uruchamiania. Ta technika umożliwia dostęp do wszystkich wpisów tajnych przy użyciu nazwy przy użyciu tego samego IConfiguration
interfejsu, który jest używany w pozostałej części konfiguracji. Aplikacje, które używają AddAzureKeyVault
, wymagają zarówno uprawnień, jak Get
i List
do magazynu.
Napiwek
Niezależnie od struktury lub języka używanego do kompilowania aplikacji, należy zaprojektować ją w celu buforowania wartości wpisów tajnych lokalnie lub załadowania ich do pamięci podczas uruchamiania, chyba że masz określony powód, aby nie. Odczytywanie ich bezpośrednio z magazynu za każdym razem, gdy są potrzebne, jest niepotrzebnie wolne i kosztowne.
AddAzureKeyVault
Usługa wymaga tylko nazwy magazynu jako danych wejściowych, które są uzyskiwane z lokalnej konfiguracji aplikacji. Automatycznie obsługuje również uwierzytelnianie tożsamości zarządzanej. W przypadku użycia w aplikacji wdrożonej w usłudze aplikacja systemu Azure z włączonymi tożsamościami zarządzanymi dla zasobów platformy Azure wykrywa usługę tokenu tożsamości zarządzanych i używa jej do uwierzytelniania. Jest to dobre rozwiązanie dla większości scenariuszy i implementuje wszystkie najlepsze rozwiązania. Zostanie ona użyta w ćwiczeniu tej lekcji.
Odczytywanie wpisów tajnych w aplikacji Node.js
Interfejs API usługi Azure Key Vault to interfejs API REST, który obsługuje wszystkie zarządzanie i użycie kluczy i magazynów. Każdy wpis tajny w magazynie ma unikatowy adres URL. Wartości wpisów tajnych są pobierane za pomocą żądań HTTP GET.
Oficjalny klient usługi Key Vault dla aplikacji środowiska Node.js to klasa SecretClient
w pakiecie npm @azure/keyvault-secrets
. Aplikacje, które zawierają nazwy wpisów tajnych w swojej konfiguracji lub kodzie, zwykle używają jej getSecret
metody, która ładuje wartość wpisu tajnego nadaną jej nazwie. getSecret
wymaga, aby tożsamość aplikacji miała Get
uprawnienia do magazynu. Aplikacje przeznaczone do ładowania wszystkich wpisów tajnych z magazynu używają listPropertiesOfSecrets
również metody , która ładuje listę wpisów tajnych i wymaga List
uprawnień.
Aby aplikacja mogła utworzyć wystąpienie SecretClient
, musi uzyskać obiekt poświadczeń umożliwiający uwierzytelnianie w magazynie. Aby przeprowadzić uwierzytelnianie, użyj elementu DefaultAzureCredential
dostarczonego w pakiecie npm @azure/identity
. Jest DefaultAzureCredential
to odpowiednie w przypadku większości scenariuszy, w których aplikacja ma ostatecznie działać w chmurze platformy Azure, ponieważ DefaultAzureCredential
łączy poświadczenia często używane do uwierzytelniania podczas wdrażania, z poświadczeniami używanymi do uwierzytelniania w środowisku projektowym. Próby DefaultAzureCredential
uwierzytelnienia przy użyciu następujących mechanizmów są następujące:
- Środowisko. Odczytuje
DefaultAzureCredential
informacje o koncie określone przy użyciu zmiennych środowiskowych i używa ich do uwierzytelniania. - Tożsamość zarządzana. Jeśli aplikacja zostanie wdrożona na hoście platformy Azure z włączoną tożsamością zarządzaną,
DefaultAzureCredential
uwierzytelnia się przy użyciu tego konta. - Visual Studio Code. Jeśli deweloper uwierzytelniony przy użyciu wtyczki konta platformy Azure programu Visual Studio Code,
DefaultAzureCredential
uwierzytelnia się przy użyciu tego konta. - Interfejs wiersza polecenia platformy Azure. Jeśli deweloper uwierzytelnił konto przy użyciu polecenia interfejsu wiersza polecenia
az login
platformy Azure,DefaultAzureCredential
uwierzytelnia się przy użyciu tego konta.
Więcej informacji zawiera strona dokumentacji.
Napiwek
Niezależnie od struktury lub języka używanego do kompilowania aplikacji, należy zaprojektować ją w celu buforowania wartości wpisów tajnych lokalnie lub załadowania ich do pamięci podczas uruchamiania, chyba że masz określony powód, aby nie. Odczytywanie ich bezpośrednio z magazynu za każdym razem, gdy są potrzebne, jest niepotrzebnie wolne i kosztowne.
Obsługa wpisów tajnych w aplikacji
Po załadowaniu wpisu tajnego do aplikacji to aplikacja powinna obsługiwać go w bezpieczny sposób. W aplikacji utworzonej w tym module zapisujesz wartość wpisu tajnego w odpowiedzi klienta i pokazujesz, że załadowano pomyślnie, wyświetlasz ją w przeglądarce internetowej. Zwracanie wartości wpisu tajnego do klienta nie jest typowym podejściem! Zazwyczaj wpisy tajne służą do wykonywania takich czynności, jak inicjowanie bibliotek klienckich dla baz danych lub zdalnych interfejsów API.
Ważne
Zawsze uważnie przejrzyj kod, aby upewnić się, że aplikacja nigdy nie zapisuje wpisów tajnych w dowolnych danych wyjściowych, w tym dzienników, magazynu i odpowiedzi.
Ćwiczenie
Aby załadować wpis tajny z naszego magazynu, utworzysz nowy internetowy interfejs API platformy ASP.NET Core i użyj polecenia AddAzureKeyVault
.
Tworzenie aplikacji
Aby utworzyć nową aplikację internetowego interfejsu API platformy ASP.NET Core i otworzyć ją w edytorze, uruchom następujące polecenia w usłudze Azure Cloud Shell.
dotnet new webapi -o KeyVaultDemoApp cd KeyVaultDemoApp code .
Po załadowaniu edytora dodaj pakiet NuGet zawierający
AddAzureKeyVault
i przywróć wszystkie zależności aplikacji. W usłudze Azure Cloud Shell uruchom następujące polecenia.dotnet add package Azure.Identity dotnet add package Azure.Extensions.AspNetCore.Configuration.Secrets dotnet restore
Dodawanie kodu w celu załadowania i użycia wpisów tajnych
Aby zademonstrować dobre użycie usługi Key Vault, zmodyfikuj aplikację tak, aby ładowała wpisy tajne z magazynu podczas uruchamiania. Dodasz również nowy kontroler z punktem końcowym, który pobiera wpis SecretPassword
tajny z magazynu.
W przypadku uruchamiania aplikacji wprowadź następujące polecenie, aby uruchomić edytor.
code .
Otwórz
Program.cs
plik , usuń zawartość i zastąp je następującym kodem.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()); }); } }
Ważne
Pamiętaj, aby zapisać pliki po zakończeniu ich edycji. Pliki można zapisywać za pomocą ciągu "..." menu lub skrótu (Ctrl+S w systemach Windows i Linux, Cmd+S w systemie macOS).
Jedyna zmiana w kodzie uruchomieniowym to dodanie
ConfigureAppConfiguration
. Ten element to miejsce, w którym załadujemy nazwę magazynu z konfiguracji i wywołamyAddAzureKeyVault
ją za pomocą polecenia .W przypadku kontrolera utwórz nowy plik w
Controllers
folderze o nazwieSecretTestController.cs
i wklej następujący kod.Napiwek
Aby utworzyć nowy plik, użyj
touch
polecenia w usłudze Cloud Shell. W takim przypadku uruchomtouch Controllers/SecretTestController.cs
polecenie . Aby znaleźć go w prawym górnym rogu okienka Pliki edytora, wybierz ikonę Odśwież.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!"); } } } }
dotnet build
Uruchom polecenie w usłudze Azure Cloud Shell, aby upewnić się, że wszystko jest kompilowane. Aplikacja jest gotowa do uruchomienia. Teraz nadszedł czas, aby dostać się na platformę Azure!
Utwórz nowy internetowy interfejs API z Express.js i użyj @azure/keyvault-secrets
pakietów i @azure/identity
, aby załadować wpis tajny z naszego magazynu.
Tworzenie aplikacji
Uruchom następujący kod w usłudze Azure Cloud Shell, aby zainicjować nową aplikację Node.js, zainstalować wymagane pakiety i otworzyć nowy plik w edytorze.
mkdir KeyVaultDemoApp
cd KeyVaultDemoApp
npm init -y
npm install @azure/identity @azure/keyvault-secrets express
touch app.js
code app.js
Dodawanie kodu w celu załadowania i użycia wpisów tajnych
Aby zademonstrować dobre użycie usługi Key Vault, aplikacja ładuje wpisy tajne z magazynu podczas uruchamiania. Aby zademonstrować, że wpisy tajne zostały załadowane, utwórz punkt końcowy, który wyświetla wartość wpisu tajnego SecretPassword
.
Aby skonfigurować aplikację, wklej następujący kod do edytora. Ten kod importuje niezbędne pakiety, skonfiguruj konfigurację portu i identyfikatora URI magazynu oraz utwórz nowy obiekt do przechowywania nazw i wartości wpisów tajnych.
// 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 = {};
Ważne
Pamiętaj o zapisywaniu plików podczas pracy z nimi, a szczególnie po jej zakończeniu. Pliki można zapisywać za pomocą ciągu "..." menu lub skrótu (Ctrl+S w systemach Windows i Linux, Cmd+S w systemie macOS).
Następnie dodaj kod w celu uwierzytelnienia w magazynie i załaduj wpisy tajne. Ten kod należy dodać jako dwie oddzielne funkcje. Wstaw kilka pustych wierszy po wcześniej dodanym kodzie, a następnie wklej następujący 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) } }
Aby sprawdzić, czy nasz wpis tajny został załadowany, utwórz punkt końcowy platformy Express. Wklej ten kod.
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); });
Wywołaj funkcje, aby załadować wpisy tajne z naszego magazynu, a następnie uruchom aplikację. Aby ukończyć aplikację, wklej ostatni fragment kodu.
(async () => { await getKeyVaultSecrets(); app.listen(port, () => { console.log(`Server running at http://localhost:${port}`); }); })().catch(err => console.log(err));
Po zakończeniu pisania kodu pamiętaj o zapisaniu pliku.
Aplikacja jest gotowa do uruchomienia. Teraz nadszedł czas, aby dostać się na platformę Azure!