Condividi tramite


Autenticare le applicazioni C++ ospitate su Azure per le risorse di Azure utilizzando un'identità gestita assegnata dall'utente

L'approccio consigliato per autenticare un'app ospitata Azure in altre risorse di Azure consiste nell'usare un'identità managed identity. Questo approccio è supportato per la maggior parte dei servizi Azure, incluse le app ospitate in Azure App Service, Azure Container Apps e Azure Virtual Machines. Altre informazioni sulle diverse tecniche e approcci di autenticazione sono disponibili nella pagina di panoramica dell'autenticazione . Nelle sezioni successive si apprenderà quanto descritto di seguito:

  • Concetti essenziali relativi all'identità gestita
  • Come creare un'identità gestita assegnata dall'utente per l'app
  • Come assegnare ruoli all'identità gestita assegnata dall'utente
  • Come eseguire l'autenticazione usando l'identità gestita assegnata dall'utente dal codice dell'app

Concetti essenziali relativi all'identità gestita

Un'identità gestita consente all'app di connettersi in modo sicuro ad altre risorse Azure senza usare chiavi segrete o altri segreti dell'applicazione. Internamente, Azure tiene traccia dell'identità e delle risorse a cui è consentito connettersi. Azure usa queste informazioni per ottenere automaticamente token di Microsoft Entra per consentire all'app di connettersi ad altre risorse Azure.

Esistono due tipi di identità gestite da considerare durante la configurazione dell'app ospitata:

  • Identità gestita assegnata dal sistema le identità gestite assegnate dal sistema vengono abilitate direttamente su una risorsa di Azure e sono associate al suo ciclo di vita. Quando la risorsa viene eliminata, Azure elimina automaticamente l'identità per te. Le identità assegnate dal sistema offrono un approccio minimalista all'uso delle identità gestite.
  • Assegnato dall'utente, le identità gestite sono create come risorse autonome di Azure e offrono maggiore flessibilità e funzionalità. Sono ideali per soluzioni che coinvolgono più risorse Azure che devono condividere la stessa identità e le stesse autorizzazioni. Ad esempio, se più macchine virtuali devono accedere allo stesso set di risorse Azure, un'identità gestita assegnata dall'utente offre la riutilizzabilità e la gestione ottimizzata.

Suggerimento

Altre informazioni sulla selezione e sulla gestione delle identità gestite assegnate dal sistema e assegnate dall'utente sono disponibili nell'articolo Raccomandazioni sulle procedure consigliate sulle identità gestite .

Le sezioni seguenti descrivono i passaggi per abilitare e usare un'identità gestita assegnata dall'utente per un'app ospitata Azure. Se è necessario usare un'identità gestita assegnata dal sistema, vedere l'articolo Identità gestite assegnate dal sistema per altre informazioni.

Creare un'identità gestita assegnata dall'utente

Le identità gestite assegnate dall'utente vengono create come risorse autonome nella sottoscrizione Azure usando il portale di Azure o il Azure CLI. I comandi di Azure CLI possono essere eseguiti nel Azure Cloud Shell o su una workstation con Azure CLI installata.

  1. Nel portale di Azure immettere Managed identities nella barra di ricerca principale e selezionare il risultato corrispondente nella sezione Services.

  2. Nella pagina Identità gestite selezionare + Crea.

    Screenshot che mostra la pagina per gestire le identità gestite assegnate dall'utente.

  3. Nella pagina Crea identità gestita assegnata dall'utente selezionare una sottoscrizione, un gruppo di risorse e un'area per l'identità gestita assegnata dall'utente e quindi specificare un nome.

  4. Seleziona Rivedi e crea per esaminare e convalidare i dati.

    Screenshot che mostra il modulo per creare un'identità gestita assegnata dall'utente.

  5. Selezionare Crea per creare l'identità gestita assegnata dall'utente.

  6. Dopo aver creato l'identità, selezionare Vai alla risorsa.

  7. Nella pagina panoramica della nuova identità, copiare il valore ID client da utilizzare successivamente per configurare il codice dell'applicazione.

Assegna l'identità gestita all'applicazione

Un'identità gestita assegnata dall'utente può essere associata a una o più risorse Azure. Tutte le risorse che usano tale identità ottengono le autorizzazioni applicate tramite i ruoli dell'identità.

  1. Nel portale di Azure passare alla risorsa che ospita il codice dell'app, ad esempio un'istanza di Azure App Service o Azure Container Apps.

  2. Nella Pagina Panoramica della risorsa, espandere Impostazioni e selezionare Identità nel menu di navigazione.

  3. Nella pagina Identità , passare alla scheda Assegnata dall'utente .

  4. Selezionare + Aggiungi per aprire il pannello Aggiungi identità gestita assegnata dall'utente.

  5. Nel pannello Aggiungi identità gestita assegnata dall'utente, usa il menu a discesa Sottoscrizione per filtrare i risultati della ricerca per le tue identità. Usare la casella di ricerca Identità gestite assegnate dall'utente per individuare l'identità gestita assegnata dall'utente abilitata per la risorsa Azure che ospita l'app.

  6. Selezionare l'identità e scegliere Aggiungi nella parte inferiore del pannello per continuare.

    Screenshot che mostra come associare un'identità gestita assegnata dall'utente a un'app.

