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 tool 或 Deployed service 認證,請將環境變數 AZURE_TOKEN_CREDENTIALS 分別設定為 prod 或 dev。 使用prod值時,基礎憑證鏈如下所示:
使用 的值 dev 時,鏈結看起來如下:
若要確保已定義環境變數並設定為支援的字串,請將 requiredEnvVars 屬性設定為 AZURE_TOKEN_CREDENTIALS:
const credential = new DefaultAzureCredential({
requiredEnvVars: [ "AZURE_TOKEN_CREDENTIALS" ]
});
使用特定認證
若要排除除了一個認證以外的所有認證,請將環境變數 AZURE_TOKEN_CREDENTIALS 設定為認證名稱。 例如,您可以將 設定為 ,以減少的DefaultAzureCredential鏈結AzureCliCredential。AZURE_TOKEN_CREDENTIALSAzureCliCredential 字串比較是以不區分大小寫的方式執行。 環境變數的有效字串值包括:
AzureCliCredentialAzureDeveloperCliCredentialAzurePowerShellCredentialEnvironmentCredentialManagedIdentityCredentialVisualStudioCodeCredentialWorkloadIdentityCredential
這很重要
環境變數 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。 在圖形化形式中,鏈條看起來像這樣:
提示
為了提升效能,請優化 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 取得了一個權杖。