Authentifier des applications Python auprès des services Azure pendant le développement local à l’aide de principaux de service

Lors de la création d’applications cloud, les développeurs doivent déboguer et tester des applications sur leur station de travail locale. Lorsqu’une application est exécutée sur la station de travail d’un développeur pendant le développement local, elle doit toujours s’authentifier auprès des services Azure utilisés par l’application. Cet article explique comment configurer des objets de principal de service d’application dédiés à utiliser pendant le développement local.

Diagramme montrant comment une application s’exécutant dans un développeur local obtient le principal du service d’application à partir d’un fichier .env, puis utilise cette identité pour se connecter aux ressources Azure.

Les principaux de service d’application dédiés pour le développement local vous permettent de suivre le principe des privilèges minimum pendant le développement de l’application. Étant donné que les autorisations sont limitées exactement à ce qui est nécessaire pour l’application pendant le développement, le code de l’application ne peut pas accéder accidentellement à une ressource Azure destinée à une autre application. Cela empêche également les bogues de se produire lorsque l’application est déplacée en production, car l’application était trop privilégiée dans l’environnement de développement.

Un principal de service d’application est configuré pour l’application lorsque l’application est inscrite dans Azure. Lors de l’inscription d’applications pour le développement local, il est recommandé de :

  • Créez des inscriptions d’application distinctes pour chaque développeur travaillant sur l’application. Cela crée des principaux de service d’application distincts pour chaque développeur à utiliser pendant le développement local et évite aux développeurs d’avoir à partager des informations d’identification pour un seul principal de service d’application.
  • Créez des inscriptions d’applications distinctes par application. Cela limite les autorisations de l’application à ce qui est nécessaire à l’application.

Pendant le développement local, les variables d’environnement sont définies avec l’identité du principal du service d’application. Le Kit de développement logiciel (SDK) Azure pour Python lit ces variables d’environnement et utilise ces informations pour authentifier l’application auprès des ressources Azure dont elle a besoin.

1. Enregistrement de l'application dans Azure AD

Les objets de principal du service d’application sont créés avec une inscription d’application dans Azure. Pour ce faire, utilisez le Portail Azure ou Azure CLI.

Les commandes Azure CLI peuvent être exécutées dans Azure Cloud Shell ou sur une station de travail dans laquelle l’interface Azure CLI est installée.

Tout d’abord, utilisez la commande az ad sp create-for-rbac pour créer un principal de service pour l’application. La commande crée également l’inscription d’application pour l’application en même temps.

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

La sortie de cette commande doit ressembler à l’exemple ci-dessous. Notez ces valeurs ou laissez cette fenêtre ouverte, car vous aurez besoin de ces valeurs dans les étapes suivantes et ne pourrez plus afficher la valeur de mot de passe (clé secrète client). Toutefois, vous pouvez ajouter un nouveau mot de passe ultérieurement sans invalider le principal de service ou les mots de passe existants si nécessaire.

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

2 - Créer un groupe de sécurité Microsoft Entra pour le développement local

Étant donné qu’il existe généralement plusieurs développeurs qui travaillent sur une application, il est recommandé de créer un groupe de sécurité Microsoft Entra pour encapsuler les rôles (autorisations) dont l’application a besoin dans le développement local, plutôt que d’affecter les rôles à des objets de principal de service individuels. Cela offre les avantages suivants :

  • Chaque développeur est assuré d’avoir les mêmes rôles attribués, car les rôles sont attribués au niveau du groupe.
  • Si un nouveau rôle est nécessaire pour l’application, il doit uniquement être ajouté au groupe Microsoft Entra pour l’application.
  • Si un nouveau développeur rejoint l’équipe, un nouveau principal de service d’application est créé pour le développeur et ajouté au groupe, ce qui garantit que le développeur dispose des autorisations appropriées pour travailler sur l’application.

La commande az ad group create est utilisée pour créer des groupes de sécurité dans Microsoft Entra ID. Les paramètres --display-name et --main-nickname sont obligatoires. Le nom donné au groupe doit être basé sur le nom de l’application. Il est également utile d’inclure une expression telle que « local-dev » dans le nom du groupe pour indiquer l’objectif du groupe.

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

Copiez la valeur de la id propriété dans la sortie de la commande. Il s’agit de l’ID d’objet du groupe. Vous en avez besoin dans les étapes ultérieures. Vous pouvez également utiliser la commande az ad group show pour récupérer cette propriété.

Pour ajouter des membres au groupe, vous avez besoin de l’ID d’objet du principal du service d’application, qui est différent de l’ID d’application. Utilisez la liste az ad sp pour répertorier les principaux de service disponibles. La commande de paramètre --filter accepte les filtres de style OData et peut être utilisée pour filtrer la liste comme indiqué. Le paramètre --query limite les colonnes aux seules colonnes intéressantes.

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

La commande az ad group member add peut ensuite être utilisée pour ajouter des membres à des groupes.

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

Remarque

