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.

Ein Diagramm, das zeigt, wie eine App, die in lokalen Entwicklern ausgeführt wird, den Anwendungsdienstprinzipal aus einer env-Datei abruft und diese Identität dann zum Herstellen einer Verbindung mit Azure-Ressourcen verwendet.

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 die App-Registrierung für die App gleichzeitig.

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 in den nächsten Schritten benötigen und den Wert des Kennworts (geheimer Clientschlüssel) nicht erneut anzeigen können. Sie können jedoch später ein neues Kennwort hinzufügen, ohne den Dienstprinzipal oder vorhandene Kennwörter bei Bedarf ungültig zu machen.

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

2 – Erstellen einer Microsoft Entra-Sicherheitsgruppe für die lokale Entwicklung

Da es in der Regel mehrere Entwickler gibt, die an einer Anwendung arbeiten, empfiehlt es sich, eine Microsoft Entra-Sicherheitsgruppe zu erstellen, um die Rollen (Berechtigungen) zu kapseln, die die App in 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 erforderlich ist, 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 zum Erstellen von Az-Anzeigengruppen wird verwendet, um Sicherheitsgruppen in der 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 der 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" verwenden, um diese Eigenschaft abzurufen.

Um der Gruppe Mitglieder hinzuzufügen, 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 In Schritt 2 erstellten Microsoft Entra-Gruppe zugewiesen. Rollen können einer Ressource, Einer Ressourcengruppe oder einem Abonnementbereich zugewiesen werden. In diesem Beispiel wird gezeigt, wie Rollen im Ressourcengruppenbereich zugewiesen werden, da die meisten Anwendungen alle ihre Azure-Ressourcen in einer einzelnen Ressourcengruppe gruppieren.

Einem Benutzer, einer Gruppe oder einem Anwendungsdienstprinzipal wird eine Rolle in Azure mithilfe des Befehls "az role assignment create " zugewiesen. Sie können eine Gruppe mit seiner 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}" 

Um die Rollennamen abzurufen, die zugewiesen werden können, verwenden Sie den Befehl "az role definition list" .

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

Um beispielsweise den Anwendungsdienstprinzipal mit der appId des 00000000-0000-0000-0000-000000000000 Lese-, Schreib- und Löschzugriffs auf Azure Storage-Blobcontainer und -Daten in allen Speicherkonten in der Beispielressourcengruppe "msdocs-python-auth-auth" im Abonnement mit ID 11111111-1111-1111-1111-111111111111zuzulassen, würden Sie den Dienstprinzipal dem Rollen "Mitwirkender von Speicher-Blobdaten" mithilfe des folgenden Befehls zuweisen.

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"

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 – Festlegen lokaler Entwicklungsumgebungsvariablen

Das DefaultAzureCredential -Objekt sucht zur Laufzeit nach den Dienstprinzipalinformationen in einer Reihe von Umgebungsvariablen. Da die meisten Entwickler an mehreren Anwendungen arbeiten, empfiehlt es sich, ein Paket wie python-dotenv für den Zugriff auf die Umgebung aus einer .env Datei zu verwenden, die während der Entwicklung im Verzeichnis der Anwendung gespeichert ist. Dadurch werden die Umgebungsvariablen verwendet, um die Anwendung bei Azure zu authentifizieren, sodass sie nur von dieser Anwendung verwendet werden können.

Die .env Datei wird nie in die Quellcodeverwaltung eingecheckt, da sie den geheimen Anwendungsschlüssel für Azure enthält. Die standardmäßige GITIGnore-Datei für Python schließt die .env Datei automatisch aus dem 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 in Ihrem Anwendungsstammverzeichnis. Legen Sie die Umgebungsvariablenwerte mit Werten fest, die aus dem App-Registrierungsprozess wie folgt 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=00000000-0000-0000-0000-000000000000
AZURE_TENANT_ID=11111111-1111-1111-1111-111111111111
AZURE_CLIENT_SECRET=abcdefghijklmnopqrstuvwxyz

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 werden die Umgebungsvariablen AZURE_TENANT_IDAZURE_CLIENT_ID, und diese Variablen werden festgelegt und AZURE_CLIENT_SECRET gelesen, DefaultAzureCredential um die Informationen zum Anwendungsdienstprinzipal abzurufen, um eine Verbindung mit Azure herzustellen.

Fügen Sie zunächst das Azure.Identity-Paket zu Ihrer Anwendung hinzu.

pip install azure-identity

Als Nächstes sollten Sie für jeden Python-Code, der ein Azure SDK-Clientobjekt in Ihrer App erstellt, Folgendes ausführen:

  1. Importieren Sie die DefaultAzureCredential Klasse aus dem azure.identity Modul.
  2. Erstellen eines DefaultAzureCredential-Objekts
  3. Ü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)