1. 题目与使用场景
公司有多个 API 资源服务器,访问令牌由授权服务器签发。资源服务器需要知道令牌是否 active、属于哪个客户端、拥有哪些 scope 以及何时过期;安全团队还要求能快速撤销被盗令牌。设计要平衡实时撤销、低延迟和授权服务可用性。
2. 面试官考察点
- 是否理解 RFC 7662 introspection 响应与 RFC 7009 撤销语义。
- 是否能设计缓存、撤销事件和版本,使“已撤销”不会长期被旧缓存掩盖。
- 是否区分不透明令牌、JWT 本地校验和 DPoP 等持有证明。
- 是否为授权服务不可用、网络重试、租户隔离和审计提供明确策略。
3. 回答前需要澄清的问题
- 令牌是短时 access token、refresh token,还是两者都要 introspect?
- 撤销目标是单个令牌、授权授予、用户会话还是整个客户端?
- 资源服务器能接受多长的撤销传播延迟?
- 是否需要绑定客户端密钥或 DPoP 公钥,防止 bearer token 被复制后重放?
4. 30 秒回答框架
用“端点—状态源—缓存—撤销传播—故障策略”回答:
授权服务器提供受保护的 introspection 和 revocation 端点,状态库保存令牌哈希、客户端、scope、过期和撤销版本。资源服务器按短 TTL 缓存 active 结果,同时订阅撤销事件立即删除相关缓存;高风险 scope 在授权服务不可用时拒绝,低风险请求只在未过期的正缓存内短暂放行。所有查询、撤销和失败都写入审计。
5. 分步骤深入解答
第一步:定义令牌状态与端点权限
Introspection 请求只允许受信任的资源服务器调用,返回 active、client_id、username、scope、exp、iat、sub 等必要字段,避免泄露多余身份信息。撤销端点应验证调用方和令牌类型,按 RFC 7009 处理重复撤销,不能因为令牌已失效就泄露其存在性。
第二步:设计状态存储和索引
以令牌指纹或哈希作为主键,保存签发时间、过期时间、授权授予 ID、客户端、scope、状态版本和撤销原因。按授权授予 ID 建立批量撤销索引;敏感原文不进入日志。数据分片按租户或哈希分布,避免单个客户端成为热点。
第三步:处理缓存与撤销传播
正结果可以短 TTL 缓存,负结果通常不应长时间缓存。撤销后发布带令牌指纹和状态版本的事件,资源服务器删除本地条目;事件丢失时由版本检查或定期拉取修复。对高风险操作可强制在线 introspect,牺牲延迟换取实时性。
第四步:故障、重试与持有证明
对 introspection 超时使用指数退避和熔断,避免资源服务器把授权服务压垮。授权服务不可用时按 scope 风险选择 fail-closed 或短暂使用尚未过期的正缓存。若采用 DPoP,资源服务器还要验证请求证明与令牌绑定的公钥,降低纯 bearer token 被复制后的重放风险。
6. 高质量示范回答
我会把系统拆成授权端点、introspection 服务、撤销服务、状态存储、撤销事件总线和资源服务器 SDK。状态库以令牌哈希为键,保存 client、scope、iat、exp、授权授予 ID、撤销状态和版本。introspection 只返回资源服务器需要的字段,并要求调用方认证。
>
SDK 对普通 scope 缓存 active 结果三十秒,对高风险 scope 每次在线查询。撤销接口支持单令牌和按授权授予批量撤销,成功后发送带版本的事件;SDK 收到事件立即删除缓存,定时任务补偿丢失事件。正结果缓存到期前如果版本不匹配,也必须重新查询。
>
授权服务超时时,低风险请求可以使用尚未过期的正缓存,高风险请求直接拒绝;熔断和抖动重试防止级联故障。若使用 DPoP,SDK 额外验证请求证明和绑定公钥。查询、撤销、缓存命中和故障都写入脱敏审计,便于追踪被盗令牌的传播范围。
7. 常见错误
- 把 JWT 本地签名验证当成实时撤销方案。
- 长时间缓存 active 结果,却没有撤销事件或版本校验。
- introspection 端点对公网开放,或返回不必要的用户字段。
- 授权服务故障时所有请求都 fail-open,放大被盗令牌风险。
- 重试没有超时、熔断和抖动,导致认证流量雪崩。
8. 追问及应对
追问一:为什么负缓存通常要更短?
令牌可能刚签发、网络读到旧副本或撤销状态正在传播。短负缓存能减少把暂时性不存在误判为永久无效的窗口。
追问二:撤销 refresh token 是否应同时撤销 access token?
按授权授予和安全策略决定。若 refresh token 被盗,通常应撤销该授予下的剩余令牌,并让资源服务器通过版本或事件尽快失效缓存。
追问三:如何防止撤销事件重复或乱序?
事件携带单调递增版本或撤销时间,消费者只接受不旧于本地状态的版本;重复事件保持幂等,乱序事件不会把已撤销状态恢复为 active。