この記事では、マネージド ID を信頼するように Microsoft Entra アプリケーションを構成する方法について説明します。 その後、アプリ シークレットを使用または管理しなくても、Microsoft Entra で保護されたリソースにアクセスできるアクセス トークンとマネージド ID トークンを交換できます。
[前提条件]
- アクティブなサブスクリプションを持つ Azure アカウント。 アカウントを無料で作成します。
- この Azure アカウントには、 アプリケーション資格情報を更新するためのアクセス許可が必要です。 以下のいずれの Microsoft Entra ロールにも、必要なアクセス許可が含まれています。
- Azure リソースのマネージド ID の概念の理解。
- ワークロードをホストする Azure コンピューティング リソース (仮想マシンや Azure App Service など) に割り当てられたユーザー割り当てマネージド ID。
- Microsoft Entra ID での アプリの登録 。 このアプリの登録は、マネージド ID と同じテナントに属している必要があります
- 別のテナントのリソースにアクセスする必要がある場合は、アプリの登録がマルチテナント アプリケーションであり、他のテナントにプロビジョニングされている必要があります。 他の テナントにマルチテナント アプリを追加する方法について説明します。
- アプリの登録には、Microsoft Entra で保護されたリソース (Azure、Microsoft Graph、Microsoft 365 など) へのアクセス権が付与されている必要があります。 このアクセスは、 API のアクセス許可 または 委任されたアクセス許可を使用して付与できます。
重要な考慮事項と制限事項
フェデレーション ID 資格情報を作成、更新、または削除するには、アクションを実行するアカウントに 、アプリケーション管理者、 アプリケーション開発者、 クラウド アプリケーション管理者、またはアプリケーション所有者ロールが必要です。 フェデレーション ID 資格情報を 更新するには、microsoft.directory/applications/credentials/update アクセス許可 が必要です。
アプリケーションまたはユーザー割り当てマネージド ID には、最大 20 個のフェデレーション ID 資格情報を追加できます。
フェデレーション ID 資格情報を構成する場合、いくつかの重要な情報を提供する必要があります。
発行者、 サブジェクト は、信頼関係を設定するために必要な重要な情報です。 Azure ワークロードが Microsoft ID プラットフォームに Entra アプリ アクセス トークンのマネージド ID トークンの交換を要求すると、フェデレーション ID 資格情報の 発行者 と サブジェクト の値が、マネージド ID トークンで指定された
issuer
およびsubject
要求に対してチェックされます。 検証チェックに合格すると、Microsoft ID プラットフォームは外部ソフトウェア ワークロードにアクセス トークンを発行します。issuer は、Microsoft Entra テナントの機関 URL の URL です (形式:
https://login.microsoftonline.com/{tenant}/v2.0
)。 Microsoft Entra アプリとマネージド ID の両方が同じテナントに属している必要があります。issuer
要求の値に先頭または末尾の空白がある場合、トークン交換はブロックされます。subject
: これは、Azure ワークロードに割り当てられているマネージド ID の オブジェクト (プリンシパル) ID の大文字と小文字が区別される GUID です。 ターゲット リソースが別のクラウドにある場合でも、マネージド ID はアプリ登録と同じテナントに存在する必要があります。 フェデレーション ID 資格情報構成のsubject
がマネージド ID のプリンシパル ID と正確に一致しない場合、Microsoft ID プラットフォームはトークン交換を拒否します。対象ユーザー は、マネージド ID トークンの
aud
要求に表示される値を指定します (必須)。 ターゲット クラウドに応じて、値は次のいずれかである必要があります。- Microsoft Entra ID グローバル サービス:
api://AzureADTokenExchange
- 米国政府の Microsoft Entra ID:
api://AzureADTokenExchangeUSGov
- 21Vianet が運営する Microsoft Entra China:
api://AzureADTokenExchangeChina
重要
別のテナント内のリソースへのアクセスがサポートされています。 別のクラウド内のリソースへのアクセスはサポートされていません。 他のクラウドへのトークン要求は失敗します。
重要
発行者に誤った情報を誤って追加した場合、フェデレーション ID 資格情報を設定する件名または対象ユーザーは、エラーなしで正常に作成されます。 このエラーは、トークン交換が失敗するまで明らかになりません。
- Microsoft Entra ID グローバル サービス:
name は、フェデレーテッドIDの資格情報における一意の識別子です。 (必須)このフィールドには 3 ~ 120 文字の文字制限があり、URL フレンドリである必要があります。 英数字、ダッシュ、またはアンダースコア文字がサポートされており、最初の文字は英数字のみである必要があります。 作成後は変更できません。
description は、フェデレーション ID 資格情報のユーザー指定の説明です (省略可能)。 説明は、Microsoft Entra ID によって検証またはチェックされません。 このフィールドの文字数は 600 文字です。
フェデレーション ID 資格情報プロパティ値では、ワイルドカード文字はサポートされていません。
アプリケーションでフェデレーション ID 資格情報を構成する
このセクションでは、マネージド ID を信頼するように既存のアプリケーションでフェデレーション ID 資格情報を構成します。 次のタブを使用して、既存のアプリケーションでフェデレーション ID 資格情報を構成する方法を選択します。
Microsoft Entra 管理センターにサインインします。 アプリケーションが登録されているテナントに存在することを確認します。
Entra ID>App 登録に移動し、メイン ウィンドウでアプリケーションを選択します。
[ 管理] で、[ 証明書とシークレット] を選択します。
[フェデレーション資格情報] タブを選択し、[ 資格情報の追加] を選択します。
[フェデレーション資格情報のシナリオ] ドロップダウンから [マネージド ID] を選択し、次の表に従って値を入力します。
フィールド 説明 例 発行者 マネージド ID トークンを発行する Microsoft Entra ID 機関の OAuth 2.0/OIDC 発行者 URL。 この値には、現在の Entra テナント発行者が自動的に設定されます。 https://login.microsoftonline.com/{tenantID}/v2.0
マネージド ID の選択 このリンクをクリックして、フェデレーション ID 資格情報として機能するマネージド ID を選択します。 User-Assigned マネージド ID は資格情報としてのみ使用できます。 msi-webapp1 説明 (省略可能) フェデレーション ID 資格情報に関するユーザー提供の説明。 ワークロード UAMI をアプリの資格情報として信頼する 聴衆 外部トークンに表示する必要がある対象ユーザーの値。 次のいずれかの値に設定する必要があります。
• Entra ID グローバル サービス: api://AzureADTokenExchange
• 米国政府の Entra ID: api://AzureADTokenExchangeUSGov
• 21Vianetが運営するエントラID中国: api://AzureADTokenExchangeChina
アクセス トークンを要求するようにアプリケーション コードを更新する
次のコード スニペットは、マネージド ID トークンを取得し、それを Entra アプリケーションの資格情報として使用する方法を示しています。 サンプルは、ターゲット リソースが Entra アプリケーションと同じテナント内にある場合と、別のテナントにある場合の両方で有効です。
Azure ID クライアント ライブラリ
次のコード サンプルは、Azure Key Vault シークレットへのアクセスを示していますが、Microsoft Entra によって保護されている任意のリソースにアクセスするように調整できます。
using Azure.Core;
using Azure.Identity;
using Azure.Security.KeyVault.Secrets;
// Audience value must be one of the below values depending on the target cloud:
// - Entra ID Global cloud: api://AzureADTokenExchange
// - Entra ID US Government: api://AzureADTokenExchangeUSGov
// - Entra ID China operated by 21Vianet: api://AzureADTokenExchangeChina
string miAudience = "api://AzureADTokenExchange";
// Create an assertion with the managed identity access token, so that it can be
// exchanged for an app token. Client ID is passed here. Alternatively, either
// object ID or resource ID can be passed.
ManagedIdentityCredential miCredential = new(
ManagedIdentityId.FromUserAssignedClientId("<YOUR_MI_CLIENT_ID>"));
TokenRequestContext tokenRequestContext = new([$"{miAudience}/.default"]);
ClientAssertionCredential clientAssertionCredential = new(
"<YOUR_RESOURCE_TENANT_ID>",
"<YOUR_APP_CLIENT_ID>",
async _ =>
(await miCredential
.GetTokenAsync(tokenRequestContext)
.ConfigureAwait(false)).Token
);
// Create a new SecretClient using the assertion
SecretClient client = new(
new Uri("https://testfickv.vault.azure.net/"),
clientAssertionCredential);
// Retrieve the secret
KeyVaultSecret secret = client.GetSecret("<SECRET_NAME>");
Microsoft.Identity.Web
Microsoft.Identity.Web では、appsettings.jsonの ClientCredentials
セクションを設定して、SignedAssertionFromManagedIdentity
を使用して、構成されたマネージド ID を資格情報としてコードで使用できるようにすることができます。
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"ClientId": "YOUR_APPLICATION_ID",
"TenantId": "YOUR_TENANT_ID",
"ClientCredentials": [
{
"SourceType": "SignedAssertionFromManagedIdentity",
"ManagedIdentityClientId": "YOUR_USER_ASSIGNED_MANAGED_IDENTITY_CLIENT_ID",
"TokenExchangeUrl": "api://AzureADTokenExchange/.default"
}
]
}
}
MSAL (.NET)
MSAL では、ManagedClientApplication クラスを使用してマネージド ID トークンを取得できます。 このトークンは、機密クライアント アプリケーションを構築するときにクライアント アサーションとして使用できます。
using Microsoft.Identity.Client;
using Microsoft.Identity.Client.AppConfig;
using Azure.Storage.Blobs;
using Azure.Core;
using Azure.Storage.Blobs.Models;
internal class Program
{
static async Task Main(string[] args)
{
string storageAccountName = "YOUR_STORAGE_ACCOUNT_NAME";
string containerName = "CONTAINER_NAME";
string appClientId = "YOUR_APP_CLIENT_ID";
string resourceTenantId = "YOUR_RESOURCE_TENANT_ID";
Uri authorityUri = new($"https://login.microsoftonline.com/{resourceTenantId}");
string miClientId = "YOUR_MI_CLIENT_ID";
string audience = "api://AzureADTokenExchange/.default";
// Get mi token to use as assertion
var miAssertionProvider = async (AssertionRequestOptions _) =>
{
var miApplication = ManagedIdentityApplicationBuilder
.Create(ManagedIdentityId.WithUserAssignedClientId(miClientId))
.Build();
var miResult = await miApplication.AcquireTokenForManagedIdentity(audience)
.ExecuteAsync()
.ConfigureAwait(false);
return miResult.AccessToken;
};
// Create a confidential client application with the assertion.
IConfidentialClientApplication app = ConfidentialClientApplicationBuilder.Create(appClientId)
.WithAuthority(authorityUri, false)
.WithClientAssertion(miAssertionProvider)
.WithCacheOptions(CacheOptions.EnableSharedCacheOptions)
.Build();
// Get the federated app token for the storage account
string[] scopes = [$"https://{storageAccountName}.blob.core.windows.net/.default"];
AuthenticationResult result = await app.AcquireTokenForClient(scopes).ExecuteAsync().ConfigureAwait(false);
TokenCredential tokenCredential = new AccessTokenCredential(result.AccessToken);
var containerClient = new BlobContainerClient(
new Uri($"https://{storageAccountName}.blob.core.windows.net/{containerName}"),
tokenCredential);
await foreach (BlobItem blob in containerClient.GetBlobsAsync())
{
// TODO: perform operations with the blobs
BlobClient blobClient = containerClient.GetBlobClient(blob.Name);
Console.WriteLine($"Blob name: {blobClient.Name}, URI: {blobClient.Uri}");
}
}
}