Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Questo articolo offre linee guida per ottimizzare le prestazioni e l'affidabilità delle app JavaScript e TypeScript durante l'autenticazione ai servizi di Azure. Per sfruttare al meglio la libreria di identità di Azure per JavaScript, è importante comprendere i potenziali problemi e le tecniche di mitigazione.
Usare credenziali deterministiche negli ambienti di produzione
DefaultAzureCredential è il modo più accessibile per iniziare a usare la libreria di identità di Azure, ma questa praticità introduce anche alcuni compromessi. In particolare, le credenziali specifiche nella catena che avranno esito positivo e che verranno usate per l'autenticazione della richiesta non possono essere garantite in anticipo. In un ambiente di produzione, questa imprevedibilità può introdurre problemi significativi e talvolta sottili.
Si consideri, ad esempio, la sequenza ipotetica di eventi seguente:
- Il team di sicurezza di un'organizzazione impone a tutte le app di usare l'identità gestita per l'autenticazione alle risorse di Azure.
- Per mesi, un'app JavaScript ospitata in una macchina virtuale di Azure usa
DefaultAzureCredentialcorrettamente per l'autenticazione tramite identità gestita. - Senza indicare al team di supporto, uno sviluppatore installa l'interfaccia della riga di comando di Azure in tale macchina virtuale ed esegue il comando
az loginper l'autenticazione in Azure. - A causa di questa nuova modifica di configurazione separata nell'ambiente Azure, l'autenticazione tramite l'identità gestita originale inizia in modo imprevisto a non riuscire in modo invisibile all'utente.
-
DefaultAzureCredentialignora ilManagedIdentityCredentialnon riuscito e cerca le credenziali disponibili successive, ovveroAzureCliCredential. - L'applicazione inizia a usare le credenziali dell'interfaccia della riga di comando di Azure anziché l'identità gestita, che potrebbe non riuscire o comportare un'elevazione o una riduzione imprevista dei privilegi.
Per evitare questi tipi di problemi sottili o errori invisibile all'utente nelle app di produzione, sostituire DefaultAzureCredential con un'implementazione di TokenCredential specifica, ad esempio ManagedIdentityCredential. Per informazioni sulle credenziali disponibili, vedere la documentazione della libreria client di Identità di Azure .
Si consideri ad esempio la configurazione seguente DefaultAzureCredential in un progetto 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
);
Modificare il codice precedente per selezionare una credenziale in base all'ambiente in cui è in esecuzione l'app:
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
);
In questo esempio viene usato solo ManagedIdentityCredential nell'ambiente di produzione. Le esigenze di autenticazione dell'ambiente di sviluppo locale vengono quindi gestite dalla sequenza di credenziali definite nella clausola else.
Riutilizzare le istanze delle credenziali
Riutilizzare le istanze delle credenziali quando possibile per migliorare la resilienza delle app e ridurre il numero di richieste di token di accesso inviate a Microsoft Entra ID. Quando viene riutilizzata una credenziale, viene effettuato un tentativo di recuperare un token dalla cache dei token dell'app gestita dalla dipendenza MSAL sottostante. Per ulteriori informazioni, vedere Cache dei token nella libreria client di Azure Identity.
Il comportamento della memorizzazione nella cache dei token differisce tra browser e ambienti Node.js. Nelle applicazioni Node.js, i token vengono memorizzati nella cache in memoria per impostazione predefinita, il che significa che la cache viene persa al riavvio dell'applicazione. Nelle applicazioni browser i token possono essere salvati in modo permanente nell'archiviazione del browser (localStorage o sessionStorage) a seconda del flusso di autenticazione e della configurazione. Comprendere queste differenze è importante quando si implementano strategie di riutilizzo delle credenziali per diversi tipi di applicazione.
Importante
Un'applicazione ad alto traffico che non riutilizza le credenziali potrebbe riscontrare messaggi di limitazione HTTP 429 da Microsoft Entra ID, che possono causare interruzioni dell'applicazione.
La strategia di riutilizzo delle credenziali consigliata è diversa dal framework applicazione.
Per implementare il riutilizzo delle credenziali nelle applicazioni JavaScript, creare una singola istanza delle credenziali e riutilizzarla in tutti gli oggetti client:
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
);
Nelle applicazioni Express.js è possibile archiviare le credenziali nelle impostazioni dell'app e accedervi nei gestori di route:
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'));
Comprendere quando è necessaria la logica di memorizzazione nella cache e la durata dei token
Se si usano credenziali della libreria di identità di Azure al di fuori del contesto di una libreria client di Azure SDK, diventa responsabilità dell'utente gestire la durata dei token e il comportamento di memorizzazione nella cache nell'app.
La refreshAfterTimestamp proprietà in AccessToken, che fornisce un suggerimento ai consumer quando è possibile tentare l'aggiornamento del token, verrà usata automaticamente dalle librerie client di Azure SDK che dipendono dalla libreria core di Azure per aggiornare il token. Per l'uso diretto delle credenziali della libreria di identità di Azure che supportano il caching dei token, la cache MSAL sottostante si aggiorna automaticamente in modo proattivo quando si verifica il tempo refreshAfterTimestamp. Questa progettazione consente al codice client di chiamare TokenCredential.getToken() ogni volta che è necessario un token e delegare l'aggiornamento alla libreria.
Per chiamare TokenCredential.getToken() solo quando necessario, monitorare la data refreshAfterTimestamp e provare ad aggiornare proattivamente il token dopo tale ora. L'implementazione specifica spetta al cliente.
Comprendere la strategia di ripetizione dei tentativi per identità gestita
La libreria di identità di Azure per JavaScript consente di eseguire l'autenticazione tramite l'identità gestita con ManagedIdentityCredential. Il modo in cui si usa ManagedIdentityCredential influisce sulla strategia di ripetizione dei tentativi applicata:
- Se utilizzato tramite
DefaultAzureCredential, non vengono effettuati tentativi quando il tentativo iniziale di acquisizione del token fallisce o va in timeout dopo un breve periodo di tempo. Questa è l'opzione meno resiliente perché è ottimizzata per un approccio di "fallimento rapido" per un ciclo interno di sviluppo efficiente. - Qualsiasi altro approccio, ad esempio
ChainedTokenCredentialoManagedIdentityCredentialdirettamente:- L'intervallo di tempo tra le ripetizioni inizia a 0,8 secondi e vengono effettuate un massimo di cinque ripetizioni per impostazione predefinita. Questa opzione è ottimizzata per la resilienza, ma introduce ritardi potenzialmente indesiderati nel ciclo interno di sviluppo.
- Per modificare una delle impostazioni predefinite per i tentativi, usare la proprietà retryOptions nel parametro options. Ad esempio, ripetere un massimo di tre volte, con un intervallo di inizio di 0,5 secondi:
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)
}
}
);
Per altre informazioni sulla personalizzazione dei criteri di ripetizione dei tentativi per l'identità gestita, vedere una delle opzioni seguenti che si estendono da TokenCredentialOptions: