题目重点:把用户角色和资源操作的授权拆开,给出继承、显式拒绝、缓存失效和审计的确定性决策顺序。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 训练策略:同租户资源组成树,用户可有多角色;显式 deny 高于 allow,沿目标资源到祖先寻找适用规则;越权和跨租户默认拒绝。
- deny 优先级和审计字段是面试深挖设计选择,不把它说成原题唯一规则。
解题路线
- 数据模型含 UserRole(user,role,tenant)、Permission(role,resource,action,effect,version)、Resource(id,parent,tenant);检查请求前先认证主体、验证同租户,再收集角色与资源祖先。
- 决策顺序明示:有任意适用 deny 则拒绝,否则有 allow 则允许,其余默认拒绝;若要求‘最近节点覆盖祖先’,需改成按深度选择,不能与全局 deny 规则混用。
- 授权缓存 key 需包括用户、资源、操作、租户和策略版本;变更角色或权限后提升版本/主动失效,尤其撤权不能长期使用旧 allow。
- 每次关键决策记录主体、资源、操作、允许/拒绝、匹配规则与版本、时间和请求 ID;审计落盘失败时如何处理敏感操作须预先决定。
手动走一遍
角色 editor 在 `/team` 上有 read allow,则 `/team/report` 可继承读;若子目录上有 read deny,按本训练规则读报告会拒绝。把 editor 从用户移除后,缓存版本变化使旧 allow 不再生效。
规模与取舍
若资源树高度 h、用户角色数 r,朴素检查最多 O(h×r×每层规则查找);索引规则可把每层查找降为期望 O(1),缓存命中近 O(1),代价是更新失效和陈旧窗口。
易错点与追问
容易失分的边界
- 只检查直接角色,不检查祖先资源。
- 没定 allow/deny 冲突优先级,线上决策不可预测。
- 撤权后缓存继续允许。
- 资源路径字符串前缀如 `/a` 错把 `/ab` 当子资源。
- 审计只记结果不记匹配规则版本,无法复盘。
继续深挖
- 如何避免租户跨界继承?
- 最近节点覆盖和 deny 优先两种策略各有什么取舍?
- 角色变更后如何快速失效海量权限缓存?
- 策略更新与审计写入如何保持一致?
