共用方式為


適用於 JavaScript 的 Azure 身分識別程式庫中的認證鏈結

Azure 身分識別程式庫提供 憑證—實作 Azure Core 程式庫 TokenCredential 介面的公用類別。 認證憑證代表從 Microsoft Entra ID 取得存取令牌的不同驗證程序。 這些憑證可以串聯在一起,以形成一個按順序嘗試的認證機制序列。

鏈結認證的運作方式

在運行時間,認證鏈結會嘗試使用序列的第一個認證進行驗證。 如果該認證無法取得存取令牌,則會嘗試序列中的下一個認證,依此方式,直到成功取得存取令牌為止。 下列順序圖說明此行為:

認證鏈結序列的圖表,顯示驗證嘗試透過多個認證進行,直到取得存取權杖為止。

為什麼使用認證鏈結

鏈結認證可以提供以下優點:

  • 環境感知:根據應用程式執行所在的環境,自動選取最適當的認證。 如果沒有它,您必須撰寫如以下的程式碼:

    import { 
        ManagedIdentityCredential, 
        AzureCliCredential 
    } from "@azure/identity";
    
    let credential;
    if (process.env.NODE_ENV === "production") {
        credential = new ManagedIdentityCredential();
    } else {
        credential = new AzureCliCredential();
    }
    
  • 順暢轉換:您的應用程式可以在不變更驗證碼的情況下,從本機開發移至預備或生產環境。

  • 提升彈性:包含一個後援機制,在前一個憑證無法取得存取權杖時會移至下一個憑證。

如何選擇鏈結認證

認證鏈結有兩種不同的方法:

  • 「拆解」鏈結:從預先設定的鏈結開始,然後剔除不需要的部分。 針對這個方法,請參閱 DefaultAzureCredential 概觀一節。
  • 「建立」鏈條:從空的鏈條開始,只包含需要的部分。 針對這個方法,請參閱 ChainedTokenCredential 概觀一節。

DefaultAzureCredential 概觀

DefaultAzureCredential 是一種經仔細設計的、預先配置的認證鏈結。 其設計目的是支援許多環境,以及最常見的驗證流程和開發人員工具。 在圖形化形式中,基礎鏈看起來像這樣:

認證鏈結序列的圖表,顯示驗證嘗試透過多個認證進行,直到取得存取權杖為止。

DefaultAzureCredential 嘗試認證的順序。

訂單 憑據 描述 預設啟用?
1 環境 讀取 環境變數的集合,以判斷應用程式服務主體(應用程式使用者)是否已為應用程式設定。 如果是,DefaultAzureCredential 使用這些值向 Azure 驗證應用程式。 此方法最常用於伺服器環境,但也可以在本機開發時使用。 Yes
2 工作負載身分識別 如果應用程式部署至已啟用工作負載識別的 Azure 主機,請驗證該帳戶。 Yes
3 受控識別 如果應用程式部署至已啟用受控識別的 Azure 主機,請使用該受控識別向 Azure 驗證應用程式。 Yes
4 Visual Studio 程式碼 如果已安裝透過Visual Studio Code的 Azure 資源延伸模組@azure/identity-vscode 套件 驗證的開發人員,請驗證該帳戶。 Yes
5 Azure CLI 如果開發人員使用 Azure CLI 的 az login 命令向 Azure 進行驗證,請使用相同的帳戶向 Azure 驗證應用程式。 Yes
6 Azure PowerShell 如果開發人員使用 Azure PowerShell 的 Connect-AzAccount Cmdlet 向 Azure 進行驗證,請使用相同的帳戶向 Azure 驗證應用程式。 Yes
7 Azure Developer CLI(開發者指令行介面) 如果開發人員使用 Azure Developer CLI 的 azd auth login 命令向 Azure 進行驗證,請使用該帳戶進行驗證。 Yes
8 Broker 使用透過訊息代理程式登入OS的預設帳戶進行驗證。 需要安裝 @azure/identity-broker 套件 Yes

最簡單的形式,您可以使用無參數版本的 DefaultAzureCredential,如下所示:

import { DefaultAzureCredential } from "@azure/identity";
import { BlobServiceClient } from "@azure/storage-blob";

// Acquire a credential object
const credential = new DefaultAzureCredential();

const blobServiceClient = new BlobServiceClient(
    `https://${storageAccountName}.blob.core.windows.net`,
    credential
);

如何自訂 DefaultAzureCredential

下列各節說明控制鏈結中包含哪些認證的策略。

排除認證類型類別

若要排除所有 Developer toolDeployed service 認證,請將環境變數 AZURE_TOKEN_CREDENTIALS 分別設定為 proddev。 使用prod值時,基礎憑證鏈如下所示:

認證鏈結序列的圖表,顯示驗證嘗試透過多個認證進行,直到取得存取權杖為止。

使用 的值 dev 時,鏈結看起來如下:

DefaultAzureCredential 鏈結的圖表,AZURE_TOKEN_CREDENTIALS設定為 'dev',顯示用於驗證的開發人員工具認證。

若要確保已定義環境變數並設定為支援的字串,請將 requiredEnvVars 屬性設定為 AZURE_TOKEN_CREDENTIALS

const credential = new DefaultAzureCredential({ 
    requiredEnvVars: [ "AZURE_TOKEN_CREDENTIALS" ]
});

使用特定認證

若要排除除了一個認證以外的所有認證,請將環境變數 AZURE_TOKEN_CREDENTIALS 設定為認證名稱。 例如,您可以將 設定為 ,以減少的DefaultAzureCredential鏈結AzureCliCredentialAZURE_TOKEN_CREDENTIALSAzureCliCredential 字串比較是以不區分大小寫的方式執行。 環境變數的有效字串值包括:

  • AzureCliCredential
  • AzureDeveloperCliCredential
  • AzurePowerShellCredential
  • EnvironmentCredential
  • ManagedIdentityCredential
  • VisualStudioCodeCredential
  • WorkloadIdentityCredential

這很重要

環境變數 AZURE_TOKEN_CREDENTIALS 支援套件 4.11.0 版和更新版本中的個別認證名稱 @azure/identity

若要確保已定義環境變數並設定為支援的字串,請將屬性 requiredEnvVars 設定為 AZURE_TOKEN_CREDENTIALS

const credential = new DefaultAzureCredential({ 
    requiredEnvVars: [ "AZURE_TOKEN_CREDENTIALS" ]
});

ChainedTokenCredential 概觀

ChainedTokenCredential 是一個空的憑證鏈,您可以在其中新增憑證以滿足應用程式的需求。 例如:

import { 
    ChainedTokenCredential, 
    AzureCliCredential, 
    VisualStudioCodeCredential 
} from "@azure/identity";

const credential = new ChainedTokenCredential(
    new AzureCliCredential(),
    new VisualStudioCodeCredential()
);

const blobServiceClient = new BlobServiceClient(
    `https://${storageAccountName}.blob.core.windows.net`,
    credential
);

上述程式碼範例會建立一條由兩個開發用認證組成的客製化認證鏈。 先嘗試 AzureCliCredential,然後視需要 VisualStudioCodeCredential。 在圖形化形式中,鏈條看起來像這樣:

認證鏈結的圖表,將 AzureCliCredential 顯示為第一次嘗試,並將 VisualStudioCodeCredential 顯示為後援。

提示

為了提升效能,請優化 ChainedTokenCredential 中的認證排序,按照從最常使用到最少使用的順序排列。

DefaultAzureCredential 的使用指引

DefaultAzureCredential 無疑是開始使用 Azure 身分識別資料庫程式庫的最簡單方式,但這種便利性也帶來了一些妥協。 將應用程式部署至 Azure 之後,您應該瞭解應用程式的驗證需求。 因此,請將 DefaultAzureCredential 取代為特定的 TokenCredential 實作,例如 ManagedIdentityCredential

原因如下:

  • 偵錯挑戰:當驗證失敗時,偵錯和識別違規認證可能會很困難。 您必須啟用記錄,才能查看從一個認證到下一個認證的進展,以及每個認證的成功/失敗狀態。 如需詳細資訊,請參閱 偵錯認證
  • 效能負擔問題:循序嘗試多個認證可能會導致效能負擔的問題。 例如,在本地開發環境中運行時,受控識別無法使用。 因此,ManagedIdentityCredential 總是在本機開發環境中失敗。
  • 無法預測的行為DefaultAzureCredential 會檢查特定環境變數是否存在。 有人有可能在主電腦上的系統層級新增或修改這些環境變數。 這些變更適用於全球範圍,因此會改變任何在該電腦上執行的應用程式中,於運行時的 DefaultAzureCredential 行為。

偵錯認證

若要診斷非預期的問題或瞭解認證的運作情況,請在您的應用程式中 啟用日誌 。 例如:

import { setLogLevel, AzureLogger } from "@azure/logger";
import { BlobServiceClient } from "@azure/storage-blob";
import { DefaultAzureCredential } from "@azure/identity";

// Constant for the Azure Identity log prefix
const AZURE_IDENTITY_LOG_PREFIX = "azure:identity";

// override logging to output to console.log (default location is stderr)
// only log messages that start with the Azure Identity log prefix
setLogLevel("verbose");
AzureLogger.log = (...args) => {
  const message = args[0];
  if (typeof message === 'string' && message.startsWith(AZURE_IDENTITY_LOG_PREFIX)) {
    console.log(...args);
  }
};

// Get storage account name from environment variable
const storageAccountName = process.env.AZURE_STORAGE_ACCOUNT_NAME;

if (!storageAccountName) {
    throw new Error("AZURE_STORAGE_ACCOUNT_NAME environment variable is required");
}

const credential = new DefaultAzureCredential({ 
    requiredEnvVars: [ "AZURE_TOKEN_CREDENTIALS" ]
});


const blobServiceClient = new BlobServiceClient(
    `https://${storageAccountName}.blob.core.windows.net`,
    credential
);
azure:identity:info EnvironmentCredential => Found the following environment variables: 
azure:identity:verbose EnvironmentCredential => AZURE_CLIENT_SEND_CERTIFICATE_CHAIN: undefined; sendCertificateChain: false
azure:identity:info WorkloadIdentityCredential => Found the following environment variables:
azure:identity:warning DefaultAzureCredential => Skipped createDefaultWorkloadIdentityCredential because of an error creating the credential: CredentialUnavailableError: WorkloadIdentityCredential: is unavailable. clientId is a required parameter. In DefaultAzureCredential and ManagedIdentityCredential, this can be provided as an environment variable - "AZURE_CLIENT_ID".
        See the troubleshooting guide for more information: https://aka.ms/azsdk/js/identity/workloadidentitycredential/troubleshoot
azure:identity:info ManagedIdentityCredential => Using DefaultToImds managed identity.
azure:identity:warning DefaultAzureCredential => Skipped createDefaultBrokerCredential because of an error creating the credential: Error: Broker for WAM was requested, but no plugin was configured or no authentication record was found. You must install the @azure/identity-broker plugin package (npm install --save @azure/identity-broker) and enable it by importing `useIdentityPlugin` from `@azure/identity` and calling useIdentityPlugin(nativeBrokerPlugin) before using enableBroker.
azure:identity:info DefaultAzureCredential => getToken() => Skipping createDefaultWorkloadIdentityCredential, reason: WorkloadIdentityCredential: is unavailable. clientId is a required parameter. In DefaultAzureCredential and ManagedIdentityCredential, this can be provided as an environment variable - "AZURE_CLIENT_ID".
        See the troubleshooting guide for more information: https://aka.ms/azsdk/js/identity/workloadidentitycredential/troubleshoot
azure:identity:info ManagedIdentityCredential => getToken() => Using the MSAL provider for Managed Identity.
azure:identity:info ManagedIdentityCredential - Token Exchange => ManagedIdentityCredential - Token Exchange: Unavailable. The environment variables needed are: AZURE_CLIENT_ID (or the client ID sent through the parameters), AZURE_TENANT_ID and AZURE_FEDERATED_TOKEN_FILE
azure:identity:info ManagedIdentityCredential => getToken() => MSAL Identity source: DefaultToImds
azure:identity:info ManagedIdentityCredential => getToken() => Using the IMDS endpoint to probe for availability.
azure:identity:info ManagedIdentityCredential - IMDS => ManagedIdentityCredential - IMDS: Pinging the Azure IMDS endpoint
azure:identity:verbose ManagedIdentityCredential - IMDS => ManagedIdentityCredential - IMDS: Caught error RestError: connect ENETUNREACH 169.254.169.254:80
azure:identity:info ManagedIdentityCredential - IMDS => ManagedIdentityCredential - IMDS: The Azure IMDS endpoint is unavailable
azure:identity:error ManagedIdentityCredential => getToken() => ERROR. Scopes: https://storage.azure.com/.default. Error message: Attempted to use the IMDS endpoint, but it is not available..
azure:identity:info AzureCliCredential => getToken() => Using the scope https://storage.azure.com/.default
azure:identity:info AzureCliCredential => getToken() => expires_on is available and is valid, using it
azure:identity:info AzureCliCredential => getToken() => SUCCESS. Scopes: https://storage.azure.com/.default.

在上述輸出中,請注意 DefaultAzureCredential 成功使用 AzureCliCredential 取得了一個權杖。