系统设计 / 访问控制 · 从 RBAC 查表到 policy 判定函数 / identity:subject 的属性从哪来,能有多旧 待审核 12 / 23
identity · authn → authz

identity:subject 的属性从哪来,能有多旧

授权请求:四元组who 当作已知输入,who:subject 与属性 又给它挂上一组属性。两页都跳过了一个前置问题:这些属性是谁填进去的。填它的是 authn:一次登录(passkeyTOTP、口令)验明「他是谁」并产出一份凭证,authz 从这份凭证出发回答「他能做什么」。两者的接口就是凭证里的那几行 claims

1 · 属性的来源与时效

claims 自带属性,判定时不必再查任何东西,代价是属性在签发那一刻就被冻结。另一条路是凭证只带 sub,属性在判定现场向 PIP 回查,即 现实世界:XACML / AWS IAM / OPA / Cedar §1 里那个供数的角色。

表 1-1 · 两种取属性方式在时效与代价上的差别。
维度 token claims 判定现场回查 PIP
判定延迟 零,属性随请求一起到达 每次判定多一次 DB / RPC
时效 签发时冻结,直到过期 与数据源同步
撤销 凭证已发出,难以追回 改完立即生效
体积 属性越多 header 越大 与请求大小无关
适配 高频调用、属性稳定 高危动作、属性易变

建议 · 两条路按属性的变化频率分工,而不是二选一。subtenantdept 这类一年改不了一次的写进 claims;employedclearance、角色成员关系这类随时可能被管理员改动的留给回查。判定一次的成本因此只落在真正易变的那几个属性上。

2 · stale claims 的窗口

stale claims 的窗口长度是一道减法:改动发生在签发后第 tt 分钟、凭证 TTL 为 TT,则此后 TtT - t 分钟内到达的请求仍按旧属性判定。TTL 取 15 分钟、第 3 分钟停用账号,剩下的 12 分钟里这个账号照样放行。缩短 TTL 是压窗口的唯一旋钮,代价是刷新更频繁。

图 2-1 · 同一次请求在 claims 与回查两种取属性方式下的决策差异。可调 TTL、属性改动时刻与请求时刻,观察陈旧窗口的长度与窗口内的判定。

注 · 本系列前几页看不到这段窗口,因为 policy.ts 里的 SUBJECTS 是一组常量:属性没有版本、没有签发时刻,等价于假设 PIP 永远即时。图 2-1 是全系列唯一给属性配了时间维度的 demo,也只在这一页成立——它多出来的那个 TTL 参数在纯函数式的 decide 签名里无处安放,只能由调用方决定喂给它哪个版本的 subject。

3 · 用户权限与 OAuth scope 的交集

第三方 client 代表用户调用 API 时,有两道限制叠在一起:用户自己有哪些权限,以及用户批准了这个 client 多少。实际能力是两者的交集,取小的那一个。用户有权而 client 没申请,调不动;client 声明了而用户无权,同样调不动——scope 不能给用户凭空添权。

图 3-1 · 用户生效集与 token scope 求交得到 client 的实际能力。可勾选角色与已授权的 scope,观察落在交集外的两类能力各自因何被拒。

注 · 本节的 scope 与 AllowedScope:同一个 action,对谁做 的 scope 是两个不相干的概念,只是撞了名字。OAuth 的 scope 切的是「client 能代表用户做多少事」,它裁剪的是能力集合;AllowedScope 切的是「同一个动作能作用在哪些数据行上」,它裁剪的是数据范围。一次真实调用会先后被两者各裁一刀。

4 · 撤销的可行路径

凭证一经签发便脱离签发方的控制,撤销因此不是一个动作,而是几条各有代价的路:短 TTL 加 refresh token,让窗口自然收窄;jti 黑名单或用户级 token 版本号,登出即失效,代价是判定端从此有状态;introspection(RFC 7662)每次判定回问签发方一次,撤销即时,但这等于把 claims 退回成回查,§1 的成本又回来了。

警示 · 「登出」与「凭证失效」是两件事。清掉浏览器里的 access token 只删除了客户端手上的副本,已经泄漏出去的那一份在过期前照样能用。真正的登出要么等 TTL 走完,要么触发上面某条撤销路径——只把前端的 storage 清空,等于什么都没做。

5 · 参考文献

  1. Hardt, D. (Ed.). (2012). The OAuth 2.0 Authorization Framework. RFC 6749, IETF. scope 与授权委托模型的出处。rfc-editor.org
  2. Jones, M., Bradley, J., & Sakimura, N. (2015). JSON Web Token (JWT). RFC 7519, IETF. claims 的容器格式与 exp / iat 的语义。rfc-editor.org
  3. Richer, J. (Ed.). (2015). OAuth 2.0 Token Introspection. RFC 7662, IETF. 把 claims 退化成回查的标准接口。rfc-editor.org
  4. Lodderstedt, T., Dronia, S., & Scurtescu, M. (2013). OAuth 2.0 Token Revocation. RFC 7009, IETF. 撤销端点的定义。rfc-editor.org