Konfigurieren kennwortloser Verbindungen zwischen mehreren Azure-Apps und -Diensten

Anwendungen erfordern häufig sichere Verbindungen zwischen mehreren Azure-Diensten gleichzeitig. Eine Azure App Service-Instanz eines Unternehmens kann beispielsweise eine Verbindung mit mehreren verschiedenen Speicherkonten, einer Azure SQL-Datenbankinstanz, einer Service Bus-Instanz und weiteren Diensten herstellen.

Verwaltete Identitäten sind die empfohlene Authentifizierungsoption für sichere, kennwortlose Verbindungen zwischen Azure-Ressourcen. Entwickler müssen nicht manuell viele verschiedene Geheimnisse für verwaltete Identitäten nachverfolgen und verwalten, da die meisten dieser Aufgaben intern von Azure erledigt werden. In diesem Tutorial erfahren Sie, wie Sie Verbindungen zwischen mehreren Diensten mithilfe von verwalteten Identitäten und der Azure Identity-Clientbibliothek verwalten können.

Vergleichen der Typen verwalteter Identitäten

Azure stellt die folgenden Typen von verwalteten Identitäten bereit:

  • Systemseitig zugewiesene verwaltete Identitäten werden direkt mit einer einzelnen Azure-Ressource verknüpft. Wenn Sie eine systemseitig zugewiesene verwaltete Identität für einen Dienst aktivieren, erstellt Azure eine verknüpfte Identität und verarbeitet administrative Aufgaben für diese Identität intern. Wenn die Azure-Ressource gelöscht wird, wird auch die Identität gelöscht.
  • Benutzerseitig zugewiesene verwaltete Identitäten sind unabhängige Identitäten, die von einem Administrator erstellt werden und einer oder mehreren Azure-Ressourcen zugeordnet werden können. Der Lebenszyklus der Identität ist unabhängig von diesen Ressourcen.

Weitere Informationen zu bewährten Methoden und dazu, wann systemseitig zugewiesene und wann benutzerseitig zugewiesene verwaltete Identitäten verwendet werden sollten, finden Sie in den Empfehlungen zu bewährten Methoden für verwaltete Identitäten.

Explore DefaultAzureCredential

Verwaltete Identitäten lassen sich am einfachsten über eine Klasse namens DefaultAzureCredential aus der Azure Identity-Clientbibliothek in Ihrem Anwendungscode implementieren. DefaultAzureCredential unterstützt mehrere Authentifizierungsmechanismen und bestimmt automatisch, welcher Mechanismus zur Laufzeit verwendet werden soll. Erfahren Sie mehr über DefaultAzureCredential für die folgenden Ökosysteme:

Verbinden einer von Azure gehosteten App mit mehreren Azure-Diensten

Angenommen, Sie wurden damit beauftragt, eine vorhandene App über kennwortlose Verbindungen mit mehreren Azure-Diensten und Datenbanken zu verbinden. Die Anwendung ist eine in Azure App Service gehostete ASP.NET Core-Web-API. Die unten stehenden Schritte gelten jedoch auch für andere Azure-Hostingumgebungen, z. B. Azure Spring Apps, Azure Virtual Machines, Azure Container Apps und AKS.

Dieses Tutorial gilt für die folgenden Architekturen, kann jedoch durch minimale Konfigurationsänderungen auch an viele andere Szenarien angepasst werden.

Darstellung der Beziehungen zwischen benutzerseitig zugewiesenen Identitäten

Die folgenden Schritte veranschaulichen, wie Sie eine App so konfigurieren, dass eine systemseitig zugewiesene verwaltete Identität und Ihr lokales Entwicklungskonto verwendet werden, um eine Verbindung mit mehreren Azure-Diensten herzustellen.

