Dela via


Metodtips för autentisering med Azure Identity-biblioteket för JavaScript

Den här artikeln innehåller riktlinjer som hjälper dig att maximera prestanda och tillförlitlighet för dina JavaScript- och TypeScript-appar när du autentiserar till Azure-tjänster. För att få ut mesta möjliga av Azure Identity-biblioteket för JavaScript är det viktigt att förstå potentiella problem och riskreduceringstekniker.

Använda deterministiska autentiseringsuppgifter i produktionsmiljöer

DefaultAzureCredential är det mest lättillgängliga sättet att komma igång med Azure Identity-biblioteket, men den bekvämligheten medför också vissa kompromisser. Framför allt kan de specifika autentiseringsuppgifterna i kedjan som ska lyckas och användas för autentisering av begäranden inte garanteras i förväg. I en produktionsmiljö kan den här oförutsägbarheten medföra betydande och ibland subtila problem.

Tänk till exempel på följande hypotetiska händelsesekvens:

  1. En organisations säkerhetsteam kräver att alla appar använder hanterad identitet för att autentisera till Azure-resurser.
  2. I månader har en JavaScript-app som är värd på en Azure Virtual Machine (VM) framgångsrikt använt DefaultAzureCredential för att autentisera via hanterad identitet.
  3. Utan att berätta för supportteamet installerar en utvecklare Azure CLI på den virtuella datorn och kör kommandot az login för att autentisera till Azure.
  4. På grund av den här nya separata konfigurationsändringen i Azure-miljön börjar autentiseringen via den ursprungliga hanterade identiteten oväntat misslyckas tyst.
  5. DefaultAzureCredential hoppar över den misslyckade ManagedIdentityCredential och söker efter nästa tillgängliga autentiseringsuppgifter, vilket är AzureCliCredential.
  6. Programmet börjar använda Azure CLI-autentiseringsuppgifterna i stället för den hanterade identiteten, vilket kan misslyckas eller leda till oväntad höjning eller minskning av behörigheter.

Om du vill förhindra dessa typer av subtila problem eller tysta fel i produktionsappar ersätter du DefaultAzureCredential med en specifik TokenCredential implementering, till exempel ManagedIdentityCredential. Se dokumentationen för Azure Identity-klientbiblioteket för tillgängliga autentiseringsuppgifter.

Tänk till exempel på följande DefaultAzureCredential konfiguration i ett Express.js projekt:

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
);

Ändra föregående kod för att välja en autentiseringsuppgift baserat på miljön där appen körs:

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
);

I det här exemplet används endast ManagedIdentityCredential i produktion. Den lokala utvecklingsmiljöns autentiseringsbehov hanteras sedan av sekvensen med autentiseringsuppgifter som definieras i else-satsen.

Återanvänd autentiseringsinstanser

Återanvänd instanser av autentiseringsuppgifter när det är möjligt för att förbättra appåterhämtningen och minska antalet begäranden om åtkomsttoken som utfärdas till Microsoft Entra-ID. När en autentiseringsuppgift återanvänds görs ett försök att hämta en token från apptokencache som hanteras av det underliggande MSAL-beroendet. Mer information finns i cachelagring av token i Azure Identity-klientbiblioteket.

Beteendet för cachelagring av token skiljer sig mellan webbläsare och Node.js miljöer. I Node.js applikationer cachas tokens som standard i minnet, vilket innebär att cachen går förlorad när applikationen startas om. I webbläsarprogram kan token sparas i webbläsarens lagring (localStorage eller sessionStorage) beroende på autentiseringsflödet och konfigurationen. Att förstå dessa skillnader är viktigt när du implementerar strategier för återanvändning av autentiseringsuppgifter för olika programtyper.

Viktigt!

En högvolymapp som inte återanvänder autentiseringsuppgifter kan stöta på HTTP 429-begränsningssvar från Microsoft Entra-ID, vilket kan leda till appfel.

Den rekommenderade strategin för återanvändning av autentiseringsuppgifter skiljer sig åt beroende på programramverk.

Om du vill implementera återanvändning av autentiseringsuppgifter i JavaScript-program skapar du en enda instans av autentiseringsuppgifter och återanvänder den i alla klientobjekt:

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
);

I Express.js program kan du lagra autentiseringsuppgifterna i appinställningarna och komma åt den i dina routningshanterare:

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'));

Förstå när tokens livslängd och cachelagringslogik behövs

Om du använder en Azure Identity Library-autentiseringsuppgift utanför kontexten för ett Azure SDK-klientbibliotek blir det ditt ansvar att hantera tokens livslängd och cachelagringsbeteende i din app.

Egenskapen refreshAfterTimestampAccessToken, som ger ett tips till konsumenter om när tokenuppdatering kan göras, används automatiskt av Azure SDK-klientbibliotek som är beroende av Azure Core-biblioteket för att uppdatera token. För direkt användning av Azure Identity-bibliotekets autentiseringsuppgifter som stöder tokencachelagringen uppdateras den underliggande MSAL-cachen automatiskt när refreshAfterTimestamp tiden inträffar. Med den här designen kan klientkoden anropa TokenCredential.getToken() varje gång en token behövs och delegera uppdateringen till biblioteket.

Om du bara vill anropa TokenCredential.getToken() vid behov kan du observera refreshAfterTimestamp datum och proaktivt försöka uppdatera token efter den tiden. Den specifika implementeringen är upp till kunden.

Förstå strategin för återförsök av hanterad identitet

Med Azure Identity-biblioteket för JavaScript kan du autentisera via hanterad identitet med ManagedIdentityCredential. Hur du använder ManagedIdentityCredential påverkar den tillämpade återförsöksstrategin:

  • När det används via DefaultAzureCredentialgörs inga återförsök när det första tokeninsamlingsförsöket misslyckas eller överskrider tidsgränsen efter en kort tid. Det här är det minst motståndskraftiga alternativet eftersom det är optimerat för att "misslyckas snabbt" för en effektiv inre loop för utveckling.
  • Andra metoder, till exempel ChainedTokenCredential eller ManagedIdentityCredential direkt:
    • Tidsintervallet mellan återförsök börjar vid 0,8 sekunder och högst fem återförsök görs som standard. Det här alternativet är optimerat för motståndskraft men medför potentiellt oönskade fördröjningar i den inre utvecklingsloopen.
    • Om du vill ändra någon av standardinställningarna för återförsök använder du egenskapen retryOptions på alternativparametern. Försök till exempel igen högst tre gånger med ett startintervall på 0,5 sekunder:
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)
    }
  }
);

Mer information om hur du anpassar återförsöksprinciper för hanterad identitet finns i något av följande alternativ som sträcker sig från TokenCredentialOptions: