Eseguire l'autenticazione alle risorse di Azure dalle app Python ospitate in locale

Le app ospitate al di fuori di Azure (ad esempio in locale o in un data center di terze parti) devono usare un'entità servizio dell'applicazione per l'autenticazione in Azure quando accedono alle risorse di Azure. Gli oggetti entità servizio dell'applicazione vengono creati tramite il processo di registrazione delle app in Azure. Quando viene creata un'entità servizio dell'applicazione, viene generato un ID cliente e un segreto client per l'app. L'ID client, il segreto client e l'ID tenant vengono quindi archiviati in variabili di ambiente in modo che possano essere usati da Azure SDK per Python per autenticare l'app in Azure in fase di esecuzione.

È necessario creare una registrazione dell'app diversa per ogni ambiente in cui l'app è ospitata. In questo modo è possibile configurare autorizzazioni di risorse specifiche dell'ambiente per ogni entità servizio e assicurarsi che un'app distribuita in un ambiente non parli con le risorse di Azure che fanno parte di un altro ambiente.

1 - Registrare l'applicazione in Azure

Un'app può essere registrata con Azure usando il portale di Azure o l'interfaccia della riga di comando di Azure.

az ad sp create-for-rbac --name <app-name>

L'output del 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).

{
  "appId": "00001111-aaaa-2222-bbbb-3333cccc4444",
  "displayName": "msdocs-python-sdk-auth-prod",
  "password": "Ee5Ff~6Gg7.-Hh8Ii9Jj0Kk1Ll2Mm3_Nn4Oo5Pp6",
  "tenant": "aaaabbbb-0000-cccc-1111-dddd2222eeee"
}

2 - Assegnare ruoli all'entità servizio dell'applicazione

Successivamente, è necessario determinare i ruoli (autorizzazioni) necessari per l'app in base alle risorse e assegnare tali ruoli all'app. I ruoli possono essere assegnati a una risorsa, a gruppo di risorse o a una sottoscrizione. Questo esempio illustra come assegnare ruoli per l'entità servizio 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'entità servizio viene assegnato un ruolo in Azure usando il comando az role assignment create.

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

Per ottenere i nomi di ruolo a cui è possibile assegnare un'entità servizio, 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 l'entità servizio con il valore appId di 00001111-aaaa-2222-bbbb-3333cccc4444 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 aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e, si assegnerebbe l'entità servizio dell'applicazione al ruolo Collaboratore ai dati dei BLOB di archiviazione usando il comando seguente.

az role assignment create --assignee 00001111-aaaa-2222-bbbb-3333cccc4444 \
    --scope /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/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.

3 - Configurare le variabili di ambiente per l'applicazione

È necessario impostare le AZURE_CLIENT_IDvariabili di ambiente , AZURE_TENANT_IDe AZURE_CLIENT_SECRET per il processo che esegue l'app Python per rendere le credenziali dell'entità servizio dell'applicazione disponibili per l'app in fase di esecuzione. L'oggetto DefaultAzureCredential cerca le informazioni sull'entità servizio in queste variabili di ambiente.

Quando si usa Gunicorn per eseguire app Web Python in un ambiente server UNIX, le variabili di ambiente per un'app possono essere specificate usando la EnvironmentFile direttiva nel gunicorn.server file, come illustrato di seguito.

[Unit]
Description=gunicorn daemon
After=network.target  
  
[Service]  
User=www-user
Group=www-data
WorkingDirectory=/path/to/python-app
EnvironmentFile=/path/to/python-app/py-env/app-environment-variables
ExecStart=/path/to/python-app/py-env/gunicorn --config config.py wsgi:app
            
[Install]  
WantedBy=multi-user.target

Il file specificato nella EnvironmentFile direttiva deve contenere un elenco di variabili di ambiente con i relativi valori, come illustrato di seguito.

AZURE_CLIENT_ID=<value>
AZURE_TENANT_ID=<value>
AZURE_CLIENT_SECRET=<value>

4 - 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.

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)

Quando il codice precedente crea un'istanza dell'oggetto DefaultAzureCredential , DefaultAzureCredential legge le variabili AZURE_TENANT_IDdi ambiente , AZURE_CLIENT_IDe AZURE_CLIENT_SECRET per le informazioni sull'entità servizio dell'applicazione con cui connettersi ad Azure.