Konfigurowanie połączeń bez hasła między wieloma aplikacjami i usługami platformy Azure
Artykuł
Aplikacje często wymagają bezpiecznych połączeń między wieloma usługami platformy Azure jednocześnie. Na przykład wystąpienie usługi aplikacja systemu Azure przedsiębiorstwa może łączyć się z kilkoma różnymi kontami magazynu, wystąpieniem bazy danych Azure SQL Database, usługą Service Bus i nie tylko.
Tożsamości zarządzane to zalecana opcja uwierzytelniania dla bezpiecznych połączeń bez hasła między zasobami platformy Azure. Deweloperzy nie muszą ręcznie śledzić wielu różnych wpisów tajnych dla tożsamości zarządzanych i zarządzać nimi, ponieważ większość tych zadań jest obsługiwana wewnętrznie przez platformę Azure. W tym samouczku przedstawiono sposób zarządzania połączeniami między wieloma usługami przy użyciu tożsamości zarządzanych i biblioteki klienta tożsamości platformy Azure.
Porównanie typów tożsamości zarządzanych
Platforma Azure udostępnia następujące typy tożsamości zarządzanych:
Tożsamości zarządzane przypisane przez system są bezpośrednio powiązane z pojedynczym zasobem platformy Azure. Po włączeniu tożsamości zarządzanej przypisanej przez system w usłudze platforma Azure utworzy połączoną tożsamość i będzie obsługiwać zadania administracyjne dla tej tożsamości wewnętrznie. Po usunięciu zasobu platformy Azure tożsamość zostanie również usunięta.
Tożsamości zarządzane przypisane przez użytkownika to niezależne tożsamości utworzone przez administratora i mogą być skojarzone z co najmniej jednym zasobem platformy Azure. Cykl życia tożsamości jest niezależny od tych zasobów.
Tożsamości zarządzane są najczęściej implementowane w kodzie aplikacji za pośrednictwem klasy wywoływanej DefaultAzureCredential z biblioteki klienta tożsamości platformy Azure.
DefaultAzureCredential obsługuje wiele mechanizmów uwierzytelniania i automatycznie określa, które powinny być używane w czasie wykonywania. Dowiedz się więcej o DefaultAzureCredential następujących ekosystemach:
Łączenie aplikacji hostowanej na platformie Azure z wieloma usługami platformy Azure
Załóżmy, że twoim zadaniem jest połączenie istniejącej aplikacji z wieloma usługami i bazami danych platformy Azure przy użyciu połączeń bez hasła. Aplikacja jest ASP.NET Core internetowy interfejs API hostowany w usłudze aplikacja systemu Azure Service, ale poniższe kroki dotyczą również innych środowisk hostingu platformy Azure, takich jak Azure Spring Apps, Virtual Machines, Container Apps i AKS.
Ten samouczek dotyczy następujących architektur, choć można go dostosować do wielu innych scenariuszy, a także poprzez minimalne zmiany konfiguracji.
W poniższych krokach pokazano, jak skonfigurować aplikację do używania tożsamości zarządzanej przypisanej przez system i lokalnego konta programistycznego w celu nawiązania połączenia z wieloma usługami platformy Azure.
Tworzenie tożsamości zarządzanej przypisanej przez system
W witrynie Azure Portal przejdź do hostowanej aplikacji, którą chcesz połączyć z innymi usługami.
Na stronie przeglądu usługi wybierz pozycję Tożsamość.
Przełącz ustawienie Stan na Włączone , aby włączyć tożsamość zarządzaną przypisaną przez system dla usługi.
Przypisywanie ról do tożsamości zarządzanej dla każdej połączonej usługi
Przejdź do strony przeglądu konta magazynu, do którego chcesz udzielić dostępu do tożsamości.
Wybierz pozycję Kontrola dostępu (Zarządzanie dostępem i tożsamościami) w obszarze nawigacji konta magazynu.
Wybierz pozycję + Dodaj , a następnie dodaj przypisanie roli.
W polu wyszukiwania Rola wyszukaj pozycję Współautor danych obiektu blob usługi Storage, który przyznaje uprawnienia do wykonywania operacji odczytu i zapisu na danych obiektów blob. Możesz przypisać dowolną rolę odpowiednią dla danego przypadku użycia. Wybierz współautora danych obiektu blob usługi Storage z listy, a następnie wybierz pozycję Dalej.
Na ekranie Dodawanie przypisania roli dla opcji Przypisz dostęp do wybierz pozycję Tożsamość zarządzana. Następnie wybierz pozycję +Wybierz członków.
W oknie wysuwaym wyszukaj utworzoną tożsamość zarządzaną, wprowadzając nazwę usługi App Service. Wybierz tożsamość przypisaną przez system, a następnie wybierz pozycję Wybierz , aby zamknąć menu wysuwane.
Wybierz pozycję Dalej kilka razy, dopóki nie będzie można wybrać pozycji Przejrzyj i przypisz , aby zakończyć przypisanie roli.
Powtórz ten proces dla innych usług, z którymi chcesz nawiązać połączenie.
Zagadnienia dotyczące programowania lokalnego
Możesz również włączyć dostęp do zasobów platformy Azure na potrzeby programowania lokalnego, przypisując role do konta użytkownika w taki sam sposób, jak przypisano role do tożsamości zarządzanej.
Po przypisaniu roli Współautor danych obiektu blob usługi Storage do tożsamości zarządzanej w obszarze Przypisz dostęp tym razem wybierz pozycję Użytkownik, grupa lub jednostka usługi. Wybierz pozycję + Wybierz członków , aby ponownie otworzyć menu wysuwane.
Wyszukaj konto user@domain lub grupę zabezpieczeń Microsoft Entra, do której chcesz udzielić dostępu za pomocą adresu e-mail lub nazwy, a następnie wybierz je. Powinno to być to samo konto, za pomocą którego logujesz się do lokalnego narzędzia programistycznego, na przykład programu Visual Studio lub interfejsu wiersza polecenia platformy Azure.
Uwaga
Możesz również przypisać te role do grupy zabezpieczeń Firmy Microsoft Entra, jeśli pracujesz nad zespołem z wieloma deweloperami. Następnie możesz umieścić dowolnego dewelopera w tej grupie, który potrzebuje dostępu do tworzenia aplikacji lokalnie.
W projekcie zainstaluj Azure.Identity pakiet. Ta biblioteka udostępnia program DefaultAzureCredential. Możesz również dodać inne biblioteki platformy Azure, które są istotne dla aplikacji. W tym przykładzie Azure.Storage.Blobs pakiety i Azure.Messaging.ServiceBus są dodawane do łączenia się odpowiednio z usługami Blob Storage i Service Bus.
Utwórz wystąpienie klientów usługi dla usług platformy Azure, z którymi aplikacja musi się połączyć. Poniższy przykładowy kod współdziała z usługą Blob Storage i usługą Service Bus przy użyciu odpowiednich klientów usługi.
C#
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");
W projekcie dodaj azure-identity zależność do pliku pom.xml . Ta biblioteka udostępnia program DefaultAzureCredential. Możesz również dodać inne zależności platformy Azure, które są istotne dla aplikacji. W tym przykładzie azure-storage-blob zależności i azure-messaging-servicebus są dodawane do interakcji z usługami Blob Storage i Service Bus.
Utwórz wystąpienie klientów usługi dla usług platformy Azure, z którymi aplikacja musi się połączyć. Poniższy przykładowy kod współdziała z usługą Blob Storage i usługą Service Bus przy użyciu odpowiednich klientów usługi.
Java
classDemo{
publicstaticvoidmain(String[] args){
// Create DefaultAzureCredential instance that uses system-assigned managed identity// in the underlying ManagedIdentityCredential.
DefaultAzureCredential credential = new DefaultAzureCredentialBuilder()
.build();
BlobServiceClient blobServiceClient = new BlobServiceClientBuilder()
.endpoint("https://<your-storage-account>.blob.core.windows.net")
.credential(credential)
.buildClient();
ServiceBusClientBuilder clientBuilder = new ServiceBusClientBuilder()
.credential(credential);
ServiceBusSenderClient serviceBusSenderClient = clientBuilder.sender()
.queueName("producttracking")
.buildClient();
}
}
W projekcie wystarczy dodać tylko używane zależności usług. W tym przykładzie spring-cloud-azure-starter-storage-blob dodano zależności i spring-cloud-azure-starter-servicebus w celu nawiązania połączenia z usługą Blob Storage i Service Bus.
Utwórz wystąpienie klientów usługi dla usług platformy Azure, z którymi aplikacja musi się połączyć. W poniższych przykładach nawiąż połączenie z usługą Blob Storage i usługą Service Bus przy użyciu odpowiednich klientów usługi.
W projekcie zainstaluj @azure/identity pakiet. Ta biblioteka udostępnia program DefaultAzureCredential. W tym przykładzie pakiety @azure/storage-blob i @azure/service-bus są instalowane w celu interakcji z usługami Blob Storage i Service Bus.
Utwórz wystąpienie klientów usługi dla usług platformy Azure, z którymi aplikacja musi się połączyć. Poniższy przykładowy kod współdziała z usługą Blob Storage i usługą Service Bus przy użyciu odpowiednich klientów usługi.
JavaScript
import { DefaultAzureCredential } from"@azure/identity";
import { BlobServiceClient } from"@azure/storage-blob";
import { ServiceBusClient } from"@azure/service-bus";
// Azure resource namesconst storageAccount = process.env.AZURE_STORAGE_ACCOUNT_NAME;
const serviceBusNamespace = process.env.AZURE_SERVICE_BUS_NAMESPACE;
// Create DefaultAzureCredential instance that uses system-assigned managed identity// in the underlying ManagedIdentityCredential.const credential = new DefaultAzureCredential();
// Create client for Blob Storageconst blobServiceClient = new BlobServiceClient(
`https://${storageAccount}.blob.core.windows.net`,
credential
);
// Create client for Service Busconst serviceBusClient = new ServiceBusClient(
`https://${serviceBusNamespace}.servicebus.windows.net`,
credential
);
W projekcie dodaj odwołanie do azure-identity pakietu. Ta biblioteka udostępnia program DefaultAzureCredential. Możesz również dodać inne biblioteki platformy Azure, które są istotne dla aplikacji. W tym przykładzie azure-storage-blob pakiety i azure-service-bus są dodawane do łączenia się odpowiednio z usługami Blob Storage i Service Bus.
Utwórz wystąpienie klientów usługi dla usług platformy Azure, z którymi aplikacja musi się połączyć. Poniższy przykładowy kod współdziała z usługą Blob Storage i usługą Service Bus przy użyciu odpowiednich klientów usługi.
Python
from azure.identity import DefaultAzureCredential
from azure.servicebus import ServiceBusClient, ServiceBusMessage
from azure.storage.blob import BlobServiceClient
import os
# Create DefaultAzureCredential instance that uses system-assigned managed identity# in the underlying ManagedIdentityCredential.
credential = DefaultAzureCredential()
blob_service_client = BlobServiceClient(
account_url="https://<my-storage-account-name>.blob.core.windows.net/",
credential=credential
)
fully_qualified_namespace = os.environ['SERVICEBUS_FULLY_QUALIFIED_NAMESPACE']
queue_name = os.environ['SERVICE_BUS_QUEUE_NAME']
with ServiceBusClient(fully_qualified_namespace, credential) as service_bus_client:
with service_bus_client.get_queue_sender(queue_name) as sender:
# Sending a single message
single_message = ServiceBusMessage("Single message")
sender.send_messages(single_message)
Gdy ten kod zostanie uruchomiony lokalnie, DefaultAzureCredential przeszukuje jego łańcuch poświadczeń pod kątem pierwszych dostępnych poświadczeń. Jeśli zmienna Managed_Identity_Client_ID środowiskowa ma wartość null lokalnie, zostanie użyte poświadczenie odpowiadające lokalnie zainstalowanemu narzędziu deweloperskiemu. Na przykład interfejs wiersza polecenia platformy Azure lub program Visual Studio. Aby dowiedzieć się więcej na temat tego procesu, zobacz sekcję Eksplorowanie domyślneAzureCredential.
Po wdrożeniu aplikacji na platformie Azure DefaultAzureCredential automatycznie pobiera zmienną Managed_Identity_Client_ID ze środowiska usługi App Service. Ta wartość staje się dostępna, gdy tożsamość zarządzana jest skojarzona z aplikacją.
Ten ogólny proces gwarantuje, że aplikacja będzie mogła działać bezpiecznie lokalnie i na platformie Azure bez konieczności wprowadzania zmian w kodzie.
Łączenie wielu aplikacji przy użyciu wielu tożsamości zarządzanych
Mimo że aplikacje w poprzednim przykładzie współużytkują te same wymagania dotyczące dostępu do usług, środowiska rzeczywiste są często bardziej zniuansowane. Rozważmy scenariusz, w którym wiele aplikacji łączy się z tymi samymi kontami magazynu, ale dwie aplikacje uzyskują również dostęp do różnych usług lub baz danych.
Aby skonfigurować tę konfigurację w kodzie, upewnij się, że aplikacja rejestruje oddzielnych klientów usługi w celu nawiązania połączenia z każdym kontem magazynu lub bazą danych. W przypadku DefaultAzureCredentialkonfigurowania programu należy odwołać się do prawidłowych identyfikatorów klienta tożsamości zarządzanej dla każdej usługi. Następujące przykłady kodu umożliwiają skonfigurowanie tych połączeń usługi platformy Azure:
Dwa połączenia z oddzielnymi kontami magazynu przy użyciu tożsamości zarządzanej przypisanej przez użytkownika
Połączenie z usługami Azure Cosmos DB i Azure SQL przy użyciu drugiej tożsamości zarządzanej przypisanej przez użytkownika. Ta tożsamość zarządzana jest udostępniana, gdy sterownik klienta usługi Azure SQL go umożliwia. Aby uzyskać więcej informacji, zobacz komentarze kodu.
classDemo{
publicstaticvoidmain(String[] args){
String clientIdStorage = System.getenv("Managed_Identity_Client_ID_Storage");
// Create a DefaultAzureCredential instance that configures the underlying// ManagedIdentityCredential to use a user-assigned managed identity.
DefaultAzureCredential credentialStorage = new DefaultAzureCredentialBuilder()
.managedIdentityClientId(clientIdStorage)
.build();
// First Blob Storage client
BlobServiceClient blobServiceClient1 = new BlobServiceClientBuilder()
.endpoint("https://<receipt-storage-account>.blob.core.windows.net")
.credential(credentialStorage)
.buildClient();
// Second Blob Storage client
BlobServiceClient blobServiceClient2 = new BlobServiceClientBuilder()
.endpoint("https://<contract-storage-account>.blob.core.windows.net")
.credential(credentialStorage)
.buildClient();
String clientIdDatabases = System.getenv("Managed_Identity_Client_ID_Databases");
// Create a DefaultAzureCredential instance that configures the underlying// ManagedIdentityCredential to use a user-assigned managed identity.
DefaultAzureCredential credentialDatabases = new DefaultAzureCredentialBuilder()
.managedIdentityClientId(clientIdDatabases)
.build()
// Create an Azure Cosmos DB client
CosmosClient cosmosClient = new CosmosClientBuilder()
.endpoint("https://<cosmos-db-account>.documents.azure.com:443/")
.credential(credentialDatabases)
.buildClient();
// Open a connection to Azure SQL using a managed identity.// The DefaultAzureCredential instance stored in the credentialDatabases variable can't be // used here, so sharing isn't possible between Cosmos DB and Azure SQL.
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();
}
}
}
from azure.cosmos import CosmosClient
from azure.identity import DefaultAzureCredential
from azure.storage.blob import BlobServiceClient
import os, pyodbc, struct
# Create a DefaultAzureCredential instance that configures the underlying# ManagedIdentityCredential to use a user-assigned managed identity.
credential_storage = DefaultAzureCredential(
managed_identity_client_id=os.environ['Managed_Identity_Client_ID_Storage']
)
# First Blob Storage client
blob_service_client_1 = BlobServiceClient(
account_url="https://<receipt-storage-account>.blob.core.windows.net/",
credential=credential_storage
)
# Second Blob Storage client
blob_service_client_2 = BlobServiceClient(
account_url="https://<contract-storage-account>.blob.core.windows.net/",
credential=credential_storage
)
# Create a DefaultAzureCredential instance that configures the underlying# ManagedIdentityCredential to use a user-assigned managed identity.
credential_databases = DefaultAzureCredential(
managed_identity_client_id=os.environ['Managed_Identity_Client_ID_Databases']
)
# Create an Azure Cosmos DB client
cosmos_client = CosmosClient(
os.environ['COSMOS_ENDPOINT'],
credential=credential_databases
)
# Connect to Azure SQL
token_bytes = credential_databases.get_token("https://database.windows.net/.default").token.encode("UTF-16-LE")
token_struct = struct.pack(f'<I{len(token_bytes)}s', len(token_bytes), token_bytes)
SQL_COPT_SS_ACCESS_TOKEN = 1256# This connection option is defined by microsoft in msodbcsql.h
conn = pyodbc.connect(connection_string, attrs_before={SQL_COPT_SS_ACCESS_TOKEN: token_struct})
Można również skojarzyć tożsamość zarządzaną przypisaną przez użytkownika i tożsamość zarządzaną przypisaną przez system do zasobu jednocześnie. Może to być przydatne w scenariuszach, w których wszystkie aplikacje wymagają dostępu do tych samych usług udostępnionych, ale jedna z aplikacji ma również określoną zależność od dodatkowej usługi. Użycie tożsamości zarządzanej przypisanej przez system gwarantuje również, że tożsamość powiązana z daną aplikacją zostanie usunięta po usunięciu aplikacji, co może pomóc w utrzymaniu czystego środowiska.
W tym samouczku przedstawiono sposób migrowania aplikacji do połączeń bez hasła. Przeczytaj następujące zasoby, aby dokładniej zapoznać się z pojęciami omówionymi w tym artykule: