AzureAD受众验证失败:API令牌aud不匹配问题求助
解决Azure AD令牌受众验证失败问题(IDX10214)
问题概述
调用端通过托管身份从Azure AD获取访问令牌,令牌已包含被调用API应用注册定义的应用角色,但调用目标API时触发受众验证失败错误:
IDX10214: Audience validation failed. Audiences: '{被调用API应用注册的ClientId}'. Did not match: validationParameters.ValidAudience: 'api://{被调用API应用注册的ClientId}' or validationParameters.ValidAudiences: 'null'.
令牌中的aud声明为API的ClientId(无前缀),但API验证配置中使用的是带api://前缀的受众值,两者不匹配导致验证失败。
现有配置与代码
被调用API的AzureAd配置
{ "AzureAd": { "Instance": "https://login.microsoftonline.com/", "ClientId": "与应用注册Application ID匹配的Guid", "TenantId": "我的租户ID", "Audience": "api://{与应用注册Application ID匹配的Guid}" } }
Program.cs核心代码
using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Identity.Web; using Microsoft.IdentityModel.Logging; var builder = WebApplication.CreateBuilder(args); IdentityModelEventSource.ShowPII = true; builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd")); // 其余服务注册与中间件配置略...
控制器排查代码片段
[HttpGet()] //[Authorize(Roles = "Api.Read,Api.ReadWrite,Api.OtherUserApp")] public async Task<IActionResult> GetNames() { AuthenticateResult authResult; try { authResult = await HttpContext.AuthenticateAsync("Bearer"); } catch (Exception ex) { var innerException = ex.InnerException != null ? ex.InnerException.Message : string.Empty; var responseString = $"认证出错: {ex.Message} {innerException}."; return StatusCode(500, responseString); } try { HttpContext.ValidateAppRole("Api.OtherUserApp"); return Ok(Data.NameList); } catch (Exception ex) { // 错误日志与返回逻辑略... } }
解决方案
方案1:让API接受两种合法受众
修改AddMicrosoftIdentityWebApi的配置,添加无前缀的ClientId作为额外合法受众:
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"), options => { // 同时允许带前缀的应用URI和无前缀的ClientId作为受众 options.TokenValidationParameters.ValidAudiences = new[] { builder.Configuration["AzureAd:Audience"], builder.Configuration["AzureAd:ClientId"] }; });
方案2:调整应用注册,让令牌返回带前缀的受众
- 登录Azure门户,进入被调用API的应用注册页面
- 切换到公开API标签,至少定义一个作用域(即使不需要用户同意)
- 确保应用URI为
api://{ClientId}并保存 - 调用端获取令牌时,使用完整的应用URI作为资源(例如
api://{ClientId}/.default)
方案3:直接修改Audience配置为ClientId
如果业务不需要api://前缀的受众,直接将配置中的Audience改为API的ClientId:
{ "AzureAd": { // ...其他配置 "Audience": "{与应用注册Application ID匹配的Guid}" } }
补充说明
当使用托管身份获取令牌时,若API应用注册未定义任何作用域,Azure AD默认会将ClientId作为aud声明返回;若定义了作用域,令牌的aud则会是完整的应用URI(带api://前缀)。可根据实际场景选择适配方案。
内容的提问来源于stack exchange,提问作者AngryToddlers
相关产品推荐
相关产品推荐

