Настройка бессерверных подключений между несколькими приложениями и службами Azure
Статья
Приложения часто требуют безопасных подключений между несколькими службами Azure одновременно. Например, экземпляр корпоративной Службы приложений Azure может подключаться к нескольким разным учетным записям хранения, экземпляру базы данных Azure SQL, служебной шине и т. д.
Управляемые удостоверения — это рекомендуемый способ проверки подлинности для безопасных подключений без пароля между ресурсами Azure. Разработчикам не нужно вручную отслеживать множество разных секретов для управляемых удостоверений и управлять ими, так как большинство этих задач обрабатываются внутри Azure. В этом учебнике рассматривается управление подключениями между несколькими службами с помощью управляемых удостоверений и клиентской библиотеки удостоверений Azure.
Сравнение типов управляемых удостоверений
Azure предоставляет следующие типы управляемых удостоверений:
Назначаемые системой удостоверения напрямую связаны с одним ресурсом Azure. При включении в службе управляемого удостоверения, назначаемого системой, Azure создаст связанное удостоверение и выполнит обработку административных задач для этого удостоверения внутри. При удалении ресурса Azure также удаляется удостоверение.
Управляемые удостоверения, назначаемые пользователем, являются независимыми удостоверениями, созданными администратором, и могут быть связаны с одним или несколькими ресурсами Azure. Жизненный цикл удостоверения не зависит от этих ресурсов.
Дополнительные сведения о рекомендациях и способах использования назначаемых системой удостоверений и удостоверений, назначаемых пользователем, см. в рекомендациях по использованию удостоверений.
Обзор DefaultAzureCredential
Управляемые удостоверения обычно реализуются в коде приложения с помощью класса под названием DefaultAzureCredential из клиентской библиотеки Azure.Identity. DefaultAzureCredential поддерживает несколько способов проверки подлинности и автоматически определяет, какой из них следует использовать в среде выполнения. Дополнительные сведения об этом подходе см. в обзоре DefaultAzureCredential.
Подключение размещенного в Azure приложения к нескольким службам Azure
Вы получили задачу подключить существующее приложение к нескольким службам и базам данных Azure с помощью подключений без пароля. Приложение представляет собой веб-API ASP.NET Core, размещенный в Службе приложений Azure, хотя приведенные ниже действия применимы и к другим средам размещения Azure, таким как Azure Spring Apps, Виртуальные машины, Контейнеры приложений и AKS.
Сведения в этом учебники применимы к следующим архитектурам, хотя его также можно адаптировать ко многим другим сценариям с помощью минимальных изменений конфигурации.
Ниже описаны действия по настройке приложения для использования управляемого удостоверения, назначаемого системой, и локальной учетной записи разработки для подключения к нескольким службам Azure.
Создание управляемого удостоверения, назначаемого системой
На портале Azure перейдите в размещенное приложение, которое вы хотите подключить к другим службам.
На странице обзора службы выберите Удостоверение.
Чтобы включить управляемое удостоверение, назначаемое системой, для службы установите переключательСостояние в положение Вкл.
Назначение ролей управляемому удостоверению для каждой подключенной службы
Перейдите на страницу обзора учетной записи хранения, которой вы хотите предоставить доступ к удостоверениям.
Выберите Контроль доступа (IAM) в области навигации по учетной записи хранения.
Нажмите + Добавить, а затем — Добавить назначение ролей.
В поле поиска Роли найдите участника данных BLOB-объектов хранилища, который предоставляет разрешения на выполнение операций чтения и записи с данными BLOB-объектов. Вы можете назначить любую роль, подходящую для вашего варианта использования. Выберите значение Участник данных BLOB-объектов хранилища в списке и нажмите кнопку Далее.
На экране Добавление назначения ролей для параметра Назначение доступа для выберите Управляемое удостоверение. Затем нажмите + Выбрать членов.
Во всплывающем элементе найдите управляемое удостоверение, созданное путем ввода имени службы приложений. Выберите назначаемое системой удостоверение и нажмите кнопку Выбрать, чтобы закрыть всплывающее меню.
Нажмите кнопку Далее несколько раз, пока не сможете нажать кнопку Проверить и назначить, чтобы завершить назначение роли.
Повторите этот процесс для других служб, к которым вы хотите подключиться.
Рекомендации к локальной разработке
Вы также можете включить доступ к ресурсам Azure для локальной разработки, назначив роли для учетной записи пользователя так же, как и были назначены роли управляемому удостоверению.
После назначения роли участника данных BLOB-объектов хранилища управляемому удостоверению в разделе Назначить доступ теперь выберите Пользователь, группа или субъект-служба. Нажмите + Выбрать членов, чтобы снова открыть всплывающее меню.
Найдите учетную запись user@domain или группу безопасности Microsoft Entra, к которым вы хотите предоставить доступ по адресу электронной почты или имени, а затем выберите ее. Это должна быть та же учетная запись, используемая для входа в локальные инструменты разработки, например Visual Studio или Azure CLI.
Примечание.
Вы также можете назначить эти роли группе безопасности Microsoft Entra, если вы работаете над командой с несколькими разработчиками. Затем вы можете поместить в эту группу любого разработчика, которому требуется доступ для локальной разработки приложения.
В проекте добавьте ссылку на пакет NuGet Azure.Identity. Эта библиотека содержит все необходимые сущности для реализации DefaultAzureCredential. Вы также можете добавить другие библиотеки Azure, относящиеся к вашему приложению. В этом примере выполняется добавление пакетов Azure.Storage.Blobs и Azure.KeyVault.Keys для подключения к хранилищу BLOB-объектов и Key Vault.
В начало файла Program.cs добавьте следующие операторы using:
using Azure.Identity;
using Azure.Storage.Blobs;
using Azure.Security.KeyVault.Keys;
В файле Program.cs кода проекта создайте экземпляры необходимых служб, к которым будет подключаться ваше приложение. Следующие примеры подключаются к хранилищу BLOB-объектов и служебной шине с помощью соответствующих классов SDK.
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");
В проекте добавьте azure-identity зависимость в файл pom.xml . Эта библиотека содержит все необходимые сущности для реализации DefaultAzureCredential. Вы также можете добавить любые другие зависимости Azure, относящиеся к вашему приложению. В этом примере azure-storage-blob добавляются зависимости и azure-messaging-servicebus зависимости для подключения к служба хранилища BLOB-объектов и Key Vault.
В коде проекта создайте экземпляры необходимых служб, к которому будет подключаться ваше приложение. Следующие примеры подключаются к хранилищу BLOB-объектов и служебной шине с помощью соответствующих классов SDK.
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();
}
}
В проекте нужно добавить только зависимости службы. В этом примере spring-cloud-azure-starter-storage-blob добавляются зависимости и spring-cloud-azure-starter-servicebus зависимости для подключения к служба хранилища BLOB-объектов и Key Vault.
В коде проекта создайте экземпляры необходимых служб, к которому будет подключаться ваше приложение. Следующие примеры подключаются к хранилищу BLOB-объектов и служебной шине с помощью соответствующих классов SDK.
@Service
public class ExampleService {
@Autowired
private BlobServiceClient blobServiceClient;
@Autowired
private ServiceBusSenderClient serviceBusSenderClient;
}
В проекте используйте npm , чтобы добавить ссылку на @azure/identity пакет. Эта библиотека содержит все необходимые сущности для реализации DefaultAzureCredential. Установите все другие библиотеки пакета SDK Azure, относящиеся к приложению.
В верхней части index.js файла добавьте следующие import инструкции, чтобы импортировать необходимые клиентские классы для служб, к которому будет подключаться ваше приложение:
import { DefaultAzureCredential } from "@azure/identity";
import { BlobServiceClient } from "@azure/storage-blob";
import { KeyClient } from "@azure/keyvault-keys";
В файле создайте клиентские index.js объекты для служб Azure, к которому будет подключаться ваше приложение. В следующих примерах можно подключиться к служба хранилища BLOB-объектов и Key Vault с помощью соответствующих классов ПАКЕТА SDK.
// 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");
При локальном DefaultAzureCredential выполнении этого кода приложения выполняется поиск цепочки учетных данных для первых доступных учетных данных. Если Managed_Identity_Client_ID равно null локально, оно автоматически будет использовать учетные данные из строки Azure CLI или Visual Studio. Дополнительные сведения об этом процессе см. в обзоре библиотеки удостоверений Azure.
При развертывании приложения в Azure DefaultAzureCredential автоматически извлекает переменную Managed_Identity_Client_ID из среды службы приложений. Это значение становится доступным, когда управляемое удостоверение связано с вашим приложением.
Этот общий процесс гарантирует, что ваше приложение может безопасно работать локально и в Azure без каких-либо изменений кода.
Подключение нескольких приложений с помощью нескольких управляемых удостоверений
Хотя приложения в предыдущем примере имеют одни и те же требования к доступу к службе, в реальных средах часто встречается больше нюансов. Рассмотрим сценарий, в котором несколько приложений подключаются к одним и тем же учетным записям хранения, но два приложения также получают доступ к разным службам или базам данных.
Чтобы выполнить эту настройку в коде, убедитесь, что приложение регистрирует отдельные службы для подключения к каждой учетной записи хранения или базе данных. При настройке DefaultAzureCredential обязательно извлеките правильные идентификаторы клиентов управляемых удостоверений для каждой службы. В следующем примере кода настраиваются следующие подключения к службам:
Два подключения к отдельным учетным записям хранения с помощью управляемого удостоверения, назначаемого пользователем
Подключение к Azure Cosmos DB и службам Azure SQL с помощью второго общего управляемого удостоверения, назначаемого пользователем
// 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();
}
}
}
В проекте используйте npm , чтобы добавить ссылку на @azure/identity пакет. Эта библиотека содержит все необходимые сущности для реализации DefaultAzureCredential. Установите все другие библиотеки пакета SDK Azure, относящиеся к приложению.
В верхней части index.js файла добавьте следующие import инструкции, чтобы импортировать необходимые клиентские классы для служб, к которому будет подключаться ваше приложение:
import { DefaultAzureCredential } from "@azure/identity";
import { BlobServiceClient } from "@azure/storage-blob";
import { KeyClient } from "@azure/keyvault-keys";
В файле создайте клиентские index.js объекты для служб Azure, к которому будет подключаться ваше приложение. В следующих примерах можно подключиться к служба хранилища BLOB-объектов, Cosmos DB и SQL Azure с помощью соответствующих классов SDK.
// 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);
Вы также можете одновременно связать управляемое удостоверение, назначаемое пользователем, и управляемое удостоверение, назначаемое системой, с ресурсом. Это может быть полезно в сценариях, когда для всех приложений требуется доступ к одним общим службам, но одно из приложений также имеет крайне определенную зависимость от дополнительной службы. Использование назначаемого системой удостоверения также гарантирует, что удостоверение, привязанное к этому конкретному приложению, удаляется при удалении приложения, что поддерживает чистоту среды.
Из этого учебника вы узнали, как выполнить переход приложения на подключение без пароля. Дополнительные сведения о понятиях, описанных в этой статье, см. в следующих ресурсах: