Konfigurieren kennwortloser Verbindungen zwischen mehreren Azure-Apps und -Diensten
Artikel
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, einem Service Bus und mehr 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 verfolgen 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 zur Verwendung von systemseitig zugewiesenen verwalteten Identitäten im Vergleich zu benutzerseitig zugewiesenen Identitäten finden Sie in den Empfehlungen zu bewährten Methoden für Identitäten.
Explore DefaultAzureCredential
Verwaltete Identitäten werden im Allgemeinen in Ihrem Anwendungscode über eine Klasse namens DefaultAzureCredential implementiert, die von der Azure.Identity-Clientbibliothek aufgerufen wird. DefaultAzureCredential unterstützt mehrere Authentifizierungsmethoden und bestimmt automatisch, welche Methode zur Laufzeit verwendet werden soll. Weitere Informationen zu diesem Ansatz finden Sie in der Übersicht über „DefaultAzureCredential“.
Verbinden einer von Azure gehosteten App mit mehreren Azure-Diensten
Sie wurden damit beauftragt, eine vorhandene App mit mehreren Azure-Diensten und Datenbanken über kennwortlose Verbindungen zu verbinden. Die Anwendung ist eine auf Azure App Service gehostete ASP.NET Core Web-API. Die nachstehenden Schritte gelten jedoch auch für andere Azure-Hostingumgebungen, z. B. Azure Spring Apps, virtuelle Computer, 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.
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
Navigieren Sie im Azure-Portal zu der gehosteten Anwendung, die Sie mit anderen Diensten verbinden möchten.
Wählen Sie auf der Seite „Dienstübersicht“ die Option Identität aus.
Legen Sie die Einstellung Status auf Ein fest, um eine systemseitig zugewiesene verwaltete Identität für den Dienst zu aktivieren.
Zuweisen von Rollen zu verwalteten Identität für jeden verbundenen Dienst
Navigieren Sie zur Übersichtsseite des Speicherkontos, auf das Ihre Identität Zugriff erhalten soll.
Wählen Sie in der Speicherkontonavigation Zugriffssteuerung (IAM) aus.
Wählen Sie Hinzufügen und dann Rollenzuweisung hinzufügen aus.
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.
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.
Suchen Sie im Flyout nach der verwalteten Identität, die Sie erstellt haben, indem Sie den Namen Ihres App-Diensts eingeben. Wählen Sie die systemseitig zugewiesene Identität aus, und wählen Sie dann Auswählen aus, um das Flyoutmenü zu schließen.
Wählen Sie mehrmals Weiter aus, bis Sie Überprüfen und zuweisen auswählen können, um die Rollenzuweisung abzuschließen.
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.
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.
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 mit mehreren Entwicklern in einem Team zusammenarbeiten. Sie können dann jeden Entwickler, der Zugriff benötigt, in diese Gruppe aufnehmen, um an der lokalen Entwicklung der App teilzunehmen.
Fügen Sie innerhalb Ihres Projekts einen Verweis auf das NuGet-Paket Azure.Identity hinzu. Diese Bibliothek enthält alle erforderlichen Entitäten zur Implementierung von DefaultAzureCredential. 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.KeyVault.Keys hinzugefügt, um eine Verbindung mit Blob Storage und Key Vault herzustellen.
Fügen Sie am Anfang der Program.cs-Datei die folgenden using-Anweisungen hinzu:
using Azure.Identity;
using Azure.Storage.Blobs;
using Azure.Security.KeyVault.Keys;
Erstellen Sie in der Program.cs-Datei des Projektcodes Instanzen der erforderlichen Dienste, mit der Ihre App eine Verbindung herstellt. In den folgenden Beispielen wird mithilfe der entsprechenden SDK-Klassen eine Verbindung mit Blob Storage und Service Bus hergestellt.
var blobServiceClient = new BlobServiceClient(
new Uri("https://<your-storage-account>.blob.core.windows.net"),
new DefaultAzureCredential(credOptions));
var serviceBusClient = new ServiceBusClient("<your-namespace>", new DefaultAzureCredential());
var sender = serviceBusClient.CreateSender("producttracking");
Fügen Sie in Ihrem Projekt die der Datei pom.xml die Abhängigkeit azure-identity hinzu. Diese Bibliothek enthält alle erforderlichen Entitäten zur Implementierung von DefaultAzureCredential. Sie können auch andere Azure-Abhängigkeiten hinzufügen, die für Ihre App relevant sind. In diesem Beispiel werden die Abhängigkeiten azure-storage-blob und azure-messaging-servicebus hinzugefügt, um eine Verbindung mit Blob Storage und Key Vault herzustellen.
Erstellen Sie in Ihrem Projektcode Instanzen der erforderlichen Dienste, mit denen Ihre App eine Verbindung herstellt. In den folgenden Beispielen wird mithilfe der entsprechenden SDK-Klassen eine Verbindung mit Blob Storage und Service Bus hergestellt.
class Demo {
public static void main(String[] args) {
DefaultAzureCredential defaultAzureCredential = new DefaultAzureCredentialBuilder().build();
BlobServiceClient blobServiceClient = new BlobServiceClientBuilder()
.endpoint("https://<your-storage-account>.blob.core.windows.net")
.credential(defaultAzureCredential)
.buildClient();
ServiceBusClientBuilder clientBuilder = new ServiceBusClientBuilder().credential(defaultAzureCredential);
ServiceBusSenderClient serviceBusSenderClient = clientBuilder.sender()
.queueName("producttracking")
.buildClient();
}
}
Innerhalb Ihres Projekts müssen nur Dienstabhängigkeiten hinzugefügt werden, die Sie verwenden. In diesem Beispiel werden die Abhängigkeiten spring-cloud-azure-starter-storage-blob und spring-cloud-azure-starter-servicebus hinzugefügt, um eine Verbindung mit Blob Storage und Key Vault herzustellen.
Erstellen Sie in Ihrem Projektcode Instanzen der erforderlichen Dienste, mit denen Ihre App eine Verbindung herstellt. In den folgenden Beispielen wird mithilfe der entsprechenden SDK-Klassen eine Verbindung mit Blob Storage und Service Bus hergestellt.
@Service
public class ExampleService {
@Autowired
private BlobServiceClient blobServiceClient;
@Autowired
private ServiceBusSenderClient serviceBusSenderClient;
}
Verwenden Sie in Ihrem Projekt npm, um einen Verweis auf das @azure/identity Paket hinzuzufügen. Diese Bibliothek enthält alle erforderlichen Entitäten zur Implementierung von DefaultAzureCredential. Installieren Sie alle anderen Azure SDK-Bibliotheken, die für Ihre App relevant sind.
Fügen Sie oben in der Datei index.js die folgenden import Anweisungen hinzu, um die erforderlichen Clientklassen für die Dienste zu importieren, mit der Ihre App eine Verbindung herstellt:
import { DefaultAzureCredential } from "@azure/identity";
import { BlobServiceClient } from "@azure/storage-blob";
import { KeyClient } from "@azure/keyvault-keys";
Erstellen Sie in der Datei index.js Clientobjekte für die Azure-Dienste, mit der Ihre App eine Verbindung herstellt. In den folgenden Beispielen wird mithilfe der entsprechenden SDK-Klassen eine Verbindung mit Blob Storage und Key Vault hergestellt.
// Azure resource names
const storageAccount = process.env.AZURE_STORAGE_ACCOUNT_NAME;
const keyVaultName = process.env.AZURE_KEYVAULT_NAME;
// Create client for Blob Storage using managed identity
const blobServiceClient = new BlobServiceClient(
`https://${storageAccount}.blob.core.windows.net`,
new DefaultAzureCredential()
);
// Create client for Key Vault using managed identity
const keyClient = new KeyClient(`https://${keyVaultName}.vault.azure.net`, new DefaultAzureCredential());
// Create a new key in Key Vault
const result = await keyClient.createKey(keyVaultName, "RSA");
Wenn dieser Anwendungscode lokal ausgeführt wird, sucht DefaultAzureCredential in einer Anmeldeinformationskette die ersten verfügbaren Anmeldeinformationen. Wenn Managed_Identity_Client_ID lokal „Null“ ist, werden automatisch die Anmeldeinformationen Ihrer lokalen Azure CLI- oder Visual Studio-Anmeldung verwendet. Weitere Informationen zu diesem Prozess finden Sie in der Übersicht über die Azure Identity-Bibliothek.
Wenn die Anwendung in Azure bereitgestellt wird, ruft DefaultAzureCredential automatisch die Variable Managed_Identity_Client_ID aus der App-Dienstumgebung 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 vorigen Beispiel alle 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, aber zwei der Apps auch auf verschiedene Dienste oder Datenbanken zugreifen.
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 Dienste registriert. Stellen Sie sicher, dass Sie bei der Konfiguration von DefaultAzureCredential die richtigen Client-IDs der verwalteten Identität für jeden Dienst abrufen. Im folgenden Codebeispiel werden die folgenden Dienstverbindungen konfiguriert:
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 gemeinsame benutzerseitig zugewiesene verwaltete Identität
// Get the first user-assigned managed identity ID to connect to shared storage
const clientIdStorage = Environment.GetEnvironmentVariable("Managed_Identity_Client_ID_Storage");
// First blob storage client that using a managed identity
BlobServiceClient blobServiceClient = new BlobServiceClient(
new Uri("https://<receipt-storage-account>.blob.core.windows.net"),
new DefaultAzureCredential()
{
ManagedIdentityClientId = clientIDstorage
});
// Second blob storage client that using a managed identity
BlobServiceClient blobServiceClient2 = new BlobServiceClient(
new Uri("https://<contract-storage-account>.blob.core.windows.net"),
new DefaultAzureCredential()
{
ManagedIdentityClientId = clientIDstorage
});
// Get the second user-assigned managed identity ID to connect to shared databases
var clientIDdatabases = Environment.GetEnvironmentVariable("Managed_Identity_Client_ID_Databases");
// Create an Azure Cosmos DB client
CosmosClient client = new CosmosClient(
accountEndpoint: Environment.GetEnvironmentVariable("COSMOS_ENDPOINT", EnvironmentVariableTarget.Process),
new DefaultAzureCredential()
{
ManagedIdentityClientId = clientIDdatabases
});
// Open a connection to Azure SQL using a managed identity
string ConnectionString1 = @"Server=<azure-sql-hostname>.database.windows.net; User Id=ClientIDOfTheManagedIdentity; Authentication=Active Directory Default; Database=<database-name>";
using (SqlConnection conn = new SqlConnection(ConnectionString1))
{
conn.Open();
}
class Demo {
public static void main(String[] args) {
// Get the first user-assigned managed identity ID to connect to shared storage
String clientIdStorage = System.getenv("Managed_Identity_Client_ID_Storage");
// Get the DefaultAzureCredential from clientIdStorage
DefaultAzureCredential storageCredential =
new DefaultAzureCredentialBuilder().managedIdentityClientId(clientIdStorage).build();
// First blob storage client that using a managed identity
BlobServiceClient blobServiceClient = new BlobServiceClientBuilder()
.endpoint("https://<receipt-storage-account>.blob.core.windows.net")
.credential(storageCredential)
.buildClient();
// Second blob storage client that using a managed identity
BlobServiceClient blobServiceClient2 = new BlobServiceClientBuilder()
.endpoint("https://<contract-storage-account>.blob.core.windows.net")
.credential(storageCredential)
.buildClient();
// Get the second user-assigned managed identity ID to connect to shared databases
String clientIdDatabase = System.getenv("Managed_Identity_Client_ID_Databases");
// Create an Azure Cosmos DB client
CosmosClient cosmosClient = new CosmosClientBuilder()
.endpoint("https://<cosmos-db-account>.documents.azure.com:443/")
.credential(new DefaultAzureCredentialBuilder().managedIdentityClientId(clientIdDatabase).build())
.buildClient();
// Open a connection to Azure SQL using a managed identity
String connectionUrl = "jdbc:sqlserver://<azure-sql-hostname>.database.windows.net:1433;"
+ "database=<database-name>;encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database"
+ ".windows.net;loginTimeout=30;Authentication=ActiveDirectoryMSI;";
try {
Connection connection = DriverManager.getConnection(connectionUrl);
Statement statement = connection.createStatement();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
Spring Cloud Azure unterstützt keine Konfiguration mehrerer Clients desselben Diensts. Durch die folgenden Codes werden mehrere Beans für diese Situation erstellt.
@Configuration
public class AzureStorageConfiguration {
@Bean("secondBlobServiceClient")
public BlobServiceClient secondBlobServiceClient(BlobServiceClientBuilder builder) {
return builder.endpoint("https://<receipt-storage-account>.blob.core.windows.net").buildClient();
}
@Bean("firstBlobServiceClient")
public BlobServiceClient firstBlobServiceClient(BlobServiceClientBuilder builder) {
return builder.buildClient();
}
}
Verwenden Sie in Ihrem Projekt npm, um einen Verweis auf das @azure/identity Paket hinzuzufügen. Diese Bibliothek enthält alle erforderlichen Entitäten zur Implementierung von DefaultAzureCredential. Installieren Sie alle anderen Azure SDK-Bibliotheken, die für Ihre App relevant sind.
Fügen Sie oben in der Datei index.js die folgenden import Anweisungen hinzu, um die erforderlichen Clientklassen für die Dienste zu importieren, mit der Ihre App eine Verbindung herstellt:
import { DefaultAzureCredential } from "@azure/identity";
import { BlobServiceClient } from "@azure/storage-blob";
import { KeyClient } from "@azure/keyvault-keys";
Erstellen Sie in der Datei index.js Clientobjekte für die Azure-Dienste, mit der Ihre App eine Verbindung herstellt. Die folgenden Beispiele stellen mithilfe der entsprechenden SDK-Klassen eine Verbindung mit Blob Storage, Cosmos DB und Azure SQL her.
// Get the first user-assigned managed identity ID to connect to shared storage
const clientIdStorage = process.env.MANAGED_IDENTITY_CLIENT_ID_STORAGE;
// Storage account names
const storageAccountName1 = process.env.AZURE_STORAGE_ACCOUNT_NAME_1;
const storageAccountName2 = process.env.AZURE_STORAGE_ACCOUNT_NAME_2;
// First blob storage client that using a managed identity
const blobServiceClient = new BlobServiceClient(
`https://${storageAccountName1}.blob.core.windows.net`,
new DefaultAzureCredential({
managedIdentityClientId: clientIdStorage
})
);
// Second blob storage client that using a managed identity
const blobServiceClient2 = new BlobServiceClient(
`https://${storageAccountName2}.blob.core.windows.net`,
new DefaultAzureCredential({
managedIdentityClientId: clientIdStorage
})
);
// Get the second user-assigned managed identity ID to connect to shared databases
const clientIdDatabases = process.env.MANAGED_IDENTITY_CLIENT_ID_DATABASES;
// Cosmos DB Account endpoint
const cosmosDbAccountEndpoint = process.env.COSMOS_ENDPOINT;
// Create an Azure Cosmos DB client
const client = new CosmosClient({
endpoint: cosmosDbAccountEndpoint,
credential: new DefaultAzureCredential({
managedIdentityClientId: clientIdDatabases
})
});
// Open a connection to Azure SQL using a managed identity with mssql package
// mssql reads the environment variables to get the managed identity
const server = process.env.AZURE_SQL_SERVER;
const database = process.env.AZURE_SQL_DATABASE;
const port = parseInt(process.env.AZURE_SQL_PORT);
const type = process.env.AZURE_SQL_AUTHENTICATIONTYPE;
const config = {
server,
port,
database,
authentication: {
type // <---- Passwordless connection
},
options: {
encrypt: true
}
};
await sql.connect(sqlConfig);
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 gemeinsam freigegebenen Dienste benötigen, aber eine der Apps hat auch eine sehr spezifische Abhängigkeit von einem zusätzlichen Dienst aufweist. Durch die Verwendung einer systemseitig zugewiesenen Identität wird außerdem sichergestellt, dass die mit der jeweiligen App verbundene Identität gelöscht wird, wenn die App gelöscht wird, was dazu beitragen kann, Ihre Umgebung sauber zu halten.
In diesem Tutorial haben Sie gelernt, wie Sie eine Anwendung zu kennwortlosen Verbindungen migrieren. Sie können die folgenden Ressourcen lesen, um die in diesem Artikel erläuterten Konzepte ausführlicher zu erkunden: