Python 用 Azure Identity クライアント ライブラリの資格情報チェーン

Azure Identity クライアント ライブラリは、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()
    
  • シームレスな移行: 認証コードを変更することなく、アプリをローカル開発からステージング環境または運用環境に移行できます。

  • 回復性の向上: 前の認証情報でアクセス トークンの取得に失敗すると次の認証情報に移る、フォールバック メカニズムが含まれています。

連結する資格情報の選択方法

資格情報の連結には、次のように 2 種類の考え方があります。

  • チェーンを "分解"する: 構成済みのチェーンから始めて、不要なものを除外します。 この方法については、「DefaultAzureCredential の概要」セクションを参照してください。
  • チェーンを "構築" する: 空のチェーンから始めて、必要なものだけを含めます。 この方法については、「ChainedTokenCredential の概要」セクションを参照してください。

DefaultAzureCredential の概要

DefaultAzureCredential は、事前構成済みの資格情報チェーンです。 これは、最も一般的な認証フローおよび開発者ツールのほか、多くの環境をサポートするように設計されています。 基になるチェーンをグラフィカルな形式で示すと、次のようになります。

DefaultAzureCredential 認証フローを示す図。

DefaultAzureCredential が資格情報を試行する順序は次のとおりです。

注文 資格情報 説明 既定で有効ですか?
1 Environment 環境変数のコレクションを読み取り、アプリケーション サービス プリンシパル (アプリケーション ユーザー) がアプリに対して構成されているかどうかを判断します。 そうであれば、DefaultAzureCredential はこれらの値を使用し、Azure に対してアプリを認証します。 この方法は、サーバー環境で最もよく使用されますが、ローカルで開発する場合も使用できます。 はい
2 ワークロード ID ワークロード ID が有効になっている Azure ホストにアプリがデプロイされている場合は、そのアカウントを認証します。 はい
3 マネージド ID マネージド ID が有効になっている Azure ホストにアプリがデプロイされている場合は、そのマネージド ID を使用してアプリを Azure に対して認証します。 はい
4 共有トークン キャッシュ 開発者が Visual Studio にログインして Azure に対する認証を行った場合は、同じアカウントを使用して Azure に対するアプリの認証を行います。 (Windows のみ。) はい
5 Azure CLI 開発者が Azure CLI の az login コマンドを使用して Azure に対する認証を行った場合は、その同じアカウントを使用して Azure に対するアプリの認証を行います。 はい
6 Azure PowerShell 開発者が Azure PowerShell の Connect-AzAccount コマンドレットを使用して Azure に対する認証を行った場合は、その同じアカウントを使用して Azure に対するアプリの認証を行います。 はい
7 Azure Developer CLI 開発者が Azure Developer CLI の azd auth login コマンドを使用して Azure に対する認証を行った場合は、そのアカウントで認証を行います。 はい
8 対話型ブラウザ 有効であれば、現在のシステムの既定のブラウザーを介し、対話形式で開発者の認証を行います。 いいえ

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 になります。 変更されたチェーンは次のようになります。

コンストラクターで exclude プレフィックス付きキーワード パラメーターを使用して環境資格情報とワークロード ID 資格情報を削除した後の DefaultAzureCredential インスタンスの認証フローを示す図。

Note

InteractiveBrowserCredential は既定で除外されるため、上の図には示されていません。 InteractiveBrowserCredential を含めるには、DefaultAzureCredential コンストラクターを呼び出すときに、exclude_interactive_browser_credential キーワード パラメーターを False に設定します。

True に設定される (資格情報の除外が構成される) exclude プレフィックス付きキーワード パラメーターの数が多くなるほど、DefaultAzureCredential を使用するメリットが小さくなります。 そのような場合は、ChainedTokenCredential を使用する方が適しており、必要なコードも少なくなります。 たとえば、次の 2 つのコード サンプルは同じように動作します。

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

上のコード サンプルでは、2 つの資格情報で構成されるカスタムの資格情報チェーンを作成しています。 まず、ManagedIdentityCredential のユーザー割り当てマネージド ID バリアントが試行され、その後で、必要に応じて AzureCliCredential が試行されます。 このチェーンをグラフィカルな形式で示すと、次のようになります。

マネージド ID 資格情報と Azure CLI 資格情報で構成される ChainedTokenCredential インスタンスの認証フローを示す図。

ヒント

パフォーマンスを向上させるには、運用環境に応じて ChainedTokenCredential の資格情報の順序を最適化します。 ローカル開発環境での使用を目的とした資格情報は、最後に追加する必要があります。

DefaultAzureCredential の使用ガイド

DefaultAzureCredential は間違いなく、もっとも簡単に Azure Identity ライブラリを使い始められる方法ですが、その便利さにはトレードオフが伴います。 アプリを Azure にデプロイしたら、アプリの認証要件を理解する必要があります。 そのため、DefaultAzureCredential から次のいずれかのソリューションへの移行の検討を強くお勧めします。

  • ManagedIdentityCredential など、特定の資格情報実装。
  • アプリを実行する Azure 環境向けに最適化されている、簡素化された ChainedTokenCredential 実装。

その理由を説明します。

  • デバッグが困難: 認証が失敗した場合、問題となっている資格情報のデバッグや特定が困難になることがあります。 1 つの資格情報から次の資格情報への進行状況や、それぞれの成功/失敗の状態を確認するには、ログ記録を有効にする必要があります。 詳細については、「連結された資格情報のデバッグ」を参照してください。
  • パフォーマンスのオーバーヘッド: 複数の資格情報を順番に試すプロセスにより、パフォーマンスのオーバーヘッドが発生する可能性があります。 たとえば、ローカル開発マシンでの実行時に、マネージド ID は使用できません。 このため、対応する exclude プレフィックス付きプロパティで明示的に無効化しない限り、ローカル開発環境では ManagedIdentityCredential が常に失敗します。
  • 予測不可能な動作: DefaultAzureCredential では、特定の環境変数の存在確認が行われます。 ホスト マシン上のシステム レベルでは、これらの環境変数の追加または変更が行われる可能性があります。 このような変更はグローバルに適用されるため、そのマシンで実行されているアプリで、DefaultAzureCredential のランタイム動作が変更されます。

連結された資格情報のデバッグ

予期しない問題を診断したり、チェーンに含まれる資格情報の動作を理解するには、アプリでログ記録を有効化します。 必要に応じて、Azure Identity クライアント ライブラリから発生したイベントのみにログを絞り込むこともできます。 次に例を示します。

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 Storage アカウントへの要求を認証したとします。 アプリはローカル開発環境で実行され、開発者は 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 が成功したため、それ以降の資格情報は試行されませんでした。

Note

前の例では、ログレベルが logging.DEBUG に設定されていました。 このログ レベルでは機密情報を出力できるため、使用する場合は注意してください。 この場合であれば、Azure における開発者のユーザー プリンシパルのクライアント ID、テナント ID、オブジェクト ID などが該当します。 わかりやすくするために、すべてのトレースバック情報が出力から削除されています。