Partager via


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

Les développeurs doivent souvent exécuter et tester leurs applications localement lors de la création d’applications cloud. Même pendant le développement local, l’application doit s’authentifier auprès des services Azure avec lesquels elle interagit. Cet article explique comment configurer des identités de principal de service dédiées spécifiquement pour une utilisation pendant le développement local.

Un diagramme montrant comment une application exécutée en développement local obtient le principal de 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 suivent le principe du privilège minimum. Ils accordent uniquement l’accès aux ressources Azure dont l’application a besoin pendant le développement. Cet accès limité réduit le risque d’atteindre involontairement d’autres ressources. Il permet également d’empêcher les bogues liés aux autorisations lors du déplacement vers la production, où des autorisations plus larges peuvent entraîner des problèmes.

Lors de l’inscription d’applications pour le développement local dans Azure :

  • Créez des inscriptions d’applications distinctes pour chaque développeur : cette approche fournit à chaque développeur son propre principal de service, évitant ainsi la nécessité de partager des informations d’identification et d’activer un contrôle d’accès plus granulaire.
  • Créez des inscriptions d’applications distinctes pour chaque application : cette approche garantit que chaque application dispose uniquement des autorisations dont elle a besoin, ce qui réduit la surface d’attaque potentielle.

Pour activer l’authentification pendant le développement local, définissez des variables d’environnement avec les informations d’identification du principal du service d’application. Le Kit de développement logiciel (SDK) Azure pour Python détecte ces variables et les utilise pour authentifier les demandes auprès des services Azure.

Inscrire l’application dans Azure

Les objets principaux du service d’application sont créés lorsque vous inscrivez une application dans Azure. Cette inscription peut être effectuée à l’aide du portail Azure ou d’Azure CLI. Le processus d’inscription crée une inscription d’application dans Microsoft Entra ID et génère un objet principal de service pour l’application. L’objet principal de service est utilisé pour authentifier l’application auprès des services Azure. Le processus d’inscription d’application génère également un secret client (mot de passe) pour l’application. Ce secret est utilisé pour authentifier l’application auprès des services Azure. Le secret client n’est jamais stocké dans le contrôle de code source, mais plutôt dans un fichier .env dans le répertoire de l’application. Au moment de l’exécution, l’application lit le .env fichier et définit des variables d’environnement que le Kit de développement logiciel (SDK) Azure pour Python utilise pour authentifier l’application.

Les étapes suivantes montrent comment inscrire une application dans Azure et créer un principal de service pour l’application. Les étapes sont affichées pour Azure CLI et le portail Azure.

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'enregistrement de l'application en même temps.

SERVICE_PRINCIPAL_NAME=<service-principal-name>
az ad sp create-for-rbac --name $SERVICE_PRINCIPAL_NAME

La sortie de cette commande est similaire à ce qui suit. Notez ces valeurs ou gardez cette fenêtre ouverte car vous aurez besoin de ces valeurs dans les étapes suivantes et vous ne pourrez plus voir la valeur du mot de passe (secret client). Vous pouvez, cependant, ajouter un nouveau mot de passe plus tard sans invalider le principal de service ou les mots de passe existants si nécessaire.

{
  "appId": "00001111-aaaa-2222-bbbb-3333cccc4444",
  "displayName": "<service-principal-name>",
  "password": "Ee5Ff~6Gg7.-Hh8Ii9Jj0Kk1Ll2Mm3_Nn4Oo5Pp6",
  "tenant": "aaaabbbb-0000-cccc-1111-dddd2222eeee"
}

Ensuite, vous devez obtenir la appID valeur et la stocker dans une variable. Cette valeur est utilisée pour définir des variables d’environnement dans votre environnement de développement local afin que le Kit de développement logiciel (SDK) Azure pour Python puisse s’authentifier auprès d’Azure à l’aide du principal de service.

APP_ID=$(az ad sp list \
  --all \
  --query "[?displayName=='$SERVICE_PRINCIPAL_NAME'].appId | [0]" \
  --output tsv)

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

Étant donné que plusieurs développeurs travaillent généralement sur la même application, il est préférable de gérer les autorisations via un groupe de sécurité Microsoft Entra. Créez un groupe de sécurité qui contient les rôles dont l’application a besoin pour le développement local, au lieu d’attribuer des rôles au principal du service de chaque développeur individuellement. L’utilisation d’un groupe de sécurité 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 suffit de l'ajouter 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 permet de 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.

