摘要

  • RFC 9701 让经过认证的资源服务器取得已签名、可选加密的 JWT 令牌内省响应;外层 iss、aud、iat 描述这份回答,内层 token_introspection 才描述被查询的访问令牌。
  • 完整证据链必须继续覆盖调用方身份、响应类型、签名与解密、受众和新鲜度、内层状态与收窄后的 scope、披露依据、抗重放、本地规则以及真正发生的操作。

校验器返回“签名有效”,并不等于授权系统返回“允许执行”。这两个结果都可能正确,却来自两个不同主体。RFC 9701 的价值,正是让授权服务器的回答变得更可归因,同时保留资源服务器对本地结果的责任。

RFC 7662 定义 OAuth 2.0 Token Introspection:受保护资源可以询问授权服务器,一个访问令牌目前是什么状态,并取得相关数据。基础响应是普通 JSON。RFC 9701 增加 JWT 形式,适用于资源服务器需要更强保证、确认回答确由授权服务器发出的场景。

签名把声明、签发者和字节绑定;可选加密把可读范围压到特定接收者。它们强化“谁说了什么”,不会自动回答“本次请求能否执行”。

先审核提问者,再描述令牌

RFC 9701 要求授权服务器识别、认证并授权调用内省端点的资源服务器。仅仅知道 URL、建立 TLS,或者能够提交一个令牌都不够。调用者必须成为可识别的资源服务器主体;它的凭据也应限制在所需调用范围内。

部署可以借助 RFC 7591 把资源服务器作为 OAuth 客户端登记,记录 client_id、认证方法与密钥。标准没有规定唯一配置库,但规定了不可绕开的判定:该服务器是不是令牌的受众,它有权看到哪些数据。

如果令牌无效、过期、已撤销,或根本不面向这个调用者,内层只能返回 active:false,不得附带其他成员。否定响应因此不会顺便泄露主体、scope、客户标识或到期时间。

若令牌对该资源服务器有效,返回的 scope 还应收窄到与它相关的部分。身份和其他敏感字段服从接收方专属政策与合法披露依据。同一个令牌面对两个服务,可以产生两份字段不同、但都正确的签名回答。

外层与内层使用同名字段,却不共享权力

资源服务器用 Accept: application/token-introspection+jwt 请求此格式。响应使用相同媒体类型,JWT header 的 typ 为 token-introspection+jwt。外层必须包含 iss、aud、iat 与 token_introspection。

外层 iss 是回答的签发者,外层 aud 是回答的接收者,外层 iat 是回答生成时间。内层可能也有 iss、aud、iat、exp、sub 与 scope;这些属于被内省的访问令牌。字段拼写相同,不代表可以在对象模型里摊平成一张表。

RFC 9701 因而不建议在外层放 sub 与 exp,并明确说明:这份 JWT 不是访问令牌的替代编码,也不应作为访问令牌使用。把它送进通用 bearer-token 验证器,就会让“关于令牌的回答”冒充“令牌本身”。

IANA OAuth 参数表、JWT claims 注册表与媒体类型登记提供公共词汇。登记能避免名称冲突,却无法证明生产代码保留了层次与上下文。

签名、加密和授权是三份收据

响应可以只签名,也可以先签名再加密,形成 Nested JWT。JWS提供签名结构,JWE提供加密结构,JWT定义 claims 与嵌套方式。它们不会替本地系统选定可信 issuer、可接受算法、密钥轮换窗口或响应最长年龄。

RFC 9701 增加签名算法、密钥加密算法与内容加密算法的元数据。授权服务器可以通过 RFC 8414公开支持集合,资源服务器可以登记 jwks_uri 或 jwks。能力清单是可选空间,不是本次执行结果。kid 是找钥匙的提示,也不是钥匙当时仍受信任的证明。

因此每次重要决定都应保存:响应哈希、媒体类型、typ、期望 issuer、issuer 绑定的密钥集版本、算法政策、实际算法、签名结果,以及加密时的接收方密钥与解密结果。没有这些记录,“JWT 已验证”仍是一句过宽的结论。

跨 JWT 混淆利用的是外形相似

JWT 访问令牌与 JWT 内省响应都可能含有 iss、aud,甚至由同一信任域签名。若资源服务器只检查“能否验证签名”,攻击者就可能把内省响应当作访问令牌提交。RFC 9701 用专属 typ 与内层对象隔离语义;RFC 8725则要求相似 JWT 用途建立互斥验证规则。

真正的防线不是通用解析器里多一条 if,而是每个入口拥有自己的 profile:允许的 type、issuer、audience、算法、必需 claims 与失败行为。成功解密也不能改变内层对象的类型。

同样,内省响应签名不会自动阻止访问令牌重放。RFC 9701 指向 RFC 9700 的重放对策。发送者约束、持有证明、请求绑定与令牌受众仍需另行验证。授权服务器可以真实地说“这个令牌当时有效”,而提交它的人仍然可能没有使用权。

active:true 是带时间戳的历史事实

外层 iat 让回答年龄可计算,但没有替所有操作规定统一缓存期。回答生成后,令牌可能撤销、过期或失去 scope;本地风险规则也可能变化。旧响应的签名仍然有效,因为它忠实记录了当时的声明;它对现在的操作却可能已经太旧。

资源服务器应按操作风险决定最大年龄。低风险读取与高额变更不必共享阈值。需要更强新鲜度时,必须重新内省或使用另一种机制。若团队只优化延迟,缓存会悄悄变成延长授权的工具。

然后才是本地政策。内层 scope=write 不会自动解除对象锁,不会满足双人审批,也不会绕过账户暂停、地理限制或交易额度。资源服务器必须产生自己的 allow/deny 收据。即使 allow,数据库写入也可能失败或回滚;只有实际副作用记录才能证明结果。

内省也会产生一条用户活动轨迹

JWT 内省可以携带个人数据。RFC 9701 要求披露有法律依据,并按资源服务器身份与令牌数据限制内容。加密只能防止无密钥者读取,不能替错误接收者取得合法资格,也不能约束解密后的二次使用。

每次内省还会告诉授权服务器:某个客户端、甚至某个用户正在访问某个资源服务器。若这种可观察性不可接受,标准要求换用其他令牌数据传递方式。RFC 9325 能加强 TLS,不会消除授权服务器对查询时刻的知情。

最终收据应逐层绑定令牌指纹、请求操作、资源服务器身份与认证、端点和 TLS、响应字节、type、密钥与算法、签名和解密、外层 claims、内层状态与 scope、个人数据披露依据、重放检查、本地政策版本、决策、实际副作用与补偿动作。

Lu Heng 的最小初始规范原则适合这套分工:公共层只规定互操作所需的请求格式、响应类型、必需 claims、嵌套位置与算法元数据;信任、新鲜度、隐私、授权和执行留给本地。现实层纪律把注册表、解析、签名、令牌状态、决策与物理结果分开。运行代码优先则要求查看这一次校验和 enforcement 的真实记录,而不是“支持 RFC 9701”的产品标签。

来源