Aracılığıyla paylaş


JavaScript için Azure Kimlik kitaplığı ile en iyi kimlik doğrulama yöntemleri

Bu makalede, Azure hizmetlerinde kimlik doğrulaması yaparken JavaScript ve TypeScript uygulamalarınızın performansını ve güvenilirliğini en üst düzeye çıkarmanıza yardımcı olacak yönergeler sunulmaktadır. JavaScript için Azure Kimlik kitaplığından en iyi şekilde çıkmak için olası sorunları ve azaltma tekniklerini anlamak önemlidir.

Üretim ortamlarında belirleyici kimlik bilgilerini kullanma

DefaultAzureCredential, Azure Kimlik kitaplığını kullanmaya başlamanın en kolay yoludur, ancak bu kolaylık bazı dezavantajları da ortaya çıkartır. En önemlisi, zincirde başarıya ulaşacak ve istek kimlik doğrulaması için kullanılacak belirli kimlik bilgileri önceden garanti edilemez. Bir üretim ortamında, bu öngörülemezlik önemli ve bazen hafif sorunlara yol açabilir.

Örneğin, aşağıdaki varsayımsal olay dizisini göz önünde bulundurun:

  1. Bir kuruluşun güvenlik ekibi, azure kaynaklarında kimlik doğrulaması yapmak için tüm uygulamaların yönetilen kimlik kullanmasını zorunlu kiliyor.
  2. Aylar boyunca, Azure Sanal Makinesinde (VM) barındırılan bir JavaScript uygulaması yönetilen kimlik aracılığıyla kimlik doğrulaması yapmak için başarıyla kullanır DefaultAzureCredential .
  3. Destek ekibine haber vermeden, bir geliştirici Azure CLI'yi bu VM'ye yükler ve Azure'da kimlik doğrulaması yapmak için az login komutunu çalıştırır.
  4. Azure ortamındaki bu yeni ayrı yapılandırma değişikliği nedeniyle, özgün yönetilen kimlik aracılığıyla kimlik doğrulaması beklenmedik bir şekilde sessizce başarısız olur.
  5. DefaultAzureCredential başarısız ManagedIdentityCredential'i atlıyor ve bir sonraki kullanılabilir kimlik bilgisi olan AzureCliCredential'yi arıyor.
  6. Uygulama, başarısız olabilecek veya beklenmeyen yükseltme veya ayrıcalıkların azaltılmasına neden olabilecek yönetilen kimlik yerine Azure CLI kimlik bilgilerini kullanmayı başlatır.

Üretim uygulamalarındaki bu tür küçük sorunları veya sessiz hataları önlemek için DefaultAzureCredential'yi TokenCredential gibi belirli bir ManagedIdentityCredential uygulamasıyla değiştirin. Kullanılabilir kimlik bilgileri için Azure Identity istemci kitaplığı belgelerine bakın.

Örneğin, bir Express.js projesinde aşağıdaki DefaultAzureCredential yapılandırmayı göz önünde bulundurun:

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

Uygulamanın çalıştığı ortama göre bir kimlik bilgisi seçmek için yukarıdaki kodu değiştirin:

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

Bu örnekte yalnızca ManagedIdentityCredential üretimde kullanılır. Daha sonra yerel geliştirme ortamının kimlik doğrulama gereksinimleri, yan tümcesinde else tanımlanan kimlik bilgileri dizisi tarafından sağlanır.

Kimlik bilgisi örneklerini yeniden kullanma

Uygulama dayanıklılığını geliştirmek ve Microsoft Entra Id'ye verilen erişim belirteci isteklerinin sayısını azaltmak için mümkün olduğunda kimlik bilgileri örneklerini yeniden kullanın. Bir kimlik bilgisi yeniden kullanıldığında, alttaki MSAL bağımlılığı tarafından yönetilen uygulama belirteci önbelleğinden bir belirteç getirme girişiminde bulunulur. Daha fazla bilgi için bkz. Azure Identity istemci kitaplığındaBelirteci önbelleğe alma.

