共用方式為


適用於 Python 的 Azure 身分識別用戶端連結庫中的認證鏈結

Azure 身分識別客戶端連結庫提供 認證-公用類別,可實作 Azure Core 連結庫的 TokenCredential 通訊 協定。 認證代表從 Microsoft Entra ID 取得存取權杖的不同驗證流程。 這些認證可以鏈結在一起,形成一個經過排序的驗證機制以進行嘗試。

鏈結認證的運作方式

在執行階段,認證鏈會嘗試使用序列的第一個憑證進行驗證。 如果該認證無法取得存取權杖,則會嘗試序列中的下一個認證,以此類推,直到成功取得存取權杖為止。 以下序列圖表說明這項行為:

顯示認證鏈結順序的圖表。

為什麼使用認證鏈結

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

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

    # Set up credential based on environment (Azure or local development)
    if os.getenv("WEBSITE_HOSTNAME"):
        credential = ManagedIdentityCredential(client_id=user_assigned_client_id)
    else:
        credential = AzureCliCredential()
    
  • 順暢轉換:您的應用程式可以在不變更驗證碼的情況下,從本機開發移至預備或生產環境。

  • 提升復原能力:包含一個後援機制,在前一個認證無法取得存取權杖時移至下一個認證。

如何選擇鏈結認證

認證鏈結有兩種不同的原理:

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

DefaultAzureCredential 概觀

DefaultAzureCredential 是固有、預先設定的認證鏈結。 其設計目的是支援多種環境,以及最常見的驗證流程和開發人員工具。 在圖形化表單中,基礎的鏈結看起來如下:

顯示 DefaultAzureCredential 驗證流程的圖表。

DefaultAzureCredential 嘗試認證時依照的順序。

順序 認證 描述 預設啟用?
1 環境 讀取環境變數集合,以判斷應用程式服務主體(應用程式使用者)是否已為應用程式設定。 如是,DefaultAzureCredential 則會使用這些值向 Azure 驗證應用程式。 此方法最常用於伺服器環境,但也可在本機開發時使用。 Yes
2 工作負載身分識別 如果應用程式部署到已啟用工作負載身分識別的 Azure 主機,請驗證該帳戶。 Yes
3 受控識別 如果應用程式部署到已啟用受控識別的 Azure 主機,則使用該受控識別將應用程式驗證至 Azure。 Yes
4 共用令牌快取 只有在 Windows 上,如果開發人員透過登入 Visual Studio 向 Azure 進行驗證,請使用相同的帳戶向 Azure 驗證應用程式。 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 互動式瀏覽器 如果啟用,則透過目前系統的預設瀏覽器以互動方式驗證開發人員。 No

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

from azure.identity import DefaultAzureCredential
from azure.storage.blob import BlobServiceClient

# Acquire a credential object
credential = DefaultAzureCredential()

blob_service_client = BlobServiceClient(
    account_url="https://<my_account_name>.blob.core.windows.net",
    credential=credential
)

如何自訂 DefaultAzureCredential

若要從 DefaultAzureCredential移除認證,請使用對應的 exclude前置 詞關鍵詞參數。 例如:

credential = DefaultAzureCredential(
    exclude_environment_credential=True, 
    exclude_workload_identity_credential=True,
    managed_identity_client_id=user_assigned_client_id
)

在上述程式碼範例中,從認證鏈結中移除 EnvironmentCredentialWorkloadIdentityCredential。 因此,第一個嘗試的認證是 ManagedIdentityCredential。 修改後的鏈結看起來如下:

此圖顯示 DefaultAzureCredential 實例在建構函式中使用排除前置關鍵詞參數來移除環境認證和工作負載身分識別認證的驗證流程。

注意

InteractiveBrowserCredential 預設為排除 ,因此沒有顯示在上列圖表中。 若要包含 InteractiveBrowserCredential,請在呼叫建構函式時, exclude_interactive_browser_credential 將 關鍵詞參數設定為 False DefaultAzureCredential

由於已將更多 exclude前置關鍵詞參數設定為 True (已設定認證排除專案),因此使用 DefaultAzureCredential 減少的優點。 在這種情況下,ChainedTokenCredential 是比較好的選擇,且需要較少的程序碼。 為了方便說明,這兩個程式碼範例有相同的行為:

credential = DefaultAzureCredential(
    exclude_environment_credential=True,
    exclude_workload_identity_credential=True,
    exclude_shared_token_cache_credential=True,
    exclude_azure_powershell_credential=True,
    exclude_azure_developer_cli_credential=True,
    managed_identity_client_id=user_assigned_client_id
)

ChainedTokenCredential 概觀

ChainedTokenCredential 是一個空的鏈結,您可以根據自己的應用程式需求加入認證。 例如:

credential = ChainedTokenCredential(
    ManagedIdentityCredential(client_id=user_assigned_client_id),
    AzureCliCredential()
)

