Azure AD 'on behalf of'流触发AADSTS65001错误求助
排查Azure AD On-Behalf-Of流AADSTS65001错误
关键排查步骤
1. 确认前端令牌的受众(aud)是否为中间层应用ID
前端SPA获取的访问令牌,其aud字段必须是中间层Azure函数对应的AD应用ID,而非XXX_embedding的应用ID。如果aud指向XXX_embedding,AAD会判定中间层无权使用该令牌发起OBO请求——因为这个令牌是发给XXX_embedding的,并非中间层应用。
用jwt.io解析前端令牌,检查aud值是否匹配中间层应用的客户端ID。
2. 检查中间层应用的API权限配置
中间层应用(Azure函数对应的AD应用)必须添加XXX_embedding的委托权限(即你暴露的on_behalf_of范围),并且完成管理员同意。你之前仅配置了前端应用的权限同意,但OBO流中,中间层作为机密客户端,自身也需要被授予访问目标资源(XXX_embedding)的委托权限。
操作步骤:
- 进入中间层AD应用的“API权限”页面
- 添加权限 → 选择“我的API” → 找到XXX_embedding
- 勾选
on_behalf_of范围,点击添加 - 点击“授予管理员同意”,完成权限配置
3. 验证OBO请求参数的正确性
在Azure函数的代码中,确保OBO请求的参数完全符合要求:
grant_type必须设为urn:ietf:params:oauth:grant-type:jwt-bearerassertion是前端传来的完整访问令牌client_id和client_secret是中间层应用的ID和密钥scope必须是XXX_embedding范围的完整URI(例如api://{XXX_embedding_client_id}/on_behalf_of)- 必须添加
requested_token_use=on_behalf_of参数
示例代码片段(.NET):
var oboRequest = new HttpRequestMessage(HttpMethod.Post, "https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/token"); oboRequest.Content = new FormUrlEncodedContent(new Dictionary<string, string> { ["grant_type"] = "urn:ietf:params:oauth:grant-type:jwt-bearer", ["assertion"] = frontendToken, ["client_id"] = middleTierClientId, ["client_secret"] = middleTierClientSecret, ["scope"] = "api://XXX_embedding_client_id/on_behalf_of", ["requested_token_use"] = "on_behalf_of" });
4. 核对令牌的租户一致性
确保前端令牌的tid(租户ID)和中间层应用所在的租户ID完全一致。跨租户的OBO流需要额外配置允许的租户,若未配置会触发权限错误。
5. 检查令牌的有效期
用jwt.io解析前端令牌,确认exp(过期时间)晚于当前时间,nbf(生效时间)早于当前时间。过期或未生效的令牌会被AAD拒绝。
6. 确认中间层应用的客户端类型
中间层应用必须是机密客户端(拥有客户端密钥或证书),公共客户端(如SPA)无法发起OBO请求。检查中间层应用的“认证”页面,确保其类型为“Web应用/API”或“机密客户端”,且已配置客户端密钥。
内容的提问来源于stack exchange,提问作者DevUser
相关产品推荐
相关产品推荐

