最终生效集:User Override 怎么盖过 Role
一个用户可以同时挂多个角色(User → Role → Permission 的关系见 为什么 RBAC),权限先求并集。但角色是「粗粒度的包」, 总有个例:「这个编辑特别信任,额外给他导出权限」「那个管理员最近要冻结他的删除权」。 于是在角色之上再加一层用户级 Override。最终公式:
effective=
union(RolePermission)
−UserDeny
+UserAllow
顺序是关键:先减 Deny,再加 Allow —— 所以 Allow 后置、能盖过 Deny(显式放行优先)。
勾选用户的角色(union)
用户级 Deny(从并集里减掉)
用户级 Allow(额外加,可盖过 Deny)
✅ 最终生效的能力(can(x) 为真的)
− deny + allow 让 Allow 生效(后置)。不少企业系统采用相反策略:Deny 永远优先
(更保守,黑名单一律否决)。无论哪种,关键是团队统一、可解释——
排查问题时能直接说清「这条权限为什么有/没有」。
读懂上面的盒子
- union(Roles):所勾角色授予的权限并集(去重)。被 Deny 命中的会画上删除线。
- − Deny:命中并集的才真正被移除;Deny 一条角色本就没授予的权限,不产生任何效果。
- + Allow:并集里没有的才是「新增」(绿色);若 Allow 的恰好刚被 Deny 掉,它会把那条补回来。
- = Effective:最终
can(key)返回 true 的集合。
editor,在 Deny 里点 article:update —— 它从并集消失;
再在 Allow 里也点 article:update —— 它重新出现。这就是「Allow 盖过 Deny」。