上述程式碼範例將建立由兩個認證組成的自訂認證鏈結。 如有必要,會先嘗試的使用者指派的 ManagedIdentityCredential 的受控識別變體,然後嘗試 AzureCliCredential。 在圖形化表單中,鏈結看起來如下:

此圖顯示由受控識別認證和 Azure CLI 認證所組成的 ChainedTokenCredential 實例驗證流程。

提示

為提升效能,請根據您的生產環境將 ChainedTokenCredential 中的認證順序最佳化。 要用於本機開發環境的認證應該在最後加入。

DefaultAzureCredential 的使用方式指導

DefaultAzureCredential 無疑是開始使用 Azure 身分識別用戶端連結庫的最簡單方式,但利用這種便利性來取捨。 將應用程式部署至 Azure 之後,您應該了解應用程式的驗證需求。 基於這個理由,強烈建議您從 DefaultAzureCredential 改用下列其中一個解決方案:

  • 特定認證實作, 例如 ManagedIdentityCredential
  • 針對您執行應用程式的 Azure 環境最佳化的簡化 ChainedTokenCredential 實作。

原因如下:

  • 偵錯困難:當驗證失敗時,偵錯和找出不符規定的認證可能會很困難。 您必須啟用記錄,才能逐一查看每個認證的進展,以及每個認證的成功/失敗狀態。 如需詳細資訊,請參閱偵錯鏈結認證
  • 過度效能負荷:循序嘗試多個認證的過程可能會造成效能負荷。 例如,在本機開發電腦上執行時,無法使用受控識別。 因此,ManagedIdentityCredential 在本機開發環境中會總是失敗,除非透過相應的 exclude 前置屬性明確停用。
  • 無法預測的行為DefaultAzureCredential 會檢查特定環境變數是否存在。 有人可能會在主機電腦上的系統層級新增或修改這些環境變數。 這些變更會全域套用,並因此改變 DefaultAzureCredential 在該電腦上執行的所有應用程式中的執行階段行為。

偵錯鏈結認證

若要診斷意外的問題,或是了解鏈結認證正在執行的動作,請在您的應用程式中啟用記錄。 選擇性地將記錄篩選為僅從 Azure 身分識別用戶端連結庫發出的那些事件。 例如:

import logging
from azure.identity import DefaultAzureCredential

# Set the logging level for the Azure Identity library
logger = logging.getLogger("azure.identity")
logger.setLevel(logging.DEBUG)

# Direct logging output to stdout. Without adding a handler,
# no logging output is visible.
handler = logging.StreamHandler(stream=sys.stdout)
logger.addHandler(handler)

# Optional: Output logging levels to the console.
print(
    f"Logger enabled for ERROR={logger.isEnabledFor(logging.ERROR)}, "
    f"WARNING={logger.isEnabledFor(logging.WARNING)}, "
    f"INFO={logger.isEnabledFor(logging.INFO)}, "
    f"DEBUG={logger.isEnabledFor(logging.DEBUG)}"
)

為了說明目的,假設的無參數形式 DefaultAzureCredential 是用來向 Blob 記憶體帳戶驗證要求。 應用程式會在本機開發環境中執行,並使用 Azure CLI 向 Azure 驗證的開發人員。 也假設記錄層級設定為 logging.DEBUG。 執行應用程式時,輸出中會出現下列相關專案:

Logger enabled for ERROR=True, WARNING=True, INFO=True, DEBUG=True
No environment configuration found.
ManagedIdentityCredential will use IMDS
EnvironmentCredential.get_token failed: EnvironmentCredential authentication unavailable. Environment variables are not fully configured.
Visit https://aka.ms/azsdk/python/identity/environmentcredential/troubleshoot to troubleshoot this issue.
ManagedIdentityCredential.get_token failed: ManagedIdentityCredential authentication unavailable, no response from the IMDS endpoint.     
SharedTokenCacheCredential.get_token failed: SharedTokenCacheCredential authentication unavailable. No accounts were found in the cache.
AzureCliCredential.get_token succeeded
[Authenticated account] Client ID: 00001111-aaaa-2222-bbbb-3333cccc4444. Tenant ID: aaaabbbb-0000-cccc-1111-dddd2222eeee. User Principal Name: unavailableUpn. Object ID (user): aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb
DefaultAzureCredential acquired a token from AzureCliCredential

在上列輸出結果中,請注意:

  • EnvironmentCredentialManagedIdentityCredentialSharedTokenCacheCredential (按照順序) 皆無法取得 Microsoft Entra 存取權杖。
  • 呼叫 AzureCliCredential.get_token 成功,而且輸出也表示 DefaultAzureCredentialAzureCliCredential取得令牌。 因為 AzureCliCredential 成功,所以未嘗試超過認證。

注意

在上述範例中,記錄層級會設定為 logging.DEBUG。 使用此記錄層級時請小心,因為它可以輸出敏感性資訊。 例如,在此情況下,用戶端標識碼、租使用者標識碼,以及 Azure 中開發人員用戶主體的物件識別碼。 為了清楚起見,所有追蹤資訊都已從輸出中移除。