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

Node.js使用@azure/msal-node调用Azure订阅API报AuthenticationFailed

故障原因

调用列订阅接口返回AuthenticationFailed,核心原因是提交给Azure资源管理器(ARM)的访问令牌未通过服务端校验,高频触发场景如下:

  • 令牌受众不匹配:ARM接口仅接受aud声明值为https://management.azure.com的访问令牌,若实际拿到的令牌是为Microsoft Graph等其他服务签发的,即使令牌本身合法也会被拒绝。
  • 授权流程未完成:配置的https://management.azure.com/user_impersonation为委托权限,需要登录用户或租户管理员完成显式授权同意,否则令牌不会携带对应权限声明。
  • 登录端点配置问题:当前代码中使用https://login.microsoftonline.com/organizations通用端点,若登录账号为个人微软账号(MSA)、或登录时走错租户,会导致令牌签发租户与ARM预期不符。
  • 请求格式错误:比如误将id token作为access token传递、请求头中Bearer前缀格式错误、令牌已过期。
排查步骤

按以下顺序校验可快速定位问题:

  1. 解码获取到的access token,检查payload内的两个核心字段:
    • 校验aud字段值:必须为https://management.azure.com,如果值为其他地址(比如https://graph.microsoft.com),说明换token时scope配置错误,拿到的是其他资源的令牌。
    • 校验scp字段值:必须包含user_impersonation,如果缺失说明授权同意流程未走完。
  2. 补全并检查授权码回调的换token逻辑(当前仅贴出了授权URL生成代码,缺少换token部分):换token时传入的scope必须和授权URL阶段的scope完全一致,不要遗漏ARM相关权限,也不要同时混传多个不同资源的scope——授权码流默认仅为第一个资源签发令牌,混传多资源scope会导致非首个资源的权限缺失。
  3. 校验接口请求头格式:调用ARM接口时请求头必须为Authorization: Bearer <access-token>,注意Bearer后保留半角空格,禁止传入id token。
  4. 检查API权限配置状态:
    API权限配置截图
    进入应用注册的API权限页,确认已添加Azure服务管理下的user_impersonation权限,且权限状态显示已完成授予同意,没有待同意的提示。
修复方案
  • 若使用单租户场景,将配置中的authority改为租户专属端点:https://login.microsoftonline.com/<你的租户ID>,替换掉通用的organizations端点,避免个人账号、错租户登录导致的令牌异常。
  • 测试阶段先将scope简化为仅保留["https://management.azure.com/user_impersonation"],调通ARM接口调用后,再通过增量同意流程追加user.read等其他资源的权限,不要在首次授权时混传多资源scope。
  • 若使用https://management.azure.com/.default作为scope测试,必须提前在API权限页配置好所需的ARM权限,并完成租户管理员同意,否则.default不会自动拉取未授权的权限。
  • 最后确认登录账号本身在目标Azure订阅中已分配至少Reader及以上角色:user_impersonation仅代表应用获得代表用户调用ARM的许可,不代表账号本身拥有订阅访问权限(注意:账号无权限通常返回AuthorizationFailed而非AuthenticationFailed,可最后排查此项)。

修正后的参考配置代码:

const config = {
  auth: {
    clientId: 'xxx',
    // 单租户替换为你的租户ID,多租户场景可保留organizations但要做租户校验
    authority: 'https://login.microsoftonline.com/<你的租户ID>',
    clientSecret: 'yyy',
  },
  system: {
    loggerOptions: {
      loggerCallback(loglevel, message, containsPii) {
        console.log(message);
      },
      piiLoggingEnabled: false,
      logLevel: msal.LogLevel.Verbose,
    },
  },
};

// 初始化MSAL confidential client实例
const pca = new msal.ConfidentialClientApplication(config);
const app = express();

app.get('/', (req, res) => {
  const authCodeUrlParameters = {
    // 测试阶段仅保留ARM权限,调通后再追加其他资源权限
    scopes: ['https://management.azure.com/user_impersonation'],
    redirectUri: REDIRECT_URI,
  };

  // 获取授权登录URL
  pca
    .getAuthCodeUrl(authCodeUrlParameters)
    .then((response) => {
      res.redirect(response);
    })
    .catch((error) => console.log(JSON.stringify(error)));
});

接口返回的典型错误示例:

{
    "error": {
        "code": "AuthenticationFailed",
        "message": "Authentication failed."
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 01:25:06