Autenticare le app Python nei servizi di Azure durante lo sviluppo locale usando le entità servizio

Quando si creano applicazioni cloud, gli sviluppatori devono eseguire il debug e il test delle applicazioni nella workstation locale. Quando un'applicazione viene eseguita nella workstation di uno sviluppatore durante lo sviluppo locale, deve comunque eseguire l'autenticazione a tutti i servizi di Azure usati dall'app. Questo articolo illustra come configurare oggetti entità servizio dell'applicazione dedicati da usare durante lo sviluppo locale.

Diagramma che mostra come un'app in esecuzione nello sviluppatore locale ottiene l'entità servizio dell'applicazione da un file con estensione env e quindi usa tale identità per connettersi alle risorse di Azure.

Le entità servizio dell'applicazione dedicate per lo sviluppo locale consentono di seguire il principio dei privilegi minimi durante lo sviluppo di app. Poiché l'ambito delle autorizzazioni è esattamente quello necessario per l'app durante lo sviluppo, il codice dell'app non può accedere accidentalmente a una risorsa di Azure destinata all'uso da parte di un'app diversa. Ciò impedisce anche che si verifichino bug quando l'app viene spostata nell'ambiente di produzione perché l'app è stata privilegiata nell'ambiente di sviluppo.

Un'entità servizio dell'applicazione viene configurata per l'app quando l'app viene registrata in Azure. Quando si registrano app per lo sviluppo locale, è consigliabile:

  • Creare registrazioni app separate per ogni sviluppatore che lavora sull'app. In questo modo verranno create entità servizio dell'applicazione separate per ogni sviluppatore da usare durante lo sviluppo locale ed evitare la necessità per gli sviluppatori di condividere le credenziali per una singola entità servizio dell'applicazione.
  • Creare registrazioni di app separate per ogni app. Questo definisce l'ambito delle autorizzazioni dell'app solo a ciò che è necessario per l'app.

Durante lo sviluppo locale, le variabili di ambiente vengono impostate con l'identità dell'entità servizio dell'applicazione. Azure SDK per Python legge queste variabili di ambiente e usa queste informazioni per autenticare l'app alle risorse di Azure necessarie.

1 - Registrare l'applicazione in Azure

Gli oggetti entità servizio dell'applicazione vengono creati con una registrazione dell'app in Azure. Questa operazione può essere effettuata tramite il portale di Azure o l'interfaccia della riga di comando di Azure.

I comandi dell'interfaccia della riga di comando di Azure possono essere eseguiti in Azure Cloud Shell o in una workstation con l'interfaccia della riga di comando di Azure installata.

Per prima cosa, utilizzare il comando az ad sp create-for-rbac per creare una nuova entità servizio per l'applicazione. Il comando crea anche la registrazione dell'app per l'app contemporaneamente.

az ad sp create-for-rbac --name {service-principal-name}

L'output di questo comando sarà simile al seguente. Prendere nota di questi valori o mantenere aperta questa finestra perché questi valori saranno necessari nei passaggi successivi e non saranno più in grado di visualizzare di nuovo il valore della password (segreto client). È tuttavia possibile aggiungere una nuova password in un secondo momento senza invalidare l'entità servizio o le password esistenti, se necessario.

{
  "appId": "00000000-0000-0000-0000-000000000000",
  "displayName": "{service-principal-name}",
  "password": "abcdefghijklmnopqrstuvwxyz",
  "tenant": "33333333-3333-3333-3333-333333333333"
}

2 - Creare un gruppo di sicurezza Microsoft Entra per lo sviluppo locale

