Blazor Client/Server发布后AAD认证报audience无效错误排查
Blazor 发布后AAD鉴权报audience无效问题排查
问题背景
- 解决方案包含Client、Server、Shared三个Blazor项目,本地开发环境对接Azure Active Directory实现O365企业账号登录,基于Visual Studio默认AAD认证模板开发,已完成App注册、重定向URI配置、API访问权限授权,配置文件中Tenant ID、Client ID等参数填写正确,本地调试时客户端、服务端鉴权逻辑全部正常。
- 项目发布到服务器后,客户端登录流程正常、已认证用户信息展示正常,但所有标记
[Authorize]特性的服务端Web API接口全部调用失败,返回错误:
Bearer error="invalid_token", error_description="The audience 'api://xxxetc' is invalid"
- 已对比本地、线上环境获取的令牌,issuer、audience等参数完全一致;服务端App注册清单未配置
accessTokenAcceptedVersion属性;已尝试在配置中增删api://前缀测试,问题未解决。 - 确认服务端App注册的Client ID与配置中
api://前缀对应的ID完全匹配,所有ID参数配置符合要求,客户端、服务端应用注册均已授予对应scope的API权限,线上发布包配置与本地正常运行版本完全一致。
现有配置片段
客户端 appsettings 配置
"AzureAd": { "Authority": "https://login.microsoftonline.com/xxxxx", "ClientId": "971f156e-xxxetc", "ValidateAuthority": true }
客户端 Program.cs 鉴权相关代码
builder.Services.AddHttpClient("ProjectName.ServerAPI", client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)) .AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>(); builder.Services.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>().CreateClient("ProjectName.ServerAPI")); builder.Services.AddMsalAuthentication(options => { builder.Configuration.Bind("AzureAd", options.ProviderOptions.Authentication); options.ProviderOptions.LoginMode = "Redirect"; options.ProviderOptions.DefaultAccessTokenScopes.Add("api://4f7ef7bbxxxetc/API.Access"); });
服务端 appsettings 配置
"AzureAd": { "Instance": "https://login.microsoftonline.com/", "Domain": "companyname.com", "TenantId": "273a37a4-etc", "ClientId": "4f7ef7bb-etc", "Scopes": "API.Access", "CallbackPath": "/signin-oidc" }
服务端 Program.cs 鉴权相关代码
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));
排查与解决步骤
按优先级从高到低排查:
- 确认服务端生产环境配置实际加载值
本地调试默认读取appsettings.Development.json,发布后默认读取生产环境配置文件,最常见问题是仅修改了基础appsettings.json,未更新appsettings.Production.json,或发布时配置文件被旧版本覆盖,导致服务端实际读取的AzureAd:ClientId与预期不符,令牌audience校验失败。
排查方式:临时新增一个无鉴权的测试接口,直接输出builder.Configuration["AzureAd:ClientId"]的运行时值,确认该值为服务端App注册的纯GUID格式Client ID,无api://前缀。 - 显式配置accessTokenAcceptedVersion属性
服务端App注册清单中accessTokenAcceptedVersion未配置时默认值为null,对应v1.0令牌校验逻辑,仅认可GUID格式的audience;当前获取的令牌audience为api://<GUID>格式,属于v2.0令牌,会直接校验失败。
操作步骤:进入服务端AAD App注册的清单编辑页面,将accessTokenAcceptedVersion的值显式设置为2,保存后等待10-15分钟等待AAD全局配置生效。
也可以在服务端鉴权代码中显式添加合法audience规则,兼容两种格式的令牌,避免配置不匹配问题:builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApi(options => { builder.Configuration.Bind("AzureAd", options); var clientId = builder.Configuration["AzureAd:ClientId"]; options.TokenValidationParameters.ValidAudiences = new[] { clientId, $"api://{clientId}" }; }, msalOptions => { builder.Configuration.Bind("AzureAd", msalOptions); }); - 确认服务端公开API的应用ID URI配置
进入服务端AAD App注册的「公开API」页面,确认「应用程序ID URI」的值与客户端配置的scope前缀完全一致,即必须为api://4f7ef7bbxxxetc,如果配置为带自定义域名的格式(如api://companyname.com/4f7ef7bbxxxetc),会导致audience不匹配。本地正常可能是因为本地缓存了旧令牌,清理本地令牌缓存后重新登录也会复现问题。 - 排查反向代理/网关的请求头转发问题
如果服务端前部署了IIS、Nginx反向代理或WAF网关,确认已正确转发Authorization请求头,未对Bearer令牌做篡改或截断。可在服务端中间件中打印实际收到的令牌,解析其aud字段与预期值对比。
注意:每次修改AAD配置或应用配置后,必须清理浏览器缓存、客户端MSAL令牌缓存,重新走完整登录流程获取新令牌测试,避免旧缓存令牌干扰排查结果。
内容的提问来源于stack exchange,提问作者Irma Nohere
相关产品推荐
相关产品推荐