Assegnare ruoli all'identità gestita

Successivamente, determinare i ruoli necessari per l'app e assegnare tali ruoli all'identità gestita. È possibile assegnare ruoli a un'identità gestita negli ambiti seguenti:

  • risorsa: i ruoli assegnati si applicano solo a tale risorsa specifica.
  • gruppo di risorse: i ruoli assegnati si applicano a tutte le risorse contenute nel gruppo di risorse.
  • Sottoscrizione: I ruoli assegnati si applicano a tutte le risorse contenute nella sottoscrizione.

L'esempio seguente illustra come assegnare ruoli nell'ambito del gruppo di risorse, poiché molte app gestiscono tutte le risorse Azure correlate usando un singolo gruppo di risorse.

  1. Passare alla pagina panoramica del gruppo di risorse che contiene l'app con l'identità gestita assegnata dall'utente.

  2. Selezionare Controllo di accesso (IAM) nella navigazione a sinistra.

  3. Nella pagina Controllo di accesso (IAM), seleziona + Aggiungi nel menu in alto e quindi scegli Aggiungi assegnazione di ruolo per passare alla pagina Aggiungi assegnazione di ruolo.

    Screenshot che mostra come accedere alla pagina di assegnazione dei ruoli di identità.

  4. La pagina Aggiungi assegnazione di ruolo presenta un flusso di lavoro a schede suddiviso in più passaggi per assegnare ruoli alle identità. Nella scheda iniziale Ruolo, usare la casella di ricerca in alto per individuare il ruolo da assegnare all'identità.

  5. Selezionare il ruolo nei risultati e quindi scegliere Avanti per passare alla scheda Membri.

  6. Per l'opzione Assegna accesso a, selezionare identità gestita.

  7. Per l'opzione Membri, scegliere + Seleziona membri per aprire il pannello Seleziona identità gestite.

  8. Nel pannello Seleziona identità gestite, utilizza i menu a tendina Sottoscrizione e Identità gestita per filtrare i risultati della ricerca delle tue identità. Usare la casella di ricerca Select per individuare l'identità gestita assegnata dall'utente abilitata per la risorsa Azure che ospita l'app.

    Screenshot che mostra il processo di assegnazione dell'identità gestita.

  9. Selezionare l'identità e scegliere Selezionare nella parte inferiore del pannello per continuare.

  10. Selezionare Rivedi e assegna nella parte inferiore della pagina.

  11. Nella scheda finale Rivedi e assegna, selezionare Rivedi e assegna per completare il flusso di lavoro.

Autenticarsi ai servizi di Azure dalla tua app

La libreria di identità Azure fornisce varie credentials: implementazioni di TokenCredential adattate al supporto di diversi scenari e flussi di autenticazione Microsoft Entra. Poiché l'identità gestita non è disponibile durante l'esecuzione in locale, i passaggi successivi illustrano quali credenziali usare in quale scenario:

  • ambiente di sviluppo locale: durante lo sviluppo locale solo, usare una classe denominata DefaultAzureCredential per una catena di credenziali preconfigurata e opinata. DefaultAzureCredential individua le credenziali utente dall'IDE o dagli strumenti locali, ad esempio il Azure CLI o l'Visual Studio. Offre inoltre flessibilità e praticità per i tentativi, i tempi di attesa per le risposte e il supporto per più opzioni di autenticazione. Per ulteriori informazioni, visitare l'articolo Autenticazione ai servizi Azure nello sviluppo locale.
  • Azure-hosted apps: quando l'app è in esecuzione in Azure, usare ManagedIdentityCredential per individuare in modo sicuro l'identità gestita configurata per l'app. La specifica di questo tipo esatto di credenziali impedisce che altre credenziali disponibili vengano prelevate in modo imprevisto.

Implementare il codice

  1. Aggiungere il pacchetto azure-identity-cpp all'applicazione usando vcpkg.

    In un terminale di propria scelta passare alla directory del progetto dell'applicazione ed eseguire il comando seguente:

    vcpkg add port azure-identity-cpp
    
  2. Aggiungere quanto segue nel file CMake:

    find_package(azure-identity-cpp CONFIG REQUIRED)
    target_link_libraries(<your project name> PRIVATE Azure::azure-identity)
    
  3. I servizi di Azure sono accessibili utilizzando client specializzati dalle varie librerie client dell'Azure SDK. Per qualsiasi codice C++ che crea un'istanza di un client Azure SDK nell'app, è necessario:

    1. Includere l'intestazione azure/identity.hpp .
    2. Crea un'istanza di DefaultAzureCredential.
    3. Passare l'istanza di DefaultAzureCredential al costruttore del client di Azure SDK.
    4. Impostare la variabile di ambiente AZURE_CLIENT_ID sull'ID client della propria identità gestita assegnata dall'utente.
    5. Impostare la AZURE_TOKEN_CREDENTIALS variabile di ambiente su ManagedIdentityCredential per assicurarsi che DefaultAzureCredential usi le credenziali dell'identità gestita. Questa procedura rende l'autenticazione più prevedibile e più semplice da eseguire durante la distribuzione in Azure. Per altre informazioni, vedere Usare credenziali specifiche.

    Un esempio di questi passaggi è illustrato nel segmento di codice seguente con un client BLOB Azure Storage.

    #include <azure/identity.hpp>
    #include <azure/storage/blobs.hpp>
    #include <iostream>
    #include <memory>
    #include <cstdlib>
    
    int main() {
        try {
            // Set the AZURE_CLIENT_ID environment variable to your user-assigned managed identity client ID
            // This can be done in your deployment environment or in code (shown below for demonstration)
            // std::putenv("AZURE_CLIENT_ID=your-user-assigned-identity-client-id");
    
            // Create a credential - DefaultAzureCredential will use the AZURE_CLIENT_ID environment variable
            // Create a credential - DefaultAzureCredential will use the AZURE_CLIENT_ID and AZURE_TOKEN_CREDENTIALS environment variables
            auto credential = std::make_shared<Azure::Identity::DefaultAzureCredential>(true);
    
            // Create a client for the specified storage account
            std::string accountUrl = "https://<replace_with_your_storage_account_name>.blob.core.windows.net/";
            Azure::Storage::Blobs::BlobServiceClient blobServiceClient(accountUrl, credential);
    
            // Get a reference to a container
            std::string containerName = "sample-container";
            auto containerClient = blobServiceClient.GetBlobContainerClient(containerName);
    
            // Get a reference to a blob
            std::string blobName = "sample-blob";
            auto blobClient = containerClient.GetBlobClient(blobName);
    
            // TODO: perform some action with the blob client
            // auto downloadResult = blobClient.DownloadTo("path/to/local/file");
    
            std::cout << "Successfully authenticated using user-assigned managed identity." << std::endl;
    
        } catch (const std::exception& ex) {
            std::cout << "Exception: " << ex.what() << std::endl;
            return 1;
        }
    
        return 0;
    }
    

Come descritto nell'articolo Azure SDK per l'autenticazione C++ articolo, DefaultAzureCredential supporta più metodi di autenticazione e determina il metodo di autenticazione usato in fase di esecuzione. Il vantaggio di questo approccio è che l'app può usare metodi di autenticazione diversi in ambienti diversi senza implementare codice specifico dell'ambiente. Quando il codice precedente viene eseguito sulla tua workstation durante lo sviluppo locale, DefaultAzureCredential usa un'entità servizio dell'applicazione, come determinato dalle impostazioni di ambiente, o le credenziali dello strumento di sviluppo per autenticarsi con altre risorse Azure. Di conseguenza, lo stesso codice può essere usato per autenticare l'app per Azure risorse durante lo sviluppo locale e quando viene distribuito in Azure.

Importante

DefaultAzureCredential semplifica l'autenticazione durante lo sviluppo di applicazioni distribuite in Azure combinando le credenziali usate negli ambienti di hosting Azure e le credenziali usate nello sviluppo locale. Nell'ambiente di produzione è preferibile usare un tipo di credenziale specifico, in modo che l'autenticazione sia più prevedibile e più semplice da eseguire.

Un'alternativa a DefaultAzureCredential consiste nell'usare ManagedIdentityCredential. I passaggi per l'utilizzo ManagedIdentityCredential sono uguali a per l'uso del DefaultAzureCredential tipo .

Un esempio di questi passaggi è illustrato nel segmento di codice seguente con un client BLOB Azure Storage.

#include <azure/identity.hpp>
#include <azure/storage/blobs.hpp>
#include <iostream>
#include <memory>

int main() {
    try {
        // Create a user-assigned managed identity credential with the client ID
        Azure::Identity::ManagedIdentityCredentialOptions options;
        options.ClientId = "abcd1234-..."; // Replace with your user-assigned managed identity client ID
        auto credential = std::make_shared<Azure::Identity::ManagedIdentityCredential>(options);
        
        // Create a client for the specified storage account
        std::string accountUrl = "https://<replace_with_your_storage_account_name>.blob.core.windows.net/";
        Azure::Storage::Blobs::BlobServiceClient blobServiceClient(accountUrl, credential);
        
        // Get a reference to a container
        std::string containerName = "sample-container";
        auto containerClient = blobServiceClient.GetBlobContainerClient(containerName);
        
        // Get a reference to a blob
        std::string blobName = "sample-blob";
        auto blobClient = containerClient.GetBlobClient(blobName);
        
        // TODO: perform some action with the blob client
        // auto downloadResult = blobClient.DownloadTo("path/to/local/file");
        
        std::cout << "Successfully authenticated using user-assigned managed identity." << std::endl;
        
    } catch (const std::exception& ex) {
        std::cout << "Exception: " << ex.what() << std::endl;
        return 1;
    }
    
    return 0;
}