GROUP_DISPLAY_NAME="<group-name>"
GROUP_MAIL_NICKNAME="<group-mail-nickname>"
GROUP_DESCRIPTION="<group-description>"
az ad group create \
  --display-name $GROUP_DISPLAY_NAME \
  --mail-nickname $GROUP_MAIL_NICKNAME \
  --description $GROUP_DESCRIPTION

Pour ajouter des membres au groupe, vous avez besoin de l’ID d’objet du principal de 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 --query paramètre limite les colonnes aux seules colonnes qui vous intéressent.

SP_OBJECT_ID=$(az ad sp list \
  --filter "startswith(displayName,'$GROUP_DISPLAY_NAME')" \
  --query "[0].id" \
  --output tsv)

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_DISPLAY_NAME \
    --member-id $SP_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(e) administrateur(-trice) pour votre annuaire. Si vous ne parvenez pas à ajouter des membres à un groupe existant, contactez le propriétaire du groupe ou un(e) administrateur(-trice) d’annuaire. Pour plus d’informations, consultez Gérer les groupes Microsoft Entra et l’appartenance à un groupe.

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 attribués au groupe Microsoft Entra créé à l'étape 2. Les rôles peuvent être attribués au niveau d'une ressource, d'un groupe de ressources ou de l'étendue d'un abonnement. Cet exemple montre comment attribuer des rôles au niveau du groupe de ressources, car la plupart des applications regroupent toutes leurs ressources Azure dans un seul groupe de ressources.

Utilisez la az role assignment create commande pour attribuer un rôle à un utilisateur, un groupe ou un principal de service d’application. Vous pouvez spécifier un groupe avec son ID d'objet. Vous pouvez spécifier un principal de service d'application avec son appId.

RESOURCE_GROUP_NAME=<resource-group-name>
SUBSCRIPTION_ID=$(az account show --query id --output tsv)
ROLE_NAME=<role-name>
az role assignment create \
  --assignee "$APP_ID" \
  --scope "./subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP_NAME" \
  --role "$ROLE_NAME"

![! REMARQUE] Pour empêcher Git Bash de traiter /subscriptions/... en tant que chemin de fichier, ajoutez ./ au début de la chaîne pour le paramètre scope et utilisez des guillemets doubles autour de toute la chaîne.

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 de service d'application avec l'appId de 00001111-aaaa-2222-bbbb-3333cccc4444 à accéder en lecture, écriture et suppression aux conteneurs et données blob d'Azure Storage dans tous les comptes de stockage du groupe de ressources msdocs-python-sdk-auth-example dans l'abonnement avec ID aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e, vous affecteriez le principal de service d'application au rôle Contributeur de données blob de stockage à l'aide de la commande suivante.

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"

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.

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

L’objet DefaultAzureCredential recherche les informations du 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, utilisez 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. Cette configuration étend les variables d’environnement afin que seule cette application puisse les utiliser pour s’authentifier auprès d’Azure.

Le fichier .env n'est jamais vérifié dans le contrôle de source car il contient la clé secrète de l'application pour Azure. Le fichier standard .gitignore pour Python exclut automatiquement le fichier .env du check-in.

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

pip install python-dotenv

Ensuite, créez un fichier .env dans le répertoire racine de votre application. Définissez les valeurs des variables d'environnement avec les valeurs obtenues lors du processus d'enregistrement de l'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=00001111-aaaa-2222-bbbb-3333cccc4444
AZURE_TENANT_ID=aaaabbbb-0000-cccc-1111-dddd2222eeee
AZURE_CLIENT_SECRET=Ee5Ff~6Gg7.-Hh8Ii9Jj0Kk1Ll2Mm3_Nn4Oo5Pp6

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

from dotenv import load_dotenv

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

Implémenter DefaultAzureCredential dans votre application

Pour authentifier les objets clients du SDK Azure auprès d'Azure, votre application doit utiliser la classe DefaultAzureCredential du package azure.identity. Dans ce scénario, DefaultAzureCredential détecte que les variables d’environnement AZURE_CLIENT_ID, AZURE_TENANT_ID et AZURE_CLIENT_SECRET sont définies, et lit ces variables pour obtenir les informations du principal du service d’application nécessaires à la connexion à 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 azure SDK dans votre application :

  1. Importez la classe DefaultAzureCredential du module azure.identity.
  2. Créez un objet DefaultAzureCredential.
  3. Transmettez l'objet DefaultAzureCredential au constructeur de l'objet client du 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)