Authentifizieren von Go-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 dennoch bei allen von der App verwendeten Azure-Diensten authentifizieren. In diesem Artikel wird beschrieben, wie Sie dedizierte Anwendungsdienstprinzipalobjekte einrichten, die während der lokalen Entwicklung verwendet werden sollen.
Dedizierte Anwendungsdienstprinzipien für die lokale Entwicklung ermöglichen es Ihnen, das Prinzip der minimalen Rechte während der App-Entwicklung zu befolgen. Da Berechtigungen auf genau das ausgelegt sind, was für die App während der Entwicklung erforderlich ist, 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 wurde.
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 auf das Notwendige beschränkt.
Während der lokalen Entwicklung werden Umgebungsvariablen mit der Identität des Anwendungsdienstprinzipals festgelegt. Das Azure SDK für Go liest diese Umgebungsvariablen und verwendet diese Informationen, um die App bei den benötigten Azure-Ressourcen zu authentifizieren.
1 – Registrieren der Anwendung in Azure
Anwendungsdienstprinzipalobjekte werden mit einer App-Registrierung in Azure erstellt. Dies kann entweder über das Azure-Portal oder die Azure CLI erfolgen.
Azure CLI-Befehle können in der Azure Cloud Shell oder auf einer Arbeitsstation ausgeführt werden, auf der die Azure CLIinstalliert ist.
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 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 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:
- Jeder Entwickler kann sicher sein, dass ihm die gleichen Rollen zugewiesen werden, da die Rollen auf Gruppenebene zugewiesen sind.
- 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 Anwendungshauptdienst für den Entwickler erstellt und der Gruppe hinzugefügt, um sicherzustellen, 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 Parameter --display-name
und --main-nickname
sind erforderlich. Der Name der Gruppe sollte auf dem Namen der Anwendung basieren. Es ist auch hilfreich, einen Ausdruck wie "local-dev" in den Namen der Gruppe einzuschließen, 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.
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 Parameterbefehl --filter
akzeptiert OData-Stilfilter und kann verwendet werden, um die Liste wie dargestellt zu filtern. Der --query
-Parameter beschränkt die Spalten auf die, die von Interesse sind.
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>
Anmerkung
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 – Rollen der Anwendung zuweisen
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 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 in Azure mit dem Befehl az role assignment create eine Rolle 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>"
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-go-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-go-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 Gruppe von Umgebungsvariablen. Da die meisten Entwickler*innen an mehreren Anwendungen arbeiten, wird empfohlen, ein Paket wie godotenv 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 eingegrenzt, um die Anwendung bei Azure zu authentifizieren, sodass sie nur von dieser Anwendung genutzt werden dürfen.
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 Go schließt die .env
-Datei automatisch vom Einchecken aus.
Um das Godotenv-Paket zu verwenden, installieren Sie zuerst das Paket in Ihrer Anwendung.
go get github.com/joho/godotenv
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
→ Die für die App generierten 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 godotenv
Bibliothek, um die Umgebungsvariablen aus der .env
Datei beim Start zu lesen.
// Imports of fmt, log, and os omitted for brevity
import "github.com/joho/godotenv"
environment := os.Getenv("ENVIRONMENT")
if environment == "development" {
fmt.Println("Loading environment variables from .env file")
// Load the .env file
err := godotenv.Load(".env")
if err != nil {
log.Fatalf("Error loading .env file: %v", err)
}
}
5 – Implementieren von DefaultAzureCredential in Ihrer Anwendung
Um Azure SDK-Clientobjekte für Azure zu authentifizieren, sollte Ihre Anwendung die DefaultAzureCredential
Klasse aus dem azidentity
-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 zuerst das azidentity
-Paket zu Ihrer Anwendung hinzu.
go get github.com/Azure/azure-sdk-for-go/sdk/azidentity
Als Nächstes sollten Sie für jeden Go-Code, der ein Azure SDK-Clientobjekt in Ihrer App erstellt, Folgendes ausführen:
- Importieren Sie das
azidentity
-Paket. - Erstellen Sie eine Instanz vom Typ
DefaultAzureCredential
. - Leiten Sie die Instanz vom Typ
DefaultAzureCredential
an den Azure SDK-Clientkonstruktor weiter.
Ein Beispiel hierfür ist im folgenden Codesegment dargestellt.
import (
"context"
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
)
const (
account = "https://<replace_with_your_storage_account_name>.blob.core.windows.net/"
containerName = "sample-container"
blobName = "sample-blob"
sampleFile = "path/to/sample/file"
)
func main() {
// create a credential
cred, err := azidentity.NewDefaultAzureCredential(nil)
if err != nil {
// TODO: handle error
}
// create a client for the specified storage account
client, err := azblob.NewClient(account, cred, nil)
if err != nil {
// TODO: handle error
}
// TODO: perform some action with the azblob Client
// _, err = client.DownloadFile(context.TODO(), <containerName>, <blobName>, <target_file>, <DownloadFileOptions>)
}