エラーメッセージ
IDX10214: Audience validation failed.
別の表記
- IDX10214: Audience validation failed. Audiences: 'api://billing'. Did not match: validationParameters.ValidAudience: 'api://orders' or validationParameters.ValidAudiences: 'null'.
- Bearer error="invalid_token", error_description="The audience 'api://billing' is invalid"
8.x ではテキストが「IDX10214: Audience validation failed. See https://aka.ms/identitymodel/app-context-switches 」に短縮されています。6.x と 7.x(6.36.0 と 7.7.1 で確認)は、トークンのオーディエンスと設定された値を列挙します。ASP.NET Core は `error_description="The audience '…' is invalid"` を送信します。
Microsoft.IdentityModel.Tokens (.NET) — SecurityTokenInvalidAudienceException
このエラーの意味
トークンの `aud` が `ValidAudience` / `ValidAudiences`(`JwtBearerOptions` で `Audience` を設定している場合はその値)と一致しません。署名には問題がなく、トークンが別の受信者向けに発行されています。Microsoft Entra ID での典型的な不一致は、API のアプリケーション ID URI(`api://…`、v1 トークンで使用)とクライアント ID の GUID(v2 トークンで使用)の間で起こります。
発生する理由
アプリケーション ID URI とクライアント ID の違い
よくあるEntra ID は、API のマニフェストが v2.0 トークンを要求している場合(`requestedAccessTokenVersion: 2`。古いマニフェスト形式では `accessTokenAcceptedVersion`)は `aud` にクライアント ID を入れ、v1.0 トークンではアプリケーション ID URI を入れます。どちらか一方しか設定していない API は、もう一方を拒否します。
クライアントが別の API 向けのトークンを要求した
よくあるオーディエンスはスコープによって決まります。`User.Read` を要求したクライアントは Microsoft Graph 用のトークン(`aud` = `https://graph.microsoft.com` または `00000003-0000-0000-c000-000000000000`)を受け取りますが、このトークンは自分の API では拒否しなければなりません。
ID トークンや Graph トークンを転送している
ときどきフロントエンドが、すでに保持している ID トークン(オーディエンスはクライアントアプリ)や Graph トークンを送ってしまうことがあります。どちらも自分の API 向けのものではありません。
修正方法
- 1.
API の識別子を明示的に列挙する
両方のバージョンのトークンを使っている場合は、自分の API のクライアント ID とアプリケーション ID URI を受け入れ、それ以外は受け入れないでください。
csharp options.TokenValidationParameters = new TokenValidationParameters { ValidIssuer = "https://login.microsoftonline.com/<tenant-id>/v2.0", // Entra ID v2 tokens carry the client ID; v1 tokens the App ID URI. Accept exactly your API's identifiers. ValidAudiences = ["00000000-0000-0000-0000-000000000000", "api://orders"], }; - 2.
自分の API のスコープを要求する
`api://orders/Orders.Read` 用のトークンでは、オーディエンスが自分の API になります。アプリの登録でスコープを公開し、クライアントにそのスコープを要求させてください。
csharp // Client: request a scope of YOUR API, not Microsoft Graph, so aud is your API. var result = await app.AcquireTokenSilent(new[] { "api://orders/Orders.Read" }, account).ExecuteAsync();