Note
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier les répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de changer de répertoire.
Cet article propose des instructions pour vous aider à optimiser les performances et la fiabilité de vos applications JavaScript et TypeScript lors de l’authentification auprès des services Azure. Pour tirer le meilleur parti de la bibliothèque Azure Identity pour JavaScript, il est important de comprendre les problèmes potentiels et les techniques d’atténuation.
Utiliser des informations d'identification déterministes dans les environnements de production
DefaultAzureCredential est le moyen le plus accessible pour commencer à utiliser la bibliothèque Azure Identity, mais cette commodité introduit également certains compromis. Surtout, il n’est pas possible de garantir à l’avance que l’identifiant spécifique dans la chaîne, qui réussira et sera utilisé pour l’authentification de la requête, sera toujours celui attendu. Dans un environnement de production, cette imprévisibilité peut entraîner des problèmes importants et parfois subtils.
Par exemple, considérez l'hypothétique séquence d'événements suivante :
- L'équipe de sécurité d'une organisation impose à toutes les applications d'utiliser des identités gérées pour s'authentifier auprès des ressources Azure.
- Pendant des mois, une application JavaScript hébergée sur une machine virtuelle Azure utilise
DefaultAzureCredentialavec succès pour s’authentifier via une identité managée. - Sans le dire à l'équipe de support, un développeur installe l'Azure CLI sur cette machine virtuelle et exécute la commande
az loginpour s'authentifier auprès d'Azure. - En raison de cette nouvelle modification de configuration distincte dans l’environnement Azure, l’authentification via l’identité managée d’origine commence de manière inattendue à échouer silencieusement.
-
DefaultAzureCredentialignore l’échec deManagedIdentityCredentialet recherche le prochain identifiant disponible, qui estAzureCliCredential. - L'application commence à utiliser les informations d'identification Azure CLI plutôt que l'identité gérée, ce qui peut échouer ou entraîner une élévation ou une réduction inattendue des privilèges.
Pour éviter ces types de problèmes subtils ou d’échecs silencieux dans les applications de production, remplacez DefaultAzureCredential par une implémentation de TokenCredential spécifique, telle que ManagedIdentityCredential. Consultez la documentation de la bibliothèque de client Azure Identity pour connaître les informations d’identification disponibles.
Par exemple, considérez la configuration suivante DefaultAzureCredential dans un projet Express.js :
import { DefaultAzureCredential } from "@azure/identity";
import { SecretClient } from "@azure/keyvault-secrets";
import { BlobServiceClient } from "@azure/storage-blob";
const credential = new DefaultAzureCredential();
const secretClient = new SecretClient("https://keyVaultName.vault.azure.net", credential);
const blobServiceClient = new BlobServiceClient(
"https://storageAccountName.blob.core.windows.net",
credential
);
Modifiez le code précédent pour sélectionner des informations d’identification en fonction de l’environnement dans lequel l’application s’exécute :
import { AzureDeveloperCliCredential, ManagedIdentityCredential, ChainedTokenCredential,
AzureCliCredential } from "@azure/identity";
import { SecretClient } from "@azure/keyvault-secrets";
import { BlobServiceClient } from "@azure/storage-blob";
let credential;
// In production, use only ManagedIdentityCredential
if (process.env.NODE_ENV === 'production') {
// For user-assigned managed identity, provide the client ID
credential = new ManagedIdentityCredential(process.env.AZURE_CLIENT_ID);
}
// In development, use a chain of credentials appropriate for local work
else {
credential = new ChainedTokenCredential(
new AzureCliCredential(),
new AzureDeveloperCliCredential()
);
}
// Initialize Key Vault client
const secretClient = new SecretClient("https://keyVaultName.vault.azure.net", credential);
// Initialize Blob Storage client
const blobServiceClient = new BlobServiceClient(
"https://storageAccountName.blob.core.windows.net",
credential
);
Dans cet exemple, seule ManagedIdentityCredential est utilisée en production. Les besoins d’authentification de l’environnement de développement local sont ensuite serviceés par la séquence d’informations d’identification définies dans la clause else.
Réutiliser les instances d’identifiants
Réutilisez les instances d'informations d'identification lorsque c'est possible pour améliorer la résilience de l'application et réduire le nombre de requêtes de jetons d'accès émises vers Microsoft Entra ID. Lorsqu'un identifiant est réutilisé, une tentative est faite pour récupérer un jeton dans le cache des jetons de l'application géré par la dépendance MSAL sous-jacente. Pour plus d’informations, consultez la mise en cache des jetons dans la bibliothèque cliente Azure Identity.
Le comportement de mise en cache des jetons diffère entre les environnements de navigateur et de Node.js. Dans Node.js applications, les jetons sont mis en cache en mémoire par défaut, ce qui signifie que le cache est perdu lorsque l’application redémarre. Dans les applications de navigateur, les jetons peuvent être conservés dans le stockage du navigateur (localStorage ou sessionStorage) en fonction du flux d’authentification et de la configuration. La compréhension de ces différences est importante lors de l’implémentation de stratégies de réutilisation des informations d’identification pour différents types d’applications.
Important
Une application à volume élevé qui ne réutilise pas les informations d’identification risque de subir des réponses de limitation HTTP 429 de Microsoft Entra ID, ce qui peut entraîner des interruptions de service.
La stratégie de réutilisation des informations d’identification recommandée diffère selon l’infrastructure d’application.
Pour implémenter la réutilisation des informations d’identification dans les applications JavaScript, créez une seule instance d’informations d’identification et réutilisez-la sur tous les objets clients :
import { DefaultAzureCredential, ManagedIdentityCredential } from "@azure/identity";
import { SecretClient } from "@azure/keyvault-secrets";
import { BlobServiceClient } from "@azure/storage-blob";
// Create a single credential instance
const credential = process.env.NODE_ENV === 'production'
? new ManagedIdentityCredential(process.env.AZURE_CLIENT_ID)
: new DefaultAzureCredential();
// Reuse the credential across different client objects
const secretClient = new SecretClient("https://keyVaultName.vault.azure.net", credential);
const blobServiceClient = new BlobServiceClient(
"https://storageAccountName.blob.core.windows.net",
credential
);
Dans Express.js applications, vous pouvez stocker les informations d’identification dans les paramètres de l’application et y accéder dans vos gestionnaires d’itinéraires :
import express from "express";
import { DefaultAzureCredential, ManagedIdentityCredential } from "@azure/identity";
import { SecretClient } from "@azure/keyvault-secrets";
import { BlobServiceClient } from "@azure/storage-blob";
const app = express();
// Create a single credential instance at app startup
app.locals.credential = process.env.NODE_ENV === 'production'
? new ManagedIdentityCredential(process.env.AZURE_CLIENT_ID)
: new DefaultAzureCredential();
// Reuse the credential in route handlers
app.get('/api/secrets/:secretName', async (req, res) => {
const secretClient = new SecretClient(
"https://keyVaultName.vault.azure.net",
req.app.locals.credential
);
try {
const secret = await secretClient.getSecret(req.params.secretName);
res.json({ name: secret.name, value: secret.value });
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// Add this route to the existing Express app
app.get('/api/blobs/:containerName', async (req, res) => {
const blobServiceClient = new BlobServiceClient(
"https://storageAccountName.blob.core.windows.net",
req.app.locals.credential
);
try {
// Get reference to a container
const containerClient = blobServiceClient.getContainerClient(req.params.containerName);
// List all blobs in the container
const blobs = [];
for await (const blob of containerClient.listBlobsFlat()) {
blobs.push({
name: blob.name,
contentType: blob.properties.contentType,
size: blob.properties.contentLength,
lastModified: blob.properties.lastModified
});
}
res.json({ containerName: req.params.containerName, blobs });
} catch (error) {
res.status(500).json({ error: error.message });
}
});
app.listen(3000, () => console.log('Server running on port 3000'));
Comprendre quand la durée de vie des jetons et la logique de mise en cache sont nécessaires
Si vous utilisez des informations d’identification de bibliothèque d’identités Azure en dehors du contexte d’une bibliothèque cliente du Kit de développement logiciel (SDK) Azure, vous devez gérer la durée de vie des jetons et le comportement de mise en cache dans votre application.
La refreshAfterTimestamp propriété sur AccessToken, qui fournit un indicateur aux consommateurs quant au moment où l’actualisation du jeton peut être tentée, sera automatiquement utilisée par les bibliothèques clientes du SDK Azure qui dépendent de la bibliothèque Azure Core pour actualiser le jeton. Pour une utilisation directe des identifiants de la bibliothèque Azure Identity qui prennent en charge la mise en cache des jetons, le cache MSAL sous-jacent s’actualise automatiquement de manière proactive lorsque le refreshAfterTimestamp temps survient. Cette conception permet au code client d’appeler TokenCredential.getToken() chaque fois qu’un jeton est nécessaire et de déléguer l’actualisation à la bibliothèque.
Pour appeler uniquement TokenCredential.getToken() si nécessaire, observez la date de refreshAfterTimestamp et tentez proactivement d'actualiser le jeton après ce moment-là. L’implémentation spécifique est à la hauteur du client.
Comprendre la stratégie de relance de l'identité gérée
La bibliothèque d’identités Azure pour JavaScript vous permet de vous authentifier via une identité managée avec ManagedIdentityCredential. La façon dont vous utilisez ManagedIdentityCredential impacte la stratégie de nouvelle tentative appliquée :
- Lorsqu’elle est utilisée via
DefaultAzureCredential, aucune nouvelle tentative n’est tentée lorsque la tentative d’acquisition de jeton initiale échoue ou expire après une courte durée. Il s’agit de l’option la moins résiliente, car elle est optimisée pour « échouer rapidement » pour une boucle interne de développement efficace. - Toute autre approche, comme
ChainedTokenCredentialouManagedIdentityCredentialdirectement :- L'intervalle de temps entre les tentatives commence à 0,8 seconde et un maximum de cinq tentatives sont effectuées par défaut. Cette option est optimisée pour la résilience, mais introduit des retards potentiellement indésirables dans la boucle interne de développement.
- Pour modifier l’un des paramètres de nouvelle tentative par défaut, utilisez la propriété retryOptions sur le paramètre options. Par exemple, réessayer un maximum de trois fois, avec un intervalle de départ de 0,5 seconde :
import { ManagedIdentityCredential } from "@azure/identity";
const credential = new ManagedIdentityCredential(
process.env.AZURE_CLIENT_ID, // For user-assigned managed identity
{
retryOptions: {
maxRetries: 3, // Maximum number of retry attempts
retryDelayInMs: 500, // Initial delay between retries (in milliseconds)
maxRetryDelayInMs: 5000 // Maximum delay between retries (in milliseconds)
}
}
);
Pour plus d’informations sur la personnalisation des stratégies de nouvelle tentative pour l’identité managée, consultez l’une des options suivantes qui s’étendent à partir de TokenCredentialOptions :