Configurer des connexions sans mot de passe entre plusieurs applications et services Azure
Article
Les applications nécessitent souvent des connexions sécurisées entre plusieurs services Azure simultanément. Par exemple, une instance Azure App Service d’entreprise peut se connecter à plusieurs comptes de stockage différents, une instance de base de données Azure SQL, un service bus, etc.
Les identités managées sont l’option d’authentification recommandée pour les connexions sécurisées sans mot de passe entre les ressources Azure. Les développeurs n’ont pas à suivre et gérer manuellement de nombreux secrets différents pour les identités managées, car la plupart de ces tâches sont gérées en interne par Azure. Ce didacticiel explique comment gérer les connexions entre plusieurs services à l’aide d’identités managées et de la bibliothèque cliente Azure Identity.
Comparer les types d’identités managées
Azure fournit les types d’identités managées suivantes :
Les identités managées affectées par le système sont directement liées à une seule ressource Azure. Lorsque vous activez une identité managée affectée par le système sur un service, Azure crée une identité liée et gère les tâches administratives pour cette identité en interne. Quand la ressource Azure est supprimée, l’identité l’est aussi.
Les identités managées affectées par l’utilisateur sont des identités indépendantes créées par un administrateur et peuvent être associées à une ou plusieurs ressources Azure. Le cycle de vie de l’identité est indépendant de ces ressources.
Vous pouvez en savoir plus sur les meilleures pratiques et quand utiliser des identités affectées par le système et des identités affectées par l’utilisateur dans les recommandations de meilleures pratiques des identités.
Explorer DefaultAzureCredential
Les identités managées sont généralement implémentées dans votre code d’application via une classe appelée DefaultAzureCredential à partir de la Azure.Identity bibliothèque cliente. DefaultAzureCredential prend en charge plusieurs méthodes d’authentification et détermine automatiquement celle qui doit être utilisée au moment de l’exécution. Vous pouvez en savoir plus sur cette approche dans la vue d’ensemble defaultAzureCredential.
Connecter une application hébergée Azure à plusieurs services Azure
Vous avez été chargé de connecter une application existante à plusieurs services et bases de données Azure à l’aide de connexions sans mot de passe. L’application est une API web ASP.NET Core hébergée sur Azure App Service, bien que les étapes ci-dessous s’appliquent également à d’autres environnements d’hébergement Azure, tels qu’Azure Spring Apps, Machines Virtuelles, Container Apps et AKS.
Ce didacticiel s’applique aux architectures suivantes, bien qu’il puisse être adapté à de nombreux autres scénarios ainsi qu’à des modifications de configuration minimales.
Les étapes suivantes montrent comment configurer une application pour utiliser une identité managée affectée par le système et votre compte de développement local pour se connecter à plusieurs services Azure.
Créer une identité managée affectée par le système
Dans le Portail Azure, accédez à l’application hébergée que vous souhaitez vous connecter à d’autres services.
Sur la page vue d’ensemble du service, sélectionnez Identité.
Basculez le paramètre d’Etat sur Activé pour activer une identité managée affectée par le système pour le service.
Attribuer des rôles à l’identité managée pour chaque service connecté
Accédez à la page vue d’ensemble du compte de stockage auquel vous souhaitez accorder l’accès à votre identité.
Sélectionnez Contrôle d’accès (IAM) à partir de la navigation du compte de stockage.
Choisissez + Ajouter, puis Ajouter une attribution de rôle.
Dans la zone de recherche de Rôle, recherchez le Contributeur de données Blob de stockage, qui accorde des autorisations pour effectuer des opérations de lecture et d’écriture sur les données d’objets blob. Vous pouvez attribuer le rôle approprié pour votre cas d’usage. Sélectionnez le contributeur de données blob de stockage dans la liste, puis choisissez Suivant.
Sur l’écran Ajouter une attribution de rôle, pour l’option Attribuer l’accès à l’option , sélectionnez Identité managée. Choisissez ensuite +Sélectionner des membres.
Dans le menu volant, recherchez l’identité managée que vous avez créée en entrant le nom de votre service app. Sélectionnez l’identité affectée par le système, puis choisissez Sélectionner pour fermer le menu volant.
Sélectionnez Suivant plusieurs fois jusqu’à ce que vous puissiez sélectionner Vérifier + attribuer pour terminer l’attribution de rôle.
Répétez ce processus pour les autres services auxquels vous souhaitez vous connecter.
Considérations relatives au développement local
Vous pouvez également activer l’accès aux ressources Azure pour le développement local en affectant des rôles à un compte d’utilisateur de la même façon que vous avez attribué des rôles à votre identité managée.
Après avoir attribué le rôle Contributeur de données Blob de stockage à votre identité managée, sous Attribuer l’accès à, cette fois sélectionnez Utilisateur, groupe ou principal de service. Choisissez + Sélectionner des membres pour ouvrir à nouveau le menu volant.
Recherchez le compte user@domain ou le groupe de sécurité Microsoft Entra auquel vous souhaitez accorder l’accès par adresse e-mail ou par nom, puis sélectionnez-le. Il doit s’agir du même compte que celui que vous utilisez pour vous connecter à vos outils de développement local, tels que Visual Studio ou Azure CLI.
Remarque
Vous pouvez également attribuer ces rôles à un groupe de sécurité Microsoft Entra si vous travaillez sur une équipe avec plusieurs développeurs. Vous pouvez ensuite placer n’importe quel développeur dans ce groupe qui a besoin d’accéder au développement de l’application localement.
À l’intérieur de votre projet, ajoutez une référence au package NuGet Azure.Identity. Cette bibliothèque contient toutes les entités nécessaires pour implémenter DefaultAzureCredential. Vous pouvez également ajouter toutes les autres bibliothèques Azure qui sont pertinentes pour votre application. Pour cet exemple, les packages Azure.Storage.Blobs et Azure.KeyVault.Keys sont ajoutés pour se connecter au stockage Blob et Key Vault.
En haut de votre fichier Program.cs, ajoutez les instructions d’utilisation suivantes :
using Azure.Identity;
using Azure.Storage.Blobs;
using Azure.Security.KeyVault.Keys;
Dans le fichier Program.cs de votre code de projet, créez des instances des services nécessaires auxquels votre application se connecte. Les exemples suivants se connectent au stockage Blob et au service bus à l’aide des classes SDK correspondantes.
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");
Dans votre projet, ajoutez la dépendance azure-identity à votre fichier pom.xml. Cette bibliothèque contient toutes les entités nécessaires pour implémenter DefaultAzureCredential. Vous pouvez également ajouter toutes les autres dépendances Azure qui sont pertinentes pour votre application. Pour cet exemple, les dépendances azure-storage-blob et azure-messaging-servicebus sont ajoutées pour se connecter au Stockage Blob et à Key Vault.
Dans le code de votre projet, créez des instances des services nécessaires auxquels votre application se connecte. Les exemples suivants se connectent au stockage Blob et au service bus à l’aide des classes SDK correspondantes.
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();
}
}
Dans votre projet, vous devez uniquement ajouter les dépendances de service que vous utilisez. Pour cet exemple, les dépendances spring-cloud-azure-starter-storage-blob et spring-cloud-azure-starter-servicebus sont ajoutées pour se connecter au Stockage Blob et à Key Vault.
Dans le code de votre projet, créez des instances des services nécessaires auxquels votre application se connecte. Les exemples suivants se connectent au stockage Blob et au service bus à l’aide des classes SDK correspondantes.
@Service
public class ExampleService {
@Autowired
private BlobServiceClient blobServiceClient;
@Autowired
private ServiceBusSenderClient serviceBusSenderClient;
}
À l’intérieur de votre projet, utilisez npm pour ajouter une référence au package @azure/identity. Cette bibliothèque contient toutes les entités nécessaires pour implémenter DefaultAzureCredential. Installez toutes les autres bibliothèques du Kit de développement logiciel (SDK) Azure pertinentes pour votre application.
En haut de votre fichier index.js, ajoutez les instructions import suivantes pour importer les classes clientes nécessaires pour les services auxquels votre application se connecte :
import { DefaultAzureCredential } from "@azure/identity";
import { BlobServiceClient } from "@azure/storage-blob";
import { KeyClient } from "@azure/keyvault-keys";
Dans le fichier index.js, créez des objets clients pour les services Azure auxquels votre application se connecte. Les exemples suivants se connectent au Stockage Blob et au Key Vault à l’aide des classes de SDK correspondantes.
// 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");
Lorsque ce code d’application s’exécute localement, DefaultAzureCredential recherche une chaîne d’informations d’identification pour les premières informations d’identification disponibles. Si la valeur Managed_Identity_Client_ID est null localement, elle utilise automatiquement les informations d’identification de votre interface de ligne de commande Azure locale ou de la connexion Visual Studio. Vous pouvez en savoir plus sur ce processus dans la vue d’ensemble de la bibliothèque Azure Identity.
Lorsque l’application est déployée sur Azure, DefaultAzureCredential récupère automatiquement la variable Managed_Identity_Client_ID à partir de l’environnement App Service. Cette valeur devient disponible lorsqu’une identité managée est associée à votre application.
Ce processus global garantit que votre application peut s’exécuter en toute sécurité localement et dans Azure sans avoir besoin de modifications de code.
Connectez plusieurs applications à l’aide de plusieurs identités managées
Bien que les applications de l’exemple précédent partagent toutes les mêmes exigences d’accès au service, les environnements réels sont souvent plus nuancés. Envisagez un scénario où plusieurs applications se connectent aux mêmes comptes de stockage, mais deux des applications accèdent également à différents services ou bases de données.
Pour configurer cette configuration dans votre code, assurez-vous que votre application inscrit des services distincts pour se connecter à chaque compte de stockage ou base de données. Veillez à extraire les ID du client d’identité managée corrects pour chaque service lors de la configuration de DefaultAzureCredential. L’exemple de code suivant configure les connexions de service suivantes :
Deux connexions à des comptes de stockage distincts à l’aide d’une identité managée affectée par l’utilisateur partagé
Connexion aux services Azure Cosmos DB et Azure SQL à l’aide d’une deuxième identité managée affectée par l’utilisateur partagé
// 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();
}
}
}
Azure Spring Cloud ne prend pas en charge la configuration de plusieurs clients du même service, les codes suivants créent plusieurs beans pour cette situation.
@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();
}
}
À l’intérieur de votre projet, utilisez npm pour ajouter une référence au package @azure/identity. Cette bibliothèque contient toutes les entités nécessaires pour implémenter DefaultAzureCredential. Installez toutes les autres bibliothèques du Kit de développement logiciel (SDK) Azure pertinentes pour votre application.
En haut de votre fichier index.js, ajoutez les instructions import suivantes pour importer les classes clientes nécessaires pour les services auxquels votre application se connecte :
import { DefaultAzureCredential } from "@azure/identity";
import { BlobServiceClient } from "@azure/storage-blob";
import { KeyClient } from "@azure/keyvault-keys";
Dans le fichier index.js, créez des objets clients pour les services Azure auxquels votre application se connecte. Les exemples suivants se connectent au Stockage Blob, à Cosmos DB et Azure SQL à l’aide des classes du Kit de développement logiciel (SDK) correspondantes.
// 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);
Vous pouvez également associer une identité managée affectée par l’utilisateur ainsi qu’une identité managée affectée par le système à une ressource simultanément. Cela peut être utile dans les scénarios où toutes les applications nécessitent l’accès aux mêmes services partagés, mais l’une des applications a également une dépendance très spécifique sur un service supplémentaire. L’utilisation d’une identité affectée par le système garantit également que l’identité liée à cette application spécifique est supprimée lorsque l’application est supprimée, ce qui peut vous aider à nettoyer votre environnement.
Dans ce didacticiel, vous avez appris à migrer une application vers des connexions sans mot de passe. Vous pouvez lire les ressources suivantes pour explorer les concepts abordés dans cet article plus en détails :