Par défaut, la création de groupes de sécurité Microsoft Entra est limitée à certains rôles privilégiés dans un répertoire. Si vous ne parvenez pas à créer un groupe, contactez un administrateur pour votre annuaire. Si vous ne parvenez pas à ajouter des membres à un groupe existant, contactez le propriétaire du groupe ou un administrateur d’annuaire. Pour plus d’informations, consultez Gérer les groupes Microsoft Entra et l’appartenance aux groupes.

3 - Attribuer des rôles à l’application

Ensuite, vous devez déterminer les rôles (autorisations) dont votre application a besoin sur les ressources et affecter ces rôles à votre application. Dans cet exemple, les rôles sont affectés au groupe Microsoft Entra créé à l’étape 2. Les rôles peuvent être attribués à une ressource, un groupe de ressources ou une étendue d’abonnement. Cet exemple montre comment attribuer des rôles à l’étendue du groupe de ressources, car la plupart des applications regroupent toutes leurs ressources Azure dans un seul groupe de ressources.

Un utilisateur, un groupe ou un principal de service d’application est affecté à un rôle dans Azure à l’aide de la commande az role assignment create . Vous pouvez spécifier un groupe avec son ID d’objet. Vous pouvez spécifier un principal de service d’application avec son appId.

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

Pour obtenir les noms de rôles qui peuvent être attribués, utilisez la commande az role definition list .

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

Par exemple, pour autoriser le principal du service d’application avec l’appId de 00000000-0000-0000-0000-000000000000 lecture, d’écriture et de suppression de l’accès à Stockage Azure conteneurs d’objets blob et aux données dans tous les comptes de stockage du groupe de ressources msdocs-python-sdk-auth-example dans l’abonnement avec l’ID11111111-1111-1111-1111-111111111111, vous devez affecter le principal du service d’application au rôle contributeur de données blob Stockage à l’aide de la commande suivante.

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"

Pour plus d’informations sur l’attribution d’autorisations au niveau de la ressource ou de l’abonnement à l’aide d’Azure CLI, consultez l’article Attribuer des rôles Azure à l’aide d’Azure CLI.

4 - Définir des variables d’environnement de développement local

L’objet DefaultAzureCredential recherche les informations de principal de service dans un ensemble de variables d’environnement au moment de l’exécution. Étant donné que la plupart des développeurs travaillent sur plusieurs applications, il est recommandé d’utiliser un package comme python-dotenv pour accéder à l’environnement à partir d’un .env fichier stocké dans le répertoire de l’application pendant le développement. Cela limite les variables d’environnement utilisées pour authentifier l’application auprès d’Azure afin qu’elles ne puissent être utilisées que par cette application.

Le .env fichier n’est jamais case activée dans le contrôle de code source, car il contient la clé secrète d’application pour Azure. Le fichier .gitignore standard pour Python exclut automatiquement le .env fichier de case activée-in.

Pour utiliser le package python-dotenv, installez d’abord le package dans votre application.

pip install python-dotenv

Ensuite, créez un .env fichier dans le répertoire racine de votre application. Définissez les valeurs de variable d’environnement avec les valeurs obtenues à partir du processus d’inscription d’application comme suit :

  • AZURE_CLIENT_ID → Valeur de l’ID d’application.
  • AZURE_TENANT_ID → Valeur de l’ID de locataire.
  • AZURE_CLIENT_SECRET → Mot de passe/informations d’identification générés pour l’application.
AZURE_CLIENT_ID=00000000-0000-0000-0000-000000000000
AZURE_TENANT_ID=11111111-1111-1111-1111-111111111111
AZURE_CLIENT_SECRET=abcdefghijklmnopqrstuvwxyz

Enfin, dans le code de démarrage de votre application, utilisez la python-dotenv bibliothèque pour lire les variables d’environnement à partir du .env fichier au démarrage.

from dotenv import load_dotenv

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

5 - Implémenter DefaultAzureCredential dans votre application

Pour authentifier les objets clients du Kit de développement logiciel (SDK) Azure sur Azure, votre application doit utiliser la DefaultAzureCredential classe à partir du azure.identity package. Dans ce scénario, DefaultAzureCredential détecte les variables AZURE_CLIENT_IDd’environnement, AZURE_TENANT_IDet définit et AZURE_CLIENT_SECRET lit ces variables pour obtenir les informations du principal du service d’application avec lesquelles se connecter à Azure.

Commencez par ajouter le package azure.identity à votre application.

pip install azure-identity

Ensuite, pour tout code Python qui crée un objet client du Kit de développement logiciel (SDK) Azure dans votre application, vous devez :

  1. Importez la DefaultAzureCredential classe à partir du azure.identity module.
  2. Créez un objet DefaultAzureCredential.
  3. Transmettez l’objet DefaultAzureCredential au constructeur d’objet client du Kit de développement logiciel (SDK) Azure.

Un exemple de cela est illustré dans le segment de code suivant.

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)