摘要

  • RFC 9767 中的“有效”是一组条件的合取:签发者、撤销状态、时间、证明方式、目标资源服务器及所请求访问都必须相符。
  • 授权服务器提供令牌状态证据;资源服务器还要验证这一次呈现、应用本地规则,并决定返回错误、公开资源还是执行受保护操作。
  • 可审计系统至少保留四张收据:内省答复、本次消息证明、本地决策、实际效果;缓存年龄和下游派生令牌不能被藏进同一个“已授权”字段。

“是”回答了什么

客户端把访问令牌交给资源服务器(RS)。RS 再向授权服务器(AS)发起内省。这个调用不是客户端借 RS 之口发问:RS 用自己的密钥签名,并表明自己的身份。

请求体还带有客户端提交的令牌值,通常写明客户端呈现令牌时使用的证明方法;RS 也可以列出完成当前请求所需的最低访问权限。AS 必须把所有已给出的参数纳入判断。若其中任何一项无法处理,它就不得返回有效。

所以,“有效”从来不是贴在令牌上的永久标签。同一令牌可能适用于 RS1,却不适用于 RS2;可以读,却不足以写;尚未过期,却用了错误的持钥证明。只有把提问者、目标、访问动作和时间带回来,布尔值才有可解释性。

RFC 9767 是 GNAP 核心协议的角色接口。RFC 9635 主要规定客户端和 AS 之间的 grant 协商;本规范处理解耦部署中的 AS—RS 连接。双方能够互通,并不意味着 AS 接管了 RS 对本地资源的控制权。

RS 的密钥如何被 AS 知晓也被留在规范范围之外。预注册、其他登记流程或首次使用信任都可能存在。签名通过只能说明请求持有已接受的密钥,不能证明登记治理正确,更不能证明 RS 随后的业务判断正确。

一个比特里的六项条件

RFC 9767 对正面结果给出了清楚边界。令牌必须由正在处理请求的 AS 签发;没有被撤销;没有过期;按照请求所指明的证明方法绑定;适合在所识别的 RS 呈现;如果请求带有 access,还必须覆盖这项最低需要。

负面结果不是标准化的病因报告。AS 找不到令牌、无法判断、发现过期、撤销、受众不符或访问不足,都可能得到 false,其余字段随之省略。把所有 false 记为“已撤销”,会把故障关闭设计改写成虚假确定性。

正面结果同样不能外推。它没有证明当前请求内容安全,没有证明用户此刻意图,没有核验对象仍存在、额度充足、反欺诈通过或下游执行成功。它只证明这枚令牌在此次内省所表达的条件下通过了 AS 的判断。

有效答复可以带回访问权、密钥、标志、时间和身份信息。但访问权可以按当前 RS 过滤,甚至是空数组;答复绝不能把令牌值本身送回。一个 RS 所见的局部视图,并非整个授权域的完整真相。

最后一步属于资源服务器

RFC 9767 在内省之后明确写出职责:RS 自行确定合适的处理方式。若权限不足,它可以返回错误,也可以返回公开资源;最终响应由 RS 决定。

这不是绕过授权,而是把权力放回能作用于对象的一层。AS 了解 grant、签发和撤销状态;RS 才知道具体接口、方法、对象状态、本地安全约束、业务限制与可执行的响应选项。

本地决定必须可问责。决策收据应记录资源和动作、采用了哪些返回权利、本地政策及版本、附加控制、软件版本和最终选项。权限不足后返回公开数据,不等于受保护访问成功。

效果还要另立收据。RS 可能完成写入却丢失回复;也可能接受请求后在存储层回滚;HTTP 200 内仍可包含业务失败;下游服务也可能没有完成。AS 的布尔值观察不到这些事实。

令牌验证与本次证明

持钥令牌常被误写成一项检查。实际上,RS 既要判断令牌本身,也要验证当前消息使用了正确密钥和证明方式。只验证签名并不够:被盗密钥或 confused deputy 可以生成密码学正确、权限却越界的请求。

反过来,内省为真也不能代替本次消息的证明。目标、被签名组件、nonce 和时间都可能变化。RFC 9767 要求按请求独立验证证明,不得把一条消息的 proof 结果缓存后套给下一条。