Belirteç önbelleğe alma davranışı, tarayıcı ve Node.js ortamları arasında farklılık gösterir. Node.js uygulamalarda belirteçler varsayılan olarak bellekte önbelleğe alınır ve bu da uygulama yeniden başlatıldığında önbelleğin kaybedildiği anlamına gelir. Tarayıcı uygulamalarında, kimlik doğrulama akışına ve yapılandırmasına bağlı olarak belirteçler tarayıcı depolamasında (localStorage veya sessionStorage) kalıcı hale gelebilir. Farklı uygulama türleri için kimlik bilgisi yeniden kullanma stratejileri uygulanırken bu farkların anlaşılması önemlidir.

Önemli

Kimlik bilgilerini yeniden kullanmayan büyük ölçekli bir uygulama, Microsoft Entra ID'den gelen HTTP 429 kısıtlama yanıtlarıyla karşılaşabilir ve bu durum, uygulama kesintilerine yol açabilir.

Önerilen kimlik bilgisi yeniden kullanma stratejisi, uygulama çerçevesine göre farklılık gösterir.

JavaScript uygulamalarında kimlik bilgisi yeniden kullanımını uygulamak için tek bir kimlik bilgisi örneği oluşturun ve tüm istemci nesneleri arasında yeniden kullanın:

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

Express.js uygulamalarda, kimlik bilgilerini uygulama ayarlarında depolayabilir ve yol işleyicilerinizde erişebilirsiniz:

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

Belirteç ömrü ve önbelleğe alma mantığının ne zaman gerekli olduğunu anlama

Azure SDK istemci kitaplığı bağlamının dışında bir Azure Kimlik kitaplığı kimlik bilgisi kullanıyorsanız, uygulamanızda belirteç ömrünü ve önbelleğe alma davranışını yönetmek sizin sorumluluğunuzdadır.

refreshAfterTimestamp Tüketicilere belirteç yenilemenin ne zaman denenebileceği konusunda ipucu sağlayan AccessToken özelliği, belirteci yenilemek için Azure Core kitaplığına bağımlı Olan Azure SDK istemci kitaplıkları tarafından otomatik olarak kullanılır. Belirteç önbellekleme desteği sunan Azure Kimlik kitaplığı kimlik bilgilerinin doğrudan kullanımı için, temel alınan MSAL önbelleği refreshAfterTimestamp o anda proaktif olarak yenilenir. Bu tasarım, istemci kodunun her belirteç gerektiğinde TokenCredential.getToken() çağrısını yapmasını ve yenilemeyi kitaplığa devretmesini sağlar.

"TokenCredential.getToken()'ı yalnızca gerektiğinde çağırmak için refreshAfterTimestamp tarihini gözlemleyin ve bu tarihten sonra belirteci etkin bir şekilde yenilemeyi deneyin." Belirli bir uygulama müşteriye aittir.

Yönetilen kimlik yeniden deneme stratejisini anlama

JavaScript için Azure Kimlik kitaplığı, ManagedIdentityCredential ile yönetilen kimlik aracılığıyla kimlik doğrulaması yapmanıza olanak tanır. Kullandığınız ManagedIdentityCredential yöntem, uygulanan yeniden deneme stratejisini etkiler:

  • aracılığıyla DefaultAzureCredentialkullanıldığında, ilk belirteç alma girişimi başarısız olduğunda veya kısa bir süre sonra zaman aşımına uğradıysa yeniden deneme yapılmaz. Verimli bir geliştirme iç döngüsü için "hızlı başarısız olacak" şekilde iyileştirildiğinden bu en az dayanıklı seçenektir.
  • Başka bir yaklaşım, doğrudan ChainedTokenCredential veya ManagedIdentityCredential gibi:
    • Yeniden denemeler arasındaki zaman aralığı 0,8 saniyede başlar ve varsayılan olarak en fazla beş yeniden deneme denenir. Bu seçenek dayanıklılık için iyileştirilmiştir, ancak geliştirme iç döngüsünde istenmeyebilecek gecikmelere neden olur.
    • Varsayılan yeniden deneme ayarlarından herhangi birini değiştirmek için seçenekler parametresinde retryOptions özelliğini kullanın. Örneğin, başlangıç aralığı 0,5 saniye olacak şekilde en fazla üç kez yeniden deneyin:
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)
    }
  }
);

Yönetilen kimlik için yeniden deneme ilkelerini özelleştirme hakkında daha fazla bilgi için TokenCredentialOptions'tan genişleten aşağıdaki seçeneklerden birine bakın: