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

如何用Microsoft访问令牌访问Dynamics CRM?遇401错误求助

解决Dynamics 365 API调用401未授权问题

你的代码能获取到访问令牌但调用API返回401,核心原因是令牌的受众(aud)与Dynamics 365资源不匹配,加上几个配置细节错误,以下是具体修复方案:

1. 修正基础配置错误

首先修正代码里的明显笔误:

// 替换为实际的Azure应用Client ID和Secret
const dynamicsClientId = "<YOUR_CLIENT_ID>"; 
const dynamicsClientSecret = "<YOUR_CLIENT_SECRET>";

2. 调整OAuth2策略,指定Dynamics资源

Azure AD v1.0 OAuth2流程需要明确指定要访问的资源(即Dynamics 365的API地址),否则生成的令牌受众不是Dynamics,会被拒绝。修改passport.use中的策略配置:

passport.use(
  "oauth2",
  new OAuth2Strategy(
    {
      authorizationURL: "https://login.microsoftonline.com/common/oauth2/authorize",
      tokenURL: "https://login.microsoftonline.com/common/oauth2/token",
      clientID: dynamicsClientId,
      clientSecret: dynamicsClientSecret,
      callbackURL: "http://localhost:3000/auth/callback",
      // 授权请求中添加resource参数
      authorizationParams: () => {
        return { resource: dynamicsResource };
      },
      // Token请求中同样携带resource参数
      tokenParams: () => {
        return { resource: dynamicsResource };
      },
      state: true // 启用CSRF防护,推荐添加
    },
    function (accessToken, refreshToken, profile, done) {
      // 可选:解码令牌验证受众是否正确(需安装jsonwebtoken包)
      // const decoded = require('jsonwebtoken').decode(accessToken);
      // console.log("令牌受众:", decoded.aud);
      return done(null, { accessToken, refreshToken });
    }
  )
);

3. 完善API请求头

调用Dynamics API并使用$count=true时,必须添加ConsistencyLevel: eventual头,否则会返回400错误,同时确保令牌格式正确:

app.get("/", ensureAuthenticated, async (req, res) => {
  try {
    const userAccessToken = req.user.accessToken;

    const response = await axios.get(
      `${dynamicsResource}/api/data/v${dynamicsApiVersion}/accounts`,
      {
        headers: {
          Authorization: `Bearer ${userAccessToken}`,
          "ConsistencyLevel": "eventual" // 必须添加的头
        },
        params: {
          $count: true
        }
      }
    );

    res.send(`Total Account Count: ${response.headers["odata-count"]}`);
  } catch (error) {
    console.error("错误详情:", error?.response?.data || error.message);
    res.status(500).send("服务器内部错误");
  }
});

4. 验证Azure AD应用配置

确保Azure端的应用设置正确:

  • API权限:添加Dynamics 365的委托权限(如user_impersonation),并由管理员完成同意授权(多租户应用需要全局管理员同意)。
  • 重定向URI:确认http://localhost:3000/auth/callback已添加到应用的"身份验证"→"Web"平台下。
  • 账户类型:应用的"支持的账户类型"设置为"任何组织目录中的账户"(多租户)。

调试技巧

  • 安装jsonwebtoken包后解码access token,检查aud字段是否与你的dynamicsResource完全一致,scp字段是否包含user_impersonation权限:
    const decoded = require('jsonwebtoken').decode(userAccessToken);
    console.log("令牌受众:", decoded.aud);
    console.log("权限范围:", decoded.scp);
    
  • 查看Azure AD的"企业应用"→你的应用→"登录日志",排查令牌颁发失败的具体原因。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 03:22:32