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

Azure APIM验证MSAL-Angular访问令牌调用Node.js API时遇401错误

Azure B2C + APIM 令牌验证401问题排查

我已配置带登录流的B2C租户,尝试在Azure API Management(APIM)中验证从msal-angular获取的访问令牌,调用Node.js API时始终返回401未授权错误。怀疑和范围(scopes)配置有关,但不确定具体原因——明明已经在B2C里设置了暴露的API并定义了范围,却还是无法用有效令牌访问API端点。

Angular应用代码:

let request = {
  scopes: ['<tenantname>.onmicrosoft.com/<clientId>/access_as_user']
};
this.msalService.loginPopup(request).subscribe((response: AuthenticationResult) => {
    this.msalService.instance.setActiveAccount(response.account);
    // 调用Node.js API,此处返回401
})

APIM 验证策略代码:

<when condition="@( !(context.Variables.GetValueOrDefault<bool>("isPublicEndpoint")) )">
    <validate-jwt header-name="Authorization" failed-validation-httpcode="401"
        failed-validation-error-message="Invalid credentials" require-scheme="Bearer" output-token-variable-name="jwt">
        <openid-config
            url="https://<tenantname>.b2clogin.com/<tenantname>.onmicrosoft.com/v2.0/.well-known/openid-configuration?p=B2C_1_sign_in" />
        <audiences>
            <audience>
                <clientId>
            </audience>
        </audiences>
    </validate-jwt>
    <set-header name="userid" exists-action="override">
        <value>@{ 
            return ((Jwt)context.Variables["jwt"])?.Claims.GetValueOrDefault("name", "");
            }</value>
    </set-header>
</when>

我曾看到过相关讨论,里面提到的范围以api://开头,但我的范围格式是tenant-name/clientid/scopename,对此感到困惑。


核心问题排查与修复方案

1. 范围格式与API标识符一致性验证

Azure B2C的API标识符支持两种格式:{tenant-name}.onmicrosoft.com/{client-id}或api://{client-id},但必须确保:

  • B2C租户应用注册 > 暴露的API中的应用程序ID URI,和你请求范围的前缀完全一致(比如你用<tenantname>.onmicrosoft.com/<clientId>作为前缀,那应用程序ID URI就得是这个值,不能混用api://格式)。
  • 请求的范围名称(access_as_user)必须是你在暴露的API里已定义的范围,拼写、大小写完全匹配。

2. APIM validate-jwt配置修正

  • 受众(aud)配置错误:<audience>标签内必须填写Node.js API的应用注册Client ID,而非Angular前端应用的Client ID——令牌的aud声明对应的是API的身份标识,不是发起请求的前端应用。
  • OpenID配置URL修正:原URL中https://后多了一个斜杠,修正为https://<tenantname>.b2clogin.com/<tenantname>.onmicrosoft.com/v2.0/.well-known/openid-configuration?p=B2C_1_sign_in。
  • 添加范围验证逻辑:当前策略未验证令牌的scp声明,需补充<required-claims>节点确保令牌包含所需范围:
    <validate-jwt ...>
        <!-- 原有配置 -->
        <required-claims>
            <claim name="scp" match="any">
                <value>access_as_user</value>
            </claim>
        </required-claims>
    </validate-jwt>
    

3. 令牌内容校验

拿到response.accessToken后,用JWT解析工具查看核心声明:

  • 确认aud等于API的Client ID;
  • 确认scp字段包含access_as_user;
  • 确认iss与APIM OpenID配置返回的issuer值一致。

4. MSAL请求范围的规范写法

如果你的B2C API应用注册使用api://<clientId>作为应用程序ID URI,请求范围应改为api://<clientId>/access_as_user;若使用租户域名前缀,保持现有格式即可,但必须与应用程序ID URI严格对齐。


内容的提问来源于stack exchange,提问作者Asad Shah

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 21:47:05