Erstellen einer systemseitig zugewiesenen verwalteten Identität

  1. Navigieren Sie im Azure-Portal zu der gehosteten Anwendung, die Sie mit anderen Diensten verbinden möchten.

  2. Wählen Sie auf der Seite „Dienstübersicht“ die Option Identität aus.

  3. Legen Sie die Einstellung Status auf Ein fest, um eine systemseitig zugewiesene verwaltete Identität für den Dienst zu aktivieren.

    Screenshot: Zuweisen einer systemseitig zugewiesenen verwalteten Identität

Zuweisen von Rollen zu verwalteten Identität für jeden verbundenen Dienst

  1. Navigieren Sie zur Übersichtsseite des Speicherkontos, auf das Ihre Identität Zugriff erhalten soll.

  2. Wählen Sie in der Speicherkontonavigation Zugriffssteuerung (IAM) aus.

  3. Wählen Sie Hinzufügen und dann Rollenzuweisung hinzufügen aus.

    Screenshot: Navigieren zum Abschnitt für die Zuweisung einer Rolle zu einer systemseitig zugewiesenen verwalteten Identität im Azure-Portal

  4. Suchen Sie im Suchfeld Rolle nach Speicherblobdaten-Mitwirkender, der Berechtigungen zum Ausführen von Lese- und Schreibvorgängen für Blobdaten gewährt. Sie können eine beliebige Rolle zuweisen, die für Ihren Anwendungsfall geeignet ist. Wählen Sie Speicherblobdaten-Mitwirkender aus der Liste und dann Weiter aus.

  5. Wählen Sie auf dem Bildschirm Rollenzuweisung hinzufügen für die Option Zugriff zuweisen zu die Option Verwaltete Identität aus. Wählen Sie dann + Mitglieder auswählen aus.

  6. Suchen Sie im Flyout nach der verwalteten Identität, die Sie erstellt haben, indem Sie den Namen Ihrer App Service-Instanz eingeben. Wählen Sie die systemseitig zugewiesene Identität und dann Auswählen aus, um das Flyoutmenü zu schließen.

    Screenshot: Zuweisen einer Rolle zu einer systemseitig zugewiesenen verwalteten Identität im Azure-Portal

  7. Wählen Sie mehrmals Weiter aus, bis Sie Überprüfen und zuweisen auswählen können, um die Rollenzuweisung abzuschließen.

  8. Wiederholen Sie diesen Vorgang für die anderen Dienste, mit denen Sie eine Verbindung herstellen möchten.

Überlegungen zur lokalen Entwicklung

Sie können auch den Zugriff auf Azure-Ressourcen für die lokale Entwicklung aktivieren, indem Sie einem Benutzerkonto auf die gleiche Weise Rollen zuweisen, wie Sie Ihrer verwalteten Identität Rollen zugewiesen haben.

  1. Nachdem Sie die Rolle Speicherblobdaten-Mitwirkender ihrer verwalteten Identität zugewiesen haben, wählen Sie unter Zugriff zuweisen zu dieses Mal Benutzer, Gruppe oder Dienstprinzipal aus. Wählen Sie + Mitglieder auswählen aus, um das Flyoutmenü erneut zu öffnen.

  2. Suchen Sie nach dem Konto user@domain oder der Microsoft Entra-Sicherheitsgruppe, dem bzw. der Sie per E-Mail-Adresse oder Namen Zugriff erteilen möchten, und wählen Sie das Konto bzw. die Sicherheitsgruppe aus. Dabei sollte es sich um dasselbe Konto handeln, mit dem Sie sich bei Ihrem lokalen Entwicklungstool anmelden, z. B. Visual Studio oder die Azure CLI.

Hinweis

Sie können diese Rollen auch einer Microsoft Entra-Sicherheitsgruppe zuweisen, wenn Sie in einem Team mit mehreren Entwicklern arbeiten. Sie können dann jeden Entwickler, der Zugriff benötigt, in diese Gruppe aufnehmen, um an der lokalen Entwicklung der App teilzunehmen.

