Azure AD共享登录场景下跨Web应用调用Web API异常问题
排查Web应用2调用Web应用1 API失败的问题
看起来你的单点登录(SSO)已经正常跑通,但Web应用2调用Web应用1的API时出现异常——核心问题大概率是Web应用2没有获取到针对Web应用1 API的有效访问令牌,或者令牌的权限、受众不符合要求。下面是一步步的排查和解决思路:
1. 先确认API权限配置是否正确
- 登录Azure门户,找到Web应用2的应用注册:
- 检查「API权限」菜单下,是否添加了Web应用1暴露的Delegated权限(因为是用户上下文调用API,必须用Delegated权限,而非Application权限)。
- 确认这些权限已经完成管理员同意(组织内应用需管理员点击「授予管理员同意」按钮;个人测试场景下,用户登录时会弹出授权框,要确保用户已完成授权)。
- 同时检查Web应用1的应用注册:
- 在「公开API」菜单下,是否正确暴露了API范围(比如
access_as_user),且范围状态为「已启用」。
- 在「公开API」菜单下,是否正确暴露了API范围(比如
2. 验证Web应用2的令牌获取逻辑
SSO成功只意味着Web应用2拿到了自己的ID令牌(用于用户登录验证),但调用Web应用1的API需要单独获取访问令牌。你需要确认:
- 当用户自动登录Web应用2后,是否在调用API前主动触发了访问令牌的获取流程?比如使用MSAL库的话,应该调用类似
AcquireTokenSilent的方法,指定Web应用1的API范围:// 示例:.NET中用MSAL获取访问令牌 var scopes = new[] { "api://<WebApp1-Client-ID>/access_as_user" }; var result = await _tokenAcquisition.GetAccessTokenForUserAsync(scopes); // 用result.AccessToken作为请求头去调用Web应用1的API - 如果缺少这个步骤,Web应用2的令牌缓存里只有自己的ID令牌,没有针对Web应用1的访问令牌,调用API自然会失败。
3. 检查令牌缓存的共享机制
你的两个应用已经实现了SSO,但令牌缓存是否跨应用共享?
- 如果Web应用1和Web应用2使用独立的令牌缓存(比如各自的内存缓存),那么Web应用2自动登录后,缓存中没有Web应用1的访问令牌,需要重新获取(此时
AcquireTokenSilent会先尝试从缓存拿,没有的话会触发静默授权流程)。 - 建议使用分布式缓存(比如Redis)来共享令牌缓存,确保两个应用能访问到同一个缓存池里的令牌。
4. 解析令牌确认关键声明
拿到Web应用2获取的访问令牌后,用jwt.ms工具解析,检查以下关键声明:
aud(受众):必须等于Web应用1的客户端ID或者API的应用ID URI,否则Web应用1的API会直接拒绝请求。scp(权限范围):必须包含你在Azure AD中配置的API权限范围(比如access_as_user),否则说明权限配置或令牌获取逻辑有问题。sub(用户ID):确认是当前登录的用户,确保上下文正确。
5. 排查API调用的请求头
调用Web应用1的API时,是否正确设置了Authorization头?格式必须是:
Authorization: Bearer <你的访问令牌>
如果头格式错误,或者令牌过期,也会导致异常。
按照上面的步骤逐一排查,应该能快速定位到问题所在。
内容的提问来源于stack exchange,提问作者Himal Patel
相关产品推荐
相关产品推荐

