Azure Easy Auth刷新AD Access Token遇403拒绝访问问题排查及解决方案咨询
问题分析与解决方案
这问题我之前帮团队排查过类似的,结合你的测试结果——移除自定义scope后刷新正常、手动调用OAuth端点也能成功——核心问题大概率出在自定义API权限范围的配置以及Azure Easy Auth的令牌刷新逻辑上,下面一步步拆解:
为什么自定义scope会导致/.auth/refresh返回403?
Azure Easy Auth的/.auth/refresh端点在刷新令牌时,会严格验证以下两点:
- 初始登录时获取的refresh token必须包含所有请求刷新的scope(也就是你登录参数里的
openid profile email offline_access api://xxx-xxx-xxx/user_impersonation) - 每个scope对应的资源(这里就是你的自定义API
api://xxx-xxx-xxx)必须允许应用服务使用refresh token来获取新的access token
如果你的自定义API没有正确配置权限,或者应用服务的身份没有被授予该API的权限,即使手动调用Azure AD端点能成功(因为手动调用可能只验证了部分条件),Easy Auth的内置刷新逻辑也会因为权限检查失败返回403。
具体解决方案步骤
1. 检查自定义API的权限配置
- 登录Azure Portal,进入Azure Active Directory -> 应用注册,找到你的自定义API(即
api://xxx-xxx-xxx对应的注册) - 切换到公开 API页面,确认
user_impersonation权限的“谁能同意?”设置:如果是租户内应用,建议设置为“管理员和用户”;如果是多租户应用,确保已正确配置同意流程 - 回到API权限页面,确认已添加
offline_access权限(属于Microsoft Graph的Delegated权限)——这是获取和使用refresh token的基础权限
2. 确保应用服务被授予自定义API的权限
- 在Azure AD的应用注册里,找到你的应用服务对应的身份(如果是Easy Auth自动创建的,名称通常和应用服务一致)
- 进入API权限页面,点击添加权限 -> 我的API,选择你的自定义API
- 勾选
user_impersonation权限,点击添加权限 - 点击授予管理员同意(如果是租户级应用,必须完成这一步才能让所有用户的refresh token正常刷新)
3. 验证登录参数的格式正确性
你的登录参数配置是:
"loginParameters": ["scope=openid profile email offline_access api://xxx-xxx-xxx/user_impersonation"]
确认scope参数是用空格分隔的多个值,没有多余的引号或转义字符——Easy Auth对参数格式的解析比较严格,格式错误可能导致refresh token不包含完整的scope,进而刷新失败。
调试技巧(解决日志看不到的问题)
PM2确实无法捕获Easy Auth的日志,因为Easy Auth是应用服务的前置代理模块,日志存储在应用服务的Web服务器日志里:
- 进入应用服务的监控 -> 日志流,选择Web Server Logs,当你调用
/.auth/refresh时,会看到对应的请求记录和错误详情(比如invalid_scope、insufficient_permissions等具体错误码) - 用jwt.ms解码你从
/.auth/me拿到的refresh token,检查scp字段是否包含user_impersonation和offline_access,aud字段是否包含你的自定义API的ID——如果scope缺失,说明登录时的参数没有被正确解析 - 手动用refresh token调用Azure AD的token端点(带上完整的scope),命令如下:
POST https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/token Content-Type: application/x-www-form-urlencoded grant_type=refresh_token &client_id={your-app-service-client-id} &refresh_token={your-refresh-token} &scope=openid profile email offline_access api://xxx-xxx-xxx/user_impersonation
如果手动调用失败,错误信息会直接告诉你问题出在scope还是权限;如果手动调用成功,那说明问题出在Easy Auth的配置,需要检查应用服务的Easy Auth设置是否有遗漏。
内容的提问来源于stack exchange,提问作者pkiller162




