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

使用Angular MSAL无法认证Azure DevOps API问题求助

Angular应用使用MSAL调用Azure DevOps API返回HTTP 203错误

我在已集成Angular MSAL库的Angular应用中,尝试完成Azure DevOps API的身份认证,但调用API时收到HTTP 203响应。

调用API的代码如下:

this.http.get<any>(`https://dev.azure.com/${org}/${proj}/_apis/wit/workitems/${id}?api-version=7.1`).subscribe({
  next: (x) => (this.debug = x),
  error: (e) => (this.debug = e),
});

错误响应截图:
错误响应截图

我已在Azure门户中为应用注册了必要权限:
应用权限配置截图

当前配置:

protectedResourceMap = new Map([
  ['https://graph.microsoft.com/v1.0/me', ['user.read']], // MS Graph
  ['499b84ac-1321-427f-aa17-267ca6975798', ['vso.work_full']], // DevOps
  [`${config.auth}/authenticate/register.json`, [`api://${CLIENT_ID}/access_as_user`]], // LAPI
]);

以及:

authRequest = {
  scopes: [
    `api://${CLIENT_ID}/access_as_user`, // MS Graph
    'https://app.vssps.visualstudio.com/user_impersonation', // DevOps
    '499b84ac-1321-427f-aa17-267ca6975798/user_impersonation', // DevOps
    'api://499b84ac-1321-427f-aa17-267ca6975798/.default', // DevOps
  ],
};

我已参考以下文档:

  • Azure DevOps身份认证示例代码
  • MSAL JavaScript库官方文档
  • Azure DevOps身份认证指南

我感觉遗漏了某些配置,但始终无法解决HTTP 203错误。


排查与解决方案

1. 修正protectedResourceMap资源匹配规则

Azure DevOps API的资源标识符需要用完整的API根路径,而非客户端ID。修改DevOps对应的配置项:

protectedResourceMap = new Map([
  ['https://graph.microsoft.com/v1.0/me', ['user.read']], // MS Graph
  ['https://dev.azure.com/', ['vso.work_full']], // 改为DevOps API根路径,确保请求能匹配到
  [`${config.auth}/authenticate/register.json`, [`api://${CLIENT_ID}/access_as_user`]], // LAPI
]);

MSAL通过资源路径匹配自动附加令牌,用客户端ID无法正确关联到Azure DevOps的API请求。

2. 精简并修正authRequest的作用域

Azure DevOps只需要https://app.vssps.visualstudio.com/user_impersonation这一个OAuth作用域,多余的作用域会干扰令牌获取:

authRequest = {
  scopes: [
    `api://${CLIENT_ID}/access_as_user`, // 自定义API作用域
    'https://app.vssps.visualstudio.com/user_impersonation', // DevOps核心作用域
    'user.read' // 若需调用Graph API则保留
  ],
};

注意:vso.work_full是Azure DevOps的权限(在门户配置),不属于OAuth作用域范畴,无需放入scopes数组。

3. 确认HTTP拦截器配置

确保已启用MSAL的MsalInterceptor,它会根据protectedResourceMap自动为请求添加Bearer令牌。如果未配置拦截器,需手动获取令牌并附加到请求头:

// 手动获取令牌并调用API示例
this.msalService.acquireTokenSilent({
  scopes: ['https://app.vssps.visualstudio.com/user_impersonation']
}).subscribe(token => {
  this.http.get<any>(`https://dev.azure.com/${org}/${proj}/_apis/wit/workitems/${id}?api-version=7.1`, {
    headers: { Authorization: `Bearer ${token.accessToken}` }
  }).subscribe({
    next: (x) => (this.debug = x),
    error: (e) => (this.debug = e),
  });
});

4. 验证权限授予状态

检查Azure门户中应用注册的vso.work_full权限是否已完成管理员同意(应用权限必须由管理员授予),用户权限则需用户登录时授权。

5. 解析令牌验证有效性

用JWT解析工具查看获取到的令牌,确认:

  • aud(受众)字段为https://app.vssps.visualstudio.com或https://dev.azure.com
  • roles字段包含vso.work_full(应用权限)或scp字段包含user_impersonation(用户权限)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 19:53:15