将Azure AD Authority从/tenantID改为/common后触发401未授权错误
问题背景
- 环境:Blazor WASM Azure静态Web应用,对接Azure AD保护的ASP.NET Core API,已配置Microsoft Account和一次性密码IDP
- 初始状态:仅租户内MS账号可正常调用API受保护端点,非租户MS账号登录时触发AADSTS50020错误
- 修改操作:将Authority从
https://login.microsoftonline.com/<YourTenantNameOrID>改为https://login.microsoftonline.com/common - 当前问题:所有用户可登录,但调用API受保护端点均返回401未授权,WWW-Authenticate头显示
Bearer error="invalid_token", error_description="The signature is invalid"
附加异常现象
- 一次性密码登录选项消失,常用MS账号不再自动提示
- Token字段验证:
aud为API客户端ID,scp包含所需的access_as_user范围
应用注册清单信息
API应用清单片段
... "oauth2AllowIdTokenImplicitFlow": true, "oauth2AllowImplicitFlow": false, ... "oauth2Permissions": [ { "adminConsentDescription": "Allows the app to access the web API on behalf of the signed-in user", "adminConsentDisplayName": "Access the API on behalf of a user", "id": "<access_as_user scope id>", "isEnabled": true, "lang": null, "origin": "Application", "type": "User", "userConsentDescription": "Allows this app to access the web API on your behalf", "userConsentDisplayName": "Access the API on your behalf", "value": "access_as_user" } ], ... "signInAudience": "AzureADandPersonalMicrosoftAccount", ...
客户端应用清单片段
... "oauth2AllowIdTokenImplicitFlow": true, "oauth2AllowImplicitFlow": true, ... "requiredResourceAccess": [ ... { "resourceAppId": "<api client id>", "resourceAccess": [ { "id": "<access_as_user scope id>", "type": "Scope" } ] } ], ... "signInAudience": "AzureADandPersonalMicrosoftAccount", ...
解决方案
1. 修正API的JWT验证配置
ASP.NET Core API需明确信任common租户及个人微软账号的Issuer,更新认证配置:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApi(options => { Configuration.Bind("AzureAd", options); // 允许common和租户特定的Issuer options.TokenValidationParameters.ValidIssuers = new[] { $"https://login.microsoftonline.com/{Configuration["AzureAd:TenantId"]}/v2.0", "https://login.microsoftonline.com/common/v2.0" }; // 使用Microsoft官方的Issuer验证器处理多场景 options.TokenValidationParameters.IssuerValidator = AadIssuerValidator.GetIssuerValidator(options.Instance, options.TenantId).Validate; }, options => Configuration.Bind("AzureAd", options));
同时确保appsettings.json中的AzureAd配置TenantId设为common:
"AzureAd": { "Instance": "https://login.microsoftonline.com/", "TenantId": "common", "ClientId": "<API Client ID>" }
2. 确认API的权限范围配置
在Azure AD门户的API应用注册中,进入「公开API」页面:
- 找到
access_as_user范围,将「谁能同意?」设置为「每个人(包括组织外部的用户)」 - 确保范围状态为「已启用」
3. 调整Blazor WASM客户端的认证配置
客户端需明确指定v2端点和完整的API范围:
builder.Services.AddMsalAuthentication(options => { builder.Configuration.Bind("AzureAd", options.ProviderOptions.Authentication); options.ProviderOptions.Authority = "https://login.microsoftonline.com/common/v2.0"; // 使用完整的范围格式:api://{API Client ID}/scope-name options.ProviderOptions.DefaultAccessTokenScopes.Add("api://<api client id>/access_as_user"); });
4. 恢复一次性密码和账号自动提示
在客户端应用注册的「身份验证」->「高级设置」中:
- 勾选「将应用视为公共客户端」
- 在MSAL配置中添加
prompt参数强制显示账号选择界面:
options.ProviderOptions.AdditionalQueryParameters.Add("prompt", "select_account");
5. 验证Token合法性
本地解析Token确认:
iss字段为https://login.microsoftonline.com/common/v2.0或对应租户的v2端点azp或appid为客户端应用ID- 确保Token未过期,签名算法为RS256
内容的提问来源于stack exchange,提问作者aes
相关产品推荐
相关产品推荐