HTTP Message Signatures、DPoP 和 mTLS 证书绑定令牌分别提供不同绑定手段;它们都没有代替 RS 的业务策略。日志应把内省 ID 与当前消息 proof ID 分开,写明覆盖组件、密钥、算法、时间或 nonce、结果与失败原因。

缓存把过去借给现在

每次访问都向 AS 内省,会增加延迟和可用性依赖。RS 可以缓存验证结果。RFC 9767 不掩饰代价:性能和处理开销得到改善,信息的新鲜度与准确度下降。正面缓存仍在使用时,已经撤销的令牌可能继续被接受。

因此 TTL 是 RS 的权力选择,而非 AS 的隐含承诺。十分钟 TTL 的真实意思是:资源运营者愿意在十分钟内用过去的 AS 事实替代当前事实。公开读取、私密读取和不可逆支付不应因为库默认值而共享同一风险窗口。

缓存键必须保留回答的上下文。若只按 token 索引,一个对 RS1、某种 proof 或只读访问成立的结论,可能被错误挪到另一个问题。负面缓存也要谨慎,因为 false 同时容纳确定拒绝和无法判断。

RFC 7009 规定 OAuth 撤销动作,但撤销请求不是每个 RS 缓存已经失效的证明。RFC 9767 提到可以主动发送失效信号,却把机制留在范围之外。闭环需要保存失效事件、受影响条目,以及此后确实改变的 RS 决定。

最小披露并非没有观察

内省的优势之一,是 AS 可以只向某个 RS 返回必要 claims。例如,非医疗服务没有理由得知另一个服务需要的医疗编号。可每一次在线内省也让 AS 知道某枚令牌何时在某个 RS 被使用。

结构化令牌把权衡推向另一侧:RS 能本地验证,AS 少了一条实时使用轨迹,但更多 claims 可能随令牌分发,撤销信息也可能更晚生效。RFC 9767 允许结构化、不透明和混合模式,没有宣称其中一种天然胜出。架构决策应同时给出新鲜度预算和披露预算。

密钥类型也会改变信任面。非对称证明的公开验证密钥不能生成私钥签名;对称密钥却必须把共同秘密交给 RS,RS 因而可能自己构造新的呈现。“已绑定密钥”不足以描述复用与泄露风险。

资源引用标识同样应保持不透明。它表示在 AS 登记的一组资源,客户端可在访问请求中引用,却不该解析其内部结构。随机或加密值减少泄露和格式锁定。它是协调句柄,不是脱离 AS 语义后仍自带权利的凭证。

下游令牌开启新的一段

RS1 收到客户端令牌后,可能需要调用 RS2。直接转交 bearer token 会扩大泄露和混淆代理风险。RFC 9767 允许 RS1 以自己的密钥作为客户端签名新请求,并用 existing_access_token 提供原令牌上下文。

AS 必须先确认原令牌适合用于 RS1,随后才能签发面向 RS2 的派生令牌。新令牌可以绑定 RS1 的密钥,并把权限缩小到下游所需。若还有 RS3,这个过程还可继续。

派生改善了受众与保管,却没有创造端到端效果证明。新令牌不能证明 RS1 正确理解了原始请求,不能证明 RS2 已执行,也不能证明结果回到最初客户端。OAuth Token Exchange 的相邻设计同样提醒我们:新凭证带来新的主体、行动者、受众和范围问题。

每一跳都要保留入站请求、派生请求、签发结果、下游呈现、本地决定与实际效果。令牌链只是一组可验证授权工件,不是工作完成链。

四张收据测试

第一张收据是内省:完整问题、RS 签名身份、令牌保护摘要、proof 方法、access、答复、时间和缓存决定。第二张是当前呈现证明。第三张是 RS 政策决定。第四张才是 commit、下游确认、响应交付或补偿效果。

测试应逐一打断连接处:正确令牌交给错误 RS;要求未覆盖的写权限;发送 AS 不理解的访问项;在第二条消息重放 proof;撤销后继续命中正面缓存;返回空的过滤权利;写入成功但回复丢失;RS1 把入站 bearer token 直接送给 RS2。

合格标准不是永远亮绿灯,而是每一层只在自己的证据范围内失败,并且没有任何一层擅自伪造下一张收据。

来源