Authentifizieren von Python-Apps bei Azure-Diensten während der lokalen Entwicklung mithilfe von Dienstprinzipalen
Beim Erstellen von Cloudanwendungen müssen Entwickler Anwendungen auf ihrer lokalen Arbeitsstation debuggen und testen. Wenn eine Anwendung während der lokalen Entwicklung auf der Arbeitsstation eines Entwicklers ausgeführt wird, muss sie sich weiterhin bei allen von der App verwendeten Azure-Diensten authentifizieren. In diesem Artikel erfahren Sie, wie Sie dedizierte Anwendungsdienstprinzipalobjekte einrichten, die während der lokalen Entwicklung verwendet werden sollen.
Dedizierte Anwendungsdienstprinzipale für die lokale Entwicklung ermöglichen es Ihnen, das Prinzip der geringsten Rechte während der App-Entwicklung zu befolgen. Da Berechtigungen genau auf das festgelegt sind, was für die App während der Entwicklung benötigt wird, wird der App-Code daran gehindert, versehentlich auf eine Azure-Ressource zuzugreifen, die für die Verwendung durch eine andere App vorgesehen ist. Dadurch wird auch verhindert, dass Fehler auftreten, wenn die App in die Produktion verschoben wird, da die App in der Entwicklungsumgebung überprivilegiert war.
Ein Anwendungsdienstprinzipal wird für die App eingerichtet, wenn die App in Azure registriert ist. Beim Registrieren von Apps für die lokale Entwicklung wird Folgendes empfohlen:
- Erstellen Sie separate App-Registrierungen für jeden Entwickler, der an der App arbeitet. Dadurch werden separate Anwendungsdienstprinzipale für jeden Entwickler erstellt, die während der lokalen Entwicklung verwendet werden können, und entwickler müssen Keine Anmeldeinformationen für einen einzelnen Anwendungsdienstprinzipal freigeben.
- Erstellen Sie separate App-Registrierungen pro App. Dadurch werden die Berechtigungen der App nur auf das festgelegt, was von der App benötigt wird.
Während der lokalen Entwicklung werden Umgebungsvariablen mit der Identität des Anwendungsdienstprinzipals festgelegt. Das Azure SDK für Python liest diese Umgebungsvariablen und verwendet diese Informationen, um die App bei den benötigten Azure-Ressourcen zu authentifizieren.
1 - Registrieren der Anwendung in Azure AD
Anwendungsdienstprinzipalobjekte werden mit einer App-Registrierung in Azure erstellt. Hierfür können Sie das Azure-Portal oder die Azure CLI verwenden.
Azure CLI-Befehle können in der Azure Cloud Shell oder auf einer Workstation mit installierter Azure CLI ausgeführt werden.
Verwenden Sie zunächst den Befehl az ad sp create-for-rbac , um einen neuen Dienstprinzipal für die App zu erstellen. Der Befehl erstellt auch gleichzeitig die App-Registrierung für die App.
az ad sp create-for-rbac --name <service-principal-name>
Die Ausgabe dieses Befehls sollte wie im folgenden Beispiel aussehen. Notieren Sie sich diese Werte, oder lassen Sie dieses Fenster geöffnet, da Sie diese Werte für die nächsten Schritte benötigen und der Wert des Kennworts (Client-Secret) nicht erneut angezeigt wird. Sie können aber bei Bedarf später ein neues Kennwort hinzufügen, ohne den Dienstprinzipal oder vorhandene Kennwörter ungültig zu machen.
{
"appId": "00001111-aaaa-2222-bbbb-3333cccc4444",
"displayName": "<service-principal-name>",
"password": "Ee5Ff~6Gg7.-Hh8Ii9Jj0Kk1Ll2Mm3_Nn4Oo5Pp6",
"tenant": "aaaabbbb-0000-cccc-1111-dddd2222eeee"
}
2 – Erstellen einer Microsoft Entra-Sicherheitsgruppe für die lokale Entwicklung
Da in der Regel mehrere Entwickler an einer Anwendung arbeiten, wird empfohlen, eine Microsoft Entra-Sicherheitsgruppe zu erstellen, um die Rollen (Berechtigungen) einzuschließen, die die App bei der lokalen Entwicklung benötigt, anstatt die Rollen einzelnen Dienstprinzipalobjekten zuzuweisen. Dies bietet die folgenden Vorteile:
- Jedem Entwickler wird sichergestellt, dass dieselben Rollen zugewiesen werden, da Rollen auf Gruppenebene zugewiesen werden.
- Wenn eine neue Rolle für die App benötigt wird, muss sie nur der Microsoft Entra-Gruppe für die App hinzugefügt werden.
- Wenn ein neuer Entwickler dem Team beitritt, wird ein neuer Anwendungsdienstprinzipal für den Entwickler erstellt und der Gruppe hinzugefügt, um zu sorgen, dass der Entwickler über die richtigen Berechtigungen für die Arbeit an der App verfügt.
Der Befehl az ad group create wird verwendet, um Sicherheitsgruppen in Microsoft Entra ID zu erstellen. Die --display-name
- und --main-nickname
-Parameter sind erforderlich. Der der Gruppe angegebene Name sollte auf dem Namen der Anwendung basieren. Es ist auch hilfreich, eine Zeichenfolge wie local-dev in den Namen der Gruppe aufzunehmen, um den Zweck der Gruppe anzugeben.
az ad group create \
--display-name MyDisplay \
--mail-nickname MyDisplay \
--description "<group-description>"
Kopieren Sie den Wert der id
-Eigenschaft in die Ausgabe des Befehls. Dies ist die Objekt-ID für die Gruppe. Sie benötigen sie in späteren Schritten. Sie können auch den Befehl az ad group show zum Abrufen dieser Eigenschaft verwenden.
Zum Hinzufügen von Mitgliedern zur Gruppe benötigen Sie die Objekt-ID des Anwendungsdienstprinzipals, die sich von der Anwendungs-ID unterscheidet. Verwenden Sie die az ad sp list , um die verfügbaren Dienstprinzipale aufzulisten. Der --filter
Parameterbefehl akzeptiert OData-Formatfilter und kann verwendet werden, um die Liste wie gezeigt zu filtern. Der --query
Parameter beschränkt sich auf Spalten auf die von Interesse.
az ad sp list \
--filter "startswith(displayName, 'msdocs')" \
--query "[].{objectId:id, displayName:displayName}" \
--output table
Der Befehl az ad group member add kann dann verwendet werden, um Gruppen Mitglieder hinzuzufügen.
az ad group member add \
--group <group-name> \
--member-id <object-id>
Hinweis
Standardmäßig ist die Erstellung von Microsoft Entra-Sicherheitsgruppen auf bestimmte privilegierte Rollen in einem Verzeichnis beschränkt. Wenn Sie keine Gruppe erstellen können, wenden Sie sich an einen Administrator für Ihr Verzeichnis. Wenn Sie einer vorhandenen Gruppe keine Mitglieder hinzufügen können, wenden Sie sich an den Gruppenbesitzer oder einen Verzeichnisadministrator. Weitere Informationen finden Sie unter Verwalten von Microsoft Entra-Gruppen und -Gruppenmitgliedschaften.
3 : Zuweisen von Rollen zur Anwendung
Als Nächstes müssen Sie bestimmen, welche Rollen (Berechtigungen) Ihre App für welche Ressourcen benötigt, und diese Rollen Ihrer App zuweisen. In diesem Beispiel werden die Rollen der Microsoft Entra-Gruppe zugewiesen, die in Schritt 2 erstellt wurde. Rollen können in einem Ressourcen-, Ressourcengruppen- oder Abonnementbereich zugewiesen werden. In diesem Beispiel wird gezeigt, wie Sie Rollen auf der Ebene der Ressourcengruppe zuweisen, da die meisten Anwendungen alle ihre Azure-Ressourcen in einer einzigen Ressourcengruppe zusammenfassen.
Einem Benutzer, einer Gruppe oder einem Anwendungsdienstprinzipal wird in Azure mit dem Befehl az role assignment create eine Rolle zugewiesen. Sie können eine Gruppe mit ihrer Objekt-ID angeben. Sie können einen Anwendungsdienstprinzipal mit seiner appId angeben.
az role assignment create --assignee <appId or objectId> \
--scope /subscriptions/<subscriptionId>/resourceGroups/<resourceGroupName> \
--role "<roleName>"
Verwenden Sie den Befehl az role definition list, um die Rollennamen abzurufen, die zugewiesen werden können.
az role definition list \
--query "sort_by([].{roleName:roleName, description:description}, &roleName)" \
--output table
Um beispielsweise dem Anwendungsdienstprinzipal mit der appId 00001111-aaaa-2222-bbbb-3333cccc4444
Lese-, Schreib- und Lösch-Zugang zu Azure Storage-Blob-Containern und Daten in allen Speicherkonten in der Ressourcengruppe msdocs-python-sdk-auth-example im Rahmen des Abonnements mit der ID aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e
zu gewähren, weisen Sie den Anwendungsdienstprinzipal mithilfe des folgenden Befehls der Rolle Storage Blob Data Contributor zu.
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"
Informationen zum Zuweisen von Berechtigungen auf Ressourcen- oder Abonnementebene mithilfe der Azure CLI finden Sie im Artikel Zuweisen von Azure-Rollen mithilfe der Azure CLI.
4 – Einrichten von Umgebungsvariablen für die lokale Entwicklung
Das DefaultAzureCredential
-Objekt sucht zur Laufzeit nach den Dienstprinzipalinformationen in einer Reihe von Umgebungsvariablen. Da die meisten Entwickler an mehreren Anwendungen arbeiten, wird empfohlen, ein Paket wie python-dotenv für den Zugriff auf die Umgebung aus einer .env
-Datei heraus zu verwenden, die während der Entwicklung im Verzeichnis der Anwendung gespeichert ist. Dadurch werden die Umgebungsvariablen für die Authentifizierung der Anwendung bei Azure so verwendet, dass sie nur von dieser Anwendung verwendet werden können.
Die Datei .env
wird nie in die Quellcodeverwaltung eingecheckt, da sie das Anwendungsgeheimnis für Azure enthält. Die standardmäßige .gitignore-Datei für Python schließt die .env
-Datei automatisch vom Einchecken aus.
Um das python-dotenv-Paket zu verwenden, installieren Sie zuerst das Paket in Ihrer Anwendung.
pip install python-dotenv
Erstellen Sie dann eine .env
-Datei im Stammverzeichnis Ihrer Anwendung. Legen Sie die Umgebungsvariablen mit Werten fest, die wie folgt aus dem App-Registrierungsprozess abgerufen werden:
AZURE_CLIENT_ID
→ Der App-ID-Wert.AZURE_TENANT_ID
→ Der Wert der Mandanten-ID.AZURE_CLIENT_SECRET
→ Das für die App generierte Kennwort/Anmeldeinformationen.
AZURE_CLIENT_ID=00001111-aaaa-2222-bbbb-3333cccc4444
AZURE_TENANT_ID=aaaabbbb-0000-cccc-1111-dddd2222eeee
AZURE_CLIENT_SECRET=Ee5Ff~6Gg7.-Hh8Ii9Jj0Kk1Ll2Mm3_Nn4Oo5Pp6
Verwenden Sie schließlich im Startcode für Ihre Anwendung die python-dotenv
-Bibliothek, um die Umgebungsvariablen aus der .env
-Datei beim Start zu lesen.
from dotenv import load_dotenv
if ( os.environ['ENVIRONMENT'] == 'development'):
print("Loading environment variables from .env file")
load_dotenv(".env")
5 - Implementieren von DefaultAzureCredential in Ihrer Anwendung
Um Azure SDK-Clientobjekte für Azure zu authentifizieren, sollte Ihre Anwendung die DefaultAzureCredential
-Klasse aus dem azure.identity
-Paket verwenden. In diesem Szenario erkennt DefaultAzureCredential
die Umgebungsvariablen AZURE_CLIENT_ID
, AZURE_TENANT_ID
und AZURE_CLIENT_SECRET
, richtet sie ein und liest sie, um die Informationen zu dem Anwendungsdienstprinzipal zu erhalten, der mit Azure verbunden werden soll.
Fügen Sie Ihrer Anwendung zunächst das Paket azure.identity hinzu.
pip install azure-identity
Danach sollten Sie für jeden Python-Code, der ein Azure SDK-Clientobjekt in Ihrer App erstellt, Folgendes ausführen:
- Importieren Sie die
DefaultAzureCredential
-Klasse aus demazure.identity
-Modul. - Erstellen eines
DefaultAzureCredential
-Objekts - Übergeben Sie das
DefaultAzureCredential
-Objekt an den Azure SDK-Clientobjektkonstruktor.
Ein Beispiel dafür wird im folgenden Codeausschnitt gezeigt.
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)