使用IdentityModel与Azure AD获取JWT令牌调用API遇403问题
解决Client Credentials令牌缺少roles导致的DAB API 403问题
核心差异说明
Azure CLI获取的是用户身份令牌(代表个人账号),因此包含scp(用户权限)和roles(用户被分配的角色);而你用IdentityModel的client_credentials流获取的是应用身份令牌(代表Blazor Server应用),只有当应用被分配了API的应用角色时,令牌才会包含roles字段。
具体修复步骤
1. 确认API应用注册的角色为「应用角色」
在Azure AD的API应用注册中:
- 进入「应用角色」页面,确保你定义的
Test.Role是应用角色(创建角色时勾选「允许应用程序访问」选项)。 - 仅允许用户/组分配的「用户角色」不会出现在应用身份令牌中。
2. 给客户端应用分配API的应用角色
- 进入Azure AD的客户端应用注册(你的Blazor Server应用对应的注册),打开「API权限」页面。
- 点击「添加权限」→ 选择「我的API」→ 找到DAB对应的API应用注册。
- 在「应用权限」分类下选择目标角色(如
Test.Role),点击「添加权限」。 - 点击「授予管理员同意」(这是Client Credentials流的必要步骤,必须完成)。
3. 验证角色分配状态
- 进入API应用注册对应的「企业应用」页面,切换到「应用程序」标签页,确认你的客户端应用已被分配对应的角色。
4. 检查代码配置正确性
确保ClientCredentialsTokenRequest参数无错误:
ClientId必须是客户端应用的ID,而非API应用ID。Scope设置为api://{API-App-ID}/.default是正确的,该范围会自动包含所有已分配的应用权限。Address中的租户ID需与API应用注册的租户ID一致。
示例修正代码:
using var client = new HttpClient(); var tokenResponse = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest { Address = "https://login.microsoftonline.com/{你的租户ID}/oauth2/v2.0/token", ClientId = "你的客户端应用ID", ClientSecret = "你的客户端应用密钥", Scope = "api://{API应用ID}/.default", GrantType = "client_credentials" });
5. 验证令牌内容
获取令牌后,解码确认roles字段是否包含分配的应用角色。若仍缺失,重新检查角色分配和管理员同意步骤。
6. 检查DAB配置
确保dab-config.json中的Azure AD设置正确:
auth.azure_ad.tenant_id为你的租户ID。auth.azure_ad.audience为API应用的客户端ID。- 若DAB配置了角色验证,确保要求的角色与分配的应用角色一致。
内容的提问来源于stack exchange,提问作者Julian Dormon
相关产品推荐
相关产品推荐