Implementieren des Anwendungscodes

  1. Installieren Sie in Ihrem Projekt das Paket Azure.Identity. Diese Bibliothek stellt DefaultAzureCredential bereit. Sie können auch alle anderen Azure-Bibliotheken hinzufügen, die für Ihre App relevant sind. In diesem Beispiel werden die Pakete Azure.Storage.Blobs und Azure.Messaging.ServiceBus hinzugefügt, um eine Verbindung mit Blob Storage bzw. Service Bus herzustellen.

    dotnet add package Azure.Identity
    dotnet add package Azure.Messaging.ServiceBus
    dotnet add package Azure.Storage.Blobs
    
  2. Instanziieren Sie Dienstclients für die Azure-Dienste, mit denen Ihre App eine Verbindung herstellen muss. Das folgende Codebeispiel interagiert mithilfe der entsprechenden Dienstclients mit Blob Storage und Service Bus.

    using Azure.Identity;
    using Azure.Messaging.ServiceBus;
    using Azure.Storage.Blobs;
    
    // Create DefaultAzureCredential instance that uses system-assigned managed identity
    // in the underlying ManagedIdentityCredential.
    DefaultAzureCredential credential = new();
    
    BlobServiceClient blobServiceClient = new(
        new Uri("https://<your-storage-account>.blob.core.windows.net"),
        credential);
    
    ServiceBusClient serviceBusClient = new("<your-namespace>", credential);
    ServiceBusSender sender = serviceBusClient.CreateSender("producttracking");
    

Wenn dieser Code lokal ausgeführt wird, sucht DefaultAzureCredential in seiner Anmeldeinformationskette nach den ersten verfügbaren Anmeldeinformationen. Wenn die Umgebungsvariable Managed_Identity_Client_ID lokal NULL ist, werden Anmeldeinformationen verwendet, die einem lokal installierten Entwicklertool entsprechen. Dabei kann es sich z. B. um die Azure-Befehlszeilenschnittstelle (Command Line Interface, CLI) oder Visual Studio handeln. Weitere Informationen zu diesem Prozess finden Sie im Abschnitt Erkunden von DefaultAzureCredential.

Wenn die Anwendung in Azure bereitgestellt wird, ruft DefaultAzureCredential automatisch die Variable Managed_Identity_Client_ID aus der App Service-Umgebung ab. Dieser Wert wird verfügbar, wenn eine verwaltete Identität Ihrer App zugeordnet wird.

Dieser Gesamtprozess stellt sicher, dass Ihre App lokal und in Azure sicher ausgeführt werden kann, ohne dass Codeänderungen erforderlich sind.

Verbinden mehrerer Apps mit mehreren verwalteten Identitäten

Obwohl die Apps im vorherigen Beispiel die gleichen Anforderungen an den Dienstzugriff haben, sind reale Umgebungen oft vielschichtiger. Betrachten Sie ein Szenario, in dem mehrere Apps eine Verbindung mit den gleichen Speicherkonten herstellen, zwei der Apps aber auch auf unterschiedliche Dienste oder Datenbanken zugreifen.

Darstellung mehrerer benutzerseitig zugewiesenen verwalteten Identitäten