Poiché in genere sono presenti più sviluppatori che lavorano su un'applicazione, è consigliabile creare un gruppo di sicurezza Microsoft Entra per incapsulare i ruoli (autorizzazioni) necessari per lo sviluppo locale, anziché assegnare i ruoli ai singoli oggetti entità servizio. Ciò offre i vantaggi seguenti:

  • Ogni sviluppatore ha la certezza di avere gli stessi ruoli assegnati perché i ruoli vengono assegnati a livello di gruppo.
  • Se è necessario un nuovo ruolo per l'app, deve essere aggiunto solo al gruppo Microsoft Entra per l'app.
  • Se un nuovo sviluppatore si aggiunge al team, viene creata una nuova entità servizio dell'applicazione per lo sviluppatore e aggiunta al gruppo, assicurando che lo sviluppatore disponga delle autorizzazioni appropriate per lavorare sull'app.

Il comando az ad group create viene usato per creare gruppi di sicurezza in Microsoft Entra ID. I parametri --display-name e --main-nickname sono obbligatori. Il nome assegnato al gruppo deve essere basato sul nome dell'applicazione. È anche utile includere una stringa come local-dev nel nome del gruppo per indicare lo scopo del gruppo.

az ad group create \
    --display-name MyDisplay \
    --mail-nickname MyDisplay  \
    --description "<group-description>"

Copiare il valore della id proprietà nell'output del comando . ID oggetto per il gruppo. È necessario nei passaggi successivi. È anche possibile usare il comando az ad group show per recuperare questa proprietà.

Per aggiungere membri al gruppo, è necessario l'ID oggetto dell'entità servizio dell'applicazione, che è diverso dall'ID applicazione. Usare az ad sp list per elencare le entità servizio disponibili. Il comando del parametro --filter accetta filtri di stile OData e può essere usato per filtrare l'elenco come illustrato. Il parametro --query limita le colonne solo a quelle di interesse.

az ad sp list \
    --filter "startswith(displayName, 'msdocs')" \
    --query "[].{objectId:id, displayName:displayName}" \
    --output table

Il comando az ad group member add può quindi essere usato per aggiungere membri ai gruppi.

az ad group member add \
    --group <group-name> \
    --member-id <object-id>

Nota

Per impostazione predefinita, la creazione di gruppi di sicurezza Di Microsoft Entra è limitata a determinati ruoli con privilegi in una directory. Se non è possibile creare un gruppo, contattare un amministratore per la directory. Se non è possibile aggiungere membri a un gruppo esistente, contattare il proprietario del gruppo o un amministratore della directory. Per altre informazioni, vedere Gestire i gruppi di Microsoft Entra e l'appartenenza ai gruppi.

3 - Assegnare ruoli all'applicazione

Successivamente, è necessario determinare i ruoli (autorizzazioni) necessari per l'app in base alle risorse e assegnare tali ruoli all'app. In questo esempio i ruoli vengono assegnati al gruppo Microsoft Entra creato nel passaggio 2. I ruoli possono essere assegnati a una risorsa, a un gruppo di risorse o a un ambito di sottoscrizione. Questo esempio illustra come assegnare ruoli nell'ambito del gruppo di risorse perché la maggior parte delle applicazioni raggruppa tutte le risorse di Azure in un singolo gruppo di risorse.

A un utente, un gruppo o un'entità servizio dell'applicazione viene assegnato un ruolo in Azure usando il comando az role assignment create . È possibile specificare un gruppo con il relativo ID oggetto. È possibile specificare un'entità servizio dell'applicazione con il relativo id app.

az role assignment create --assignee {appId or objectId} \
    --scope /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName} \
    --role "{roleName}" 

Per ottenere i nomi dei ruoli che è possibile assegnare, usare il comando az role definition list .

az role definition list \
    --query "sort_by([].{roleName:roleName, description:description}, &roleName)" \
    --output table

Ad esempio, per consentire all'entità servizio dell'applicazione con il valore appId di 00000000-0000-0000-0000-000000000000 lettura, scrittura ed eliminazione dell'accesso a Archiviazione di Azure contenitori BLOB e dati in tutti gli account di archiviazione nel gruppo di risorse msdocs-python-sdk-auth-example nella sottoscrizione con ID 11111111-1111-1111-1111-111111111111, si assegnerebbe l'entità servizio dell'applicazione all'Archiviazione Collaboratore ai dati BLOB role using the following command.

az role assignment create --assignee 00000000-0000-0000-0000-000000000000 \
    --scope /subscriptions/11111111-1111-1111-1111-111111111111/resourceGroups/msdocs-python-sdk-auth-example \
    --role "Storage Blob Data Contributor"

Per informazioni sull'assegnazione delle autorizzazioni a livello di risorsa o sottoscrizione tramite l'interfaccia della riga di comando di Azure, vedere l'articolo Assegnare ruoli di Azure usando l'interfaccia della riga di comando di Azure.

4 - Impostare le variabili di ambiente di sviluppo locale

L'oggetto DefaultAzureCredential cercherà le informazioni sull'entità servizio in un set di variabili di ambiente in fase di esecuzione. Poiché la maggior parte degli sviluppatori lavora su più applicazioni, è consigliabile usare un pacchetto come python-dotenv per accedere all'ambiente da un .env file archiviato nella directory dell'applicazione durante lo sviluppo. In questo modo le variabili di ambiente usate per autenticare l'applicazione in Azure possono essere usate solo da questa applicazione.

Il .env file non viene mai archiviato nel controllo del codice sorgente perché contiene la chiave privata dell'applicazione per Azure. Il file con estensione gitignore standard per Python esclude automaticamente il file dall'archiviazione.env.

Per usare il pacchetto python-dotenv, installare prima di tutto il pacchetto nell'applicazione.

pip install python-dotenv

Creare quindi un .env file nella directory radice dell'applicazione. Impostare i valori delle variabili di ambiente con i valori ottenuti dal processo di registrazione dell'app come indicato di seguito:

  • AZURE_CLIENT_ID → Il valore dell'ID dell'app.
  • AZURE_TENANT_ID → Il valore dell'ID del tenant.
  • AZURE_CLIENT_SECRET → Password/credenziali generate per l'app.
AZURE_CLIENT_ID=00000000-0000-0000-0000-000000000000
AZURE_TENANT_ID=11111111-1111-1111-1111-111111111111
AZURE_CLIENT_SECRET=abcdefghijklmnopqrstuvwxyz

Infine, nel codice di avvio per l'applicazione usare la python-dotenv libreria per leggere le variabili di ambiente dal file all'avvio .env .

from dotenv import load_dotenv

if ( os.environ['ENVIRONMENT'] == 'development'):
    print("Loading environment variables from .env file")
    load_dotenv(".env")

5 - Implementare DefaultAzureCredential nell'applicazione

Per autenticare gli oggetti client di Azure SDK in Azure, l'applicazione deve usare la DefaultAzureCredential classe del azure.identity pacchetto. In questo scenario, DefaultAzureCredential rileverà le variabili AZURE_CLIENT_IDdi ambiente , AZURE_TENANT_IDe AZURE_CLIENT_SECRET vengono impostate e leggono tali variabili per ottenere le informazioni sull'entità servizio dell'applicazione con cui connettersi ad Azure.

Per iniziare, aggiungere il pacchetto azure.identity all'applicazione.

pip install azure-identity

Successivamente, per qualsiasi codice Python che crea un oggetto client Azure SDK nell'app, è necessario:

  1. Importare la DefaultAzureCredential classe dal azure.identity modulo.
  2. Creare un oggetto DefaultAzureCredential.
  3. Passare l'oggetto al costruttore dell'oggetto DefaultAzureCredential client di Azure SDK.

Un esempio è illustrato nel segmento di codice seguente.

from azure.identity import DefaultAzureCredential
from azure.storage.blob import BlobServiceClient

# Acquire a credential object
token_credential = DefaultAzureCredential()

blob_service_client = BlobServiceClient(
        account_url="https://<my_account_name>.blob.core.windows.net",
        credential=token_credential)