You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将Azure AD Authority从/tenantID改为/common后触发401未授权错误

Blazor WASM Azure静态Web应用切换到common Authority后API调用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 13:01:05