grant type 决定采用哪一种授权流程,scope 描述权限范围,用户审批决定是否同意授权。响应没有 refresh_token,与授权确认页没出现,是不同问题,不能都归结为 scope 名称不对。
两次 scope 改名,观察结果恰好相反
2019 年 3 月,首次授权已能返回 access token,响应的 scope 为 user_info,却没有 refresh token。当时同时做了两个改动:给客户端允许的授权类型增加 refresh_token,并把 scope 改成 all。随后响应中出现刷新令牌。
同年 12 月,自定义授权页和默认授权页都没有出现,即使设置 autoApprove(false) 也一样。把注册和请求中的 scope 从 all 改成 read 后,确认页出现。
这两次经历不能证明 all 是获取刷新令牌的必要条件,也不能证明 read 是显示确认页的开关。前一次同时改了两项,后一次还涉及会话与已有审批状态。
配置各管什么
| 配置或状态 | 主要职责 |
|---|---|
| authorizedGrantTypes | 客户端获准使用的授权类型 |
| scopes / 请求 scope | 注册范围与本次申请的权限范围 |
| auto-approve | 某些范围是否自动批准 |
| 已有授权、会话及审批存储 | 影响当前交互是否需要再次询问 |
| Token 服务与令牌策略 | 决定是否颁发及如何刷新令牌 |
这些字段可在旧 BaseClientDetails API 中分别找到。scope 字符串的业务含义由服务约定,不能从字面上的“全部”推导出框架特殊能力。
没有 refresh_token 时按顺序检查
先确认采用的流程是否支持刷新、客户端是否获准使用刷新授权,以及服务端 Token 服务的颁发策略;再核对请求范围与注册范围是否一致。不要为了得到一个字段把流程改成另一种身份语义。
RFC 6749 §6 区分刷新凭据与新 access token,刷新范围不能超过原授权范围;颁发刷新令牌也不是所有流程的统一保证。
在相同用户、相同客户端、相同存储条件下,一次只改一项并保存脱敏响应,才能区分哪个改动真正产生影响。收到刷新令牌之后,客户端认证仍需单独正确配置,见 刷新请求 invalid_client。
确认页不出现时,先追跳转链
从实际授权请求检查 client_id、response_type、scope、回调地址和会话,再看授权服务是否复用了既有审批、是否自动批准、是否进入了预期页面处理器。
更改 scope 后出现页面,可以作为排查线索,却不能取代对审批存储和页面映射的检查。以下结论只解释旧 Spring Security OAuth 的历史问题;旧项目已结束生命周期,新实现需要采用受支持组件的配置方式。