Um dieses Setup in Ihrem Code zu konfigurieren, müssen Sie sicherstellen, dass Ihre Anwendung für jede Verbindung mit einem Speicherkonto oder einer Datenbank separate Dienstclients registriert. Verweisen Sie beim Konfigurieren von DefaultAzureCredential für jeden Dienst auf die richtigen Client-IDs der verwalteten Identität. Die folgenden Codebeispiele konfigurieren diese Azure-Dienstverbindungen:

  • Zwei Verbindungen mit separaten Speicherkonten über eine gemeinsame benutzerseitig zugewiesene verwaltete Identität
  • Eine Verbindung mit Azure Cosmos DB- und Azure SQL-Diensten über eine zweite benutzerseitig zugewiesene verwaltete Identität. Diese verwaltete Identität wird freigegeben, wenn der Azure SQL-Clienttreiber dies zulässt. Weitere Informationen finden Sie in den Codekommentaren.
  1. Installieren Sie in Ihrem Projekt die erforderlichen Pakete. Die Azure Identity-Bibliothek stellt DefaultAzureCredential bereit.

    dotnet add package Azure.Identity
    dotnet add package Azure.Storage.Blobs
    dotnet add package Microsoft.Azure.Cosmos
    dotnet add package Microsoft.Data.SqlClient
    
  2. Fügen Sie Ihrem Code Folgendes hinzu:

    using Azure.Core;
    using Azure.Identity;
    using Azure.Storage.Blobs;
    using Microsoft.Azure.Cosmos;
    using Microsoft.Data.SqlClient;
    
    string clientIdStorage =
        Environment.GetEnvironmentVariable("Managed_Identity_Client_ID_Storage")!;
    
    // Create a DefaultAzureCredential instance that configures the underlying
    // ManagedIdentityCredential to use a user-assigned managed identity.
    DefaultAzureCredential credentialStorage = new(
        new DefaultAzureCredentialOptions
        {
            ManagedIdentityClientId = clientIdStorage,
        });
    
    // First Blob Storage client
    BlobServiceClient blobServiceClient1 = new(
        new Uri("https://<receipt-storage-account>.blob.core.windows.net"),
        credentialStorage);
    
    // Second Blob Storage client
    BlobServiceClient blobServiceClient2 = new(
        new Uri("https://<contract-storage-account>.blob.core.windows.net"),
        credentialStorage);
    
    string clientIdDatabases =
        Environment.GetEnvironmentVariable("Managed_Identity_Client_ID_Databases")!;
    
    // Create a DefaultAzureCredential instance that configures the underlying
    // ManagedIdentityCredential to use a user-assigned managed identity.
    DefaultAzureCredential credentialDatabases = new(
        new DefaultAzureCredentialOptions
        {
            ManagedIdentityClientId = clientIdDatabases,
        });
    
    // Create an Azure Cosmos DB client
    CosmosClient cosmosClient = new(
        Environment.GetEnvironmentVariable("COSMOS_ENDPOINT", EnvironmentVariableTarget.Process),
        credentialDatabases);
    
    // Open a connection to Azure SQL
    string connectionString =
        $"Server=<azure-sql-hostname>.database.windows.net;User Id={clientIdDatabases};Authentication=Active Directory Default;Database=<database-name>";
    
    using (SqlConnection connection = new(connectionString)
    {
        AccessTokenCallback = async (authParams, cancellationToken) =>
        {
            const string defaultScopeSuffix = "/.default";
            string scope = authParams.Resource.EndsWith(defaultScopeSuffix)
                ? authParams.Resource
                : $"{authParams.Resource}{defaultScopeSuffix}";
            AccessToken token = await credentialDatabases.GetTokenAsync(
                new TokenRequestContext([scope]),
                cancellationToken);
    
            return new SqlAuthenticationToken(token.Token, token.ExpiresOn);
        }
    })
    {
        connection.Open();
    }
    

Sie können einer Ressource auch gleichzeitig eine benutzerseitig zugewiesene verwaltete Identität und eine systemseitig zugewiesene verwaltete Identität zuordnen. Dies kann in Szenarien nützlich sein, in denen alle Apps Zugriff auf dieselben freigegebenen Dienste benötigen, eine der Apps jedoch auch eine spezifische Abhängigkeit von einem zusätzlichen Dienst aufweist. Durch die Verwendung einer systemseitig zugewiesenen verwalteten Identität wird außerdem sichergestellt, dass die an die jeweilige App gebundene Identität beim Löschen der App gelöscht wird, was die Bereinigung Ihrer Umgebung erleichtern kann.

Darstellung benutzerseitig und systemseitig zugewiesener verwalteter Identitäten

In den Empfehlungen zu bewährten Methoden für verwaltete Identitäten werden solche Szenarien ausführlicher erläutert.

Nächste Schritte

In diesem Tutorial haben Sie gelernt, wie Sie eine Anwendung zu kennwortlosen Verbindungen migrieren. Lesen Sie die folgenden Artikel, um mehr über die Konzepte zu erfahren, die in diesem Artikel vorgestellt wurden: