.NET 用 Azure ID ライブラリを使用した認証のベスト プラクティス
この記事では、Azure サービスに対する認証時に .NET アプリのパフォーマンスと信頼性を最大限に高めるのに役立つガイドラインを提供します。 .NET 用の Azure Identity ライブラリを最大限に活用するには、潜在的な問題と軽減手法を理解することが重要です。
運用環境で確定的な資格情報を使用する
DefaultAzureCredential
は Azure Identity ライブラリを使い始めるのに最も近い方法ですが、その便利さにも特定のトレードオフが生じます。 最も顕著なのは、チェーン内で成功し、要求認証に使用される特定の資格情報を事前に保証することはできません。 運用環境では、この予測不能性により、重大で、時には微妙な問題が発生する可能性があります。
たとえば、次の架空の一連のイベントについて考えてみます。
- 組織のセキュリティ チームは、すべてのアプリでマネージド ID を使用して Azure リソースに対する認証を行う必要があります。
- 数か月間、Azure 仮想マシン (VM) でホストされている .NET アプリは、マネージド ID を介して認証するために
DefaultAzureCredential
を正常に使用します。 - サポート チームに指示することなく、開発者はその VM に Azure CLI をインストールし、
az login
コマンドを実行して Azure に対して認証します。 - Azure 環境での個別の構成変更により、元のマネージド ID を介した認証が予期せずサイレントモードで失敗し始めます。
DefaultAzureCredential
失敗したManagedIdentityCredential
をスキップし、次に使用可能な資格情報 (AzureCliCredential
) を検索します。- アプリケーションでは、マネージド ID ではなく Azure CLI 資格情報の使用が開始され、失敗したり、予期しない昇格や特権の削減が発生したりする可能性があります。
運用環境のアプリでこのような種類の微妙な問題やサイレント エラーが発生するのを防ぐには、DefaultAzureCredential
を特定の TokenCredential
実装 (ManagedIdentityCredential
など) に置き換えます。 オプションについては、派生 の一覧 を参照してください。
たとえば、ASP.NET Core プロジェクトで次の DefaultAzureCredential
構成を考えてみましょう。
builder.Services.AddAzureClients(clientBuilder =>
{
clientBuilder.AddSecretClient(
new Uri($"https://{keyVaultName}.vault.azure.net"));
clientBuilder.AddBlobServiceClient(
new Uri($"https://{storageAccountName}.blob.core.windows.net"));
DefaultAzureCredential credential = new();
clientBuilder.UseCredential(credential);
});
上記のコードを変更して、アプリが実行されている環境に基づいて資格情報を選択します。
builder.Services.AddAzureClients(clientBuilder =>
{
clientBuilder.AddSecretClient(
new Uri($"https://{keyVaultName}.vault.azure.net"));
clientBuilder.AddBlobServiceClient(
new Uri($"https://{storageAccountName}.blob.core.windows.net"));
TokenCredential credential;
if (builder.Environment.IsProduction() || builder.Environment.IsStaging())
{
string? clientId = builder.Configuration["UserAssignedClientId"];
credential = new ManagedIdentityCredential(
ManagedIdentityId.FromUserAssignedClientId(clientId));
}
else
{
// local development environment
credential = new ChainedTokenCredential(
new VisualStudioCredential(),
new AzureCliCredential(),
new AzurePowerShellCredential());
}
clientBuilder.UseCredential(credential);
});
この例では、運用環境では ManagedIdentityCredential
のみが使用されます。 その後、ローカル開発環境の認証ニーズは、else
句で定義されている資格情報のシーケンスによって処理されます。
資格情報インスタンスを再利用する
可能な限り資格情報インスタンスを再利用して、アプリの回復性を向上させ、Microsoft Entra ID に発行されるアクセス トークン要求の数を減らします。 資格情報が再利用されると、基になる MSAL 依存関係によって管理されるアプリ トークン キャッシュからトークンをフェッチしようとします。 詳細については、「Azure Identity クライアント ライブラリの トークン キャッシュ」を参照してください。
重要
資格情報を再利用しない大量のアプリでは、Microsoft Entra ID からの HTTP 429 調整応答が発生し、アプリが停止する可能性があります。
推奨される資格情報の再利用戦略は、.NET アプリケーションの種類によって異なります。
資格情報の再利用を実装するには、Microsoft.Extensions.Azure
の UseCredential メソッドを使用します。 運用環境とステージング環境の両方で Azure App Service でホストされている ASP.NET Core アプリについて考えてみましょう。 環境変数 ASPNETCORE_ENVIRONMENT
は、これら 2 つの非開発環境を区別するために Production
または Staging
に設定されます。 運用環境とステージング環境の両方で、ManagedIdentityCredential
のユーザー割り当てバリアントを使用して、Key Vault シークレットと Blob Storage クライアントを認証します。
ASPNETCORE_ENVIRONMENT
が Development
に設定されているローカル開発マシンでアプリを実行すると、代わりにチェーンされた一連の開発者ツール資格情報が使用されます。 この方法により、環境に適した資格情報が使用され、セキュリティが強化され、資格情報の管理が簡素化されます。
builder.Services.AddAzureClients(clientBuilder =>
{
clientBuilder.AddSecretClient(
new Uri($"https://{keyVaultName}.vault.azure.net"));
clientBuilder.AddBlobServiceClient(
new Uri($"https://{storageAccountName}.blob.core.windows.net"));
TokenCredential credential;
if (builder.Environment.IsProduction() || builder.Environment.IsStaging())
{
string? clientId = builder.Configuration["UserAssignedClientId"];
credential = new ManagedIdentityCredential(
ManagedIdentityId.FromUserAssignedClientId(clientId));
}
else
{
// local development environment
credential = new ChainedTokenCredential(
new VisualStudioCredential(),
new AzureCliCredential(),
new AzurePowerShellCredential());
}
clientBuilder.UseCredential(credential);
});
ASP.NET Core アプリでのこの方法については、「Microsoft Entra IDを使用した認証」を参照してください。
トークンの有効期間とキャッシュ ロジックが必要なタイミングを理解する
Azure Core に依存する Azure SDK クライアント ライブラリコンテキスト外で Azure ID ライブラリの資格情報を使用する場合は、トークンの有効期間の とキャッシュ動作をアプリで管理する必要があります。
RefreshOnの AccessToken
プロパティは、トークンの更新を試みることができるタイミングに関するヒントをコンシューマーに提供します。これは、トークンを更新するために Azure Core ライブラリに依存する Azure SDK クライアント ライブラリによって自動的に使用されます。 トークン キャッシュ をサポートする資格情報Azure ID ライブラリを直接使用する場合、基になる MSAL キャッシュは、RefreshOn
時間が発生したときに自動的に事前に更新されます。 この設計により、クライアント コードはトークンが必要なたびに GetToken
を呼び出し、ライブラリに更新を委任できます。
必要な場合にのみ GetToken
を呼び出すには、RefreshOn
の日付を確認し、その後に事前にトークンの更新を試みます。 具体的な実装はお客様が行います。
マネージド ID の再試行戦略を理解する
.NET 用 Azure Identity ライブラリを使用すると、ManagedIdentityCredential
を使用してマネージド ID を使用して認証できます。 ManagedIdentityCredential
を使用する方法は、適用された再試行戦略に影響します。 次の方法で使用する場合:
DefaultAzureCredential
、最初のトークン取得の試行が失敗した場合や、短い期間が経過した後にタイムアウトになった場合、再試行は試行されません。 これは、効率的な開発内部ループのために "高速に失敗" するように最適化されているため、最も回復力の低いオプションです。ChainedTokenCredential
やManagedIdentityCredential
のような他の方法としては、直接的なものがあります。再試行の間隔は 0.8 秒から始まり、既定では最大 5 回の再試行が試行されます。 このオプションは回復性のために最適化されていますが、開発内部ループで望ましくない可能性のある遅延が発生します。
既定の再試行設定を変更するには、
Retry
のManagedIdentityCredentialOptions
プロパティを使用します。 たとえば、最大 3 回再試行し、開始間隔は 0.5 秒です。ManagedIdentityCredentialOptions miCredentialOptions = new( ManagedIdentityId.FromUserAssignedClientId(clientId) ) { Retry = { MaxRetries = 3, Delay = TimeSpan.FromSeconds(0.5), } }; ManagedIdentityCredential miCredential = new(miCredentialOptions);
再試行ポリシーのカスタマイズの詳細については、「カスタム再試行ポリシーの設定」を参照してください。
.NET