Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Este artigo oferece diretrizes para ajudá-lo a maximizar o desempenho e a confiabilidade de seus aplicativos JavaScript e TypeScript ao autenticar nos serviços do Azure. Para aproveitar ao máximo a biblioteca de Identidade do Azure para JavaScript, é importante entender possíveis problemas e técnicas de mitigação.
Usar credenciais determinísticas em ambientes de produção
DefaultAzureCredential
é a maneira mais acessível de começar a usar a biblioteca de identidades do Azure, mas essa conveniência também apresenta certas compensações. Notavelmente, não se pode garantir antecipadamente qual credencial na cadeia terá êxito e será usada para a autenticação de requisição. Em um ambiente de produção, essa imprevisibilidade pode introduzir problemas significativos e, às vezes, sutis.
Por exemplo, considere a seguinte sequência hipotética de eventos:
- A equipe de segurança de uma organização determina que todos os aplicativos usem identidade gerenciada para autenticação nos recursos do Azure.
- Durante meses, um aplicativo JavaScript hospedado em uma VM (Máquina Virtual) do Azure usa
DefaultAzureCredential
com êxito para autenticar por meio de identidade gerenciada. - Sem informar a equipe de suporte, um desenvolvedor instala a CLI do Azure nessa VM e executa o comando
az login
para autenticar no Azure. - Devido a essa nova alteração de configuração separada no ambiente do Azure, a autenticação por meio da identidade gerenciada original inesperadamente começa a falhar silenciosamente.
-
DefaultAzureCredential
ignora oManagedIdentityCredential
que falhou e procura a próxima credencial disponível, que éAzureCliCredential
. - O aplicativo começa a utilizar as credenciais da CLI do Azure em vez da identidade gerenciada, o que pode falhar ou resultar em elevação ou redução inesperada de privilégios.
Para evitar esses tipos de problemas sutis ou falhas silenciosas em aplicativos de produção, substitua DefaultAzureCredential
por uma implementação específica TokenCredential
, como ManagedIdentityCredential
. Consulte a documentação da biblioteca de clientes da Identidade do Azure para obter as credenciais disponíveis.
Por exemplo, considere a seguinte DefaultAzureCredential
configuração em um projeto de 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
);
Modifique o código anterior para selecionar uma credencial com base no ambiente em que o aplicativo está em execução:
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
);
Neste exemplo, só ManagedIdentityCredential
é usado na produção. As necessidades de autenticação do ambiente de desenvolvimento local são então atendidas pela sequência de credenciais definidas na else
cláusula.
Reutilizar instâncias de credenciais
Reutilize instâncias de credenciais quando possível para melhorar a resiliência do aplicativo e reduzir o número de solicitações de token de acesso emitidas para o Microsoft Entra ID. Quando uma credencial é reutilizada, é feita uma tentativa de buscar um token do cache de token de aplicativo gerenciado pela dependência subjacente do MSAL. Para obter mais informações, consulte Cache de token na biblioteca de cliente do Azure Identity.
O comportamento de armazenamento em cache de tokens difere entre ambientes de navegador e Node.js. Em aplicativos Node.js, os tokens são armazenados em cache na memória por padrão, o que significa que o cache é perdido quando o aplicativo é reiniciado. Em aplicativos de navegador, os tokens podem ser persistidos no armazenamento do navegador (localStorage
ou sessionStorage
) dependendo do fluxo de autenticação e da configuração. Entender essas diferenças é importante ao implementar estratégias de reutilização de credenciais para diferentes tipos de aplicativo.
Importante
Um aplicativo de alto volume que não reutiliza credenciais pode encontrar respostas de limitação de HTTP 429 do Microsoft Entra ID, o que pode levar a interrupções do aplicativo.
A estratégia de reutilização de credencial recomendada é diferente pela estrutura do aplicativo.
Para implementar a reutilização de credenciais em aplicativos JavaScript, crie uma única instância de credencial e reutilize-a em todos os objetos cliente:
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
);
Em Express.js aplicativos, você pode armazenar a credencial nas configurações do aplicativo e acessá-la em seus manipuladores de rota:
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'));
Entender quando o tempo de vida do token e a lógica de cache são necessários
Se você usar uma credencial da biblioteca de Identidade do Azure fora do contexto de uma biblioteca de clientes do SDK do Azure, ela se tornará sua responsabilidade para gerenciar o tempo de vida do token e o comportamento de cache em seu aplicativo.
A refreshAfterTimestamp
propriedade no AccessToken, que fornece uma dica aos consumidores sobre quando a atualização de token pode ser tentada, será usada automaticamente pelas bibliotecas de clientes do SDK do Azure que dependem da biblioteca do Azure Core para atualizar o token. Para o uso direto das credenciais da biblioteca de identidade do Azure que dão suporte ao cache de token, o cache MSAL subjacente é atualizado automaticamente proativamente quando a refreshAfterTimestamp
hora ocorre. Esse design permite que o código do cliente chame TokenCredential.getToken() sempre que um token for necessário e delegar a atualização para a biblioteca.
Para apenas chamar TokenCredential.getToken()
quando necessário, observe a data refreshAfterTimestamp
e tente atualizar o token proativamente após esse período. A implementação específica cabe ao cliente.
Compreender a estratégia de repetição de identidade gerenciada
A biblioteca de identidades do Azure para JavaScript permite que você se autentique por meio de identidade gerenciada com ManagedIdentityCredential
. A maneira como você usa ManagedIdentityCredential
afeta a estratégia de repetição aplicada:
- Quando usado via
DefaultAzureCredential
, nenhuma tentativa é realizada quando a tentativa inicial de aquisição de token falha ou expira após um curto período. Essa é a opção menos resiliente porque é otimizada para "falhar rapidamente" para um loop interno de desenvolvimento eficiente. - Qualquer outra abordagem, como
ChainedTokenCredential
ouManagedIdentityCredential
diretamente:- O intervalo de tempo entre novas tentativas começa em 0,8 segundos, e, por padrão, são tentadas um máximo de cinco vezes. Essa opção é otimizada para resiliência, mas introduz atrasos potencialmente indesejados no loop interno de desenvolvimento.
- Para alterar qualquer uma das configurações de repetição padrão, use a propriedade retryOptions no parâmetro de opções. Por exemplo, tente novamente no máximo três vezes, com um intervalo inicial de 0,5 segundos:
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)
}
}
);
Para obter mais informações sobre como personalizar políticas de repetição para identidade gerenciada, consulte uma das seguintes opções que se estendem de TokenCredentialOptions: