权限系统测试:正确性、越权、一致性与性能

权限测试不能只用管理员账号点一遍页面。权限缺陷往往出现在反向路径:没有按钮但接口可调、列表过滤但详情直查、权限撤销但旧缓存仍有效、同一租户正常而跨租户 ID 可枚举。

测试目标不仅是防攻击,还要证明角色合并、ACL 继承、策略边界、生命周期和分布式一致性都符合设计。

权限测试矩阵

1. 建立权限矩阵

每个用例至少包含:

Subject × Resource × Action × Context × Expected Decision

还应断言 reasonCode、Scope、字段效果和 Obligations。例如:

主体 资源 操作 条件 预期
王芳 P1001 approve 8 万、MFA 有效 ALLOW
刘敏 P1001 approve 本人创建 DENY_SELF_APPROVAL
孙伟 O1001 read 华南用户访问华东订单 DENY_SCOPE_MISMATCH
Alice D1001 download 外部用户、机密文档 DENY_EXTERNAL_CONFIDENTIAL_DOWNLOAD
report-agent O1001 update 代表张三但 Agent 只读 DENY_AGENT_TOOL_SCOPE

每一个 Allow 至少要有一个相邻 Deny:金额刚超过边界、有效期刚结束、Scope 切换、MFA 缺失或资源属于另一租户。

2. 测试四个维度

  1. 正确性:模型算法是否符合设计。
  2. 安全性:能否横向、纵向或跨租户越权。
  3. 一致性:撤销和策略更新能否在所有节点及时生效。
  4. 性能:在真实用户、角色、ACL 和策略规模下是否满足延迟和吞吐目标。

3. 测试主体和数据

固定准备:

  • 无权限用户;
  • 单角色用户;
  • 多角色且 Scope 不同的用户;
  • 临时授权和已过期用户;
  • 跨部门和跨租户用户;
  • 租户管理员和平台管理员;
  • 服务账号、定时任务、第三方应用;
  • AI Agent 自身和代表用户两种模式。

测试数据要使用固定租户 T1001/T2001、固定组织和资源,避免测试之间临时创建不可追踪的角色。时间相关测试应使用可控 Clock,不依赖真实等待。

4. 横向、纵向和跨租户越权

三类越权

横向越权

张三把 O1001 的 ID 改为其他员工订单;枚举附件、历史版本、分享链接;批量接口中混入无权 ID;导出和搜索返回不属于自己的数据。

纵向越权

普通用户直接调用角色管理、策略发布、模拟用户和系统配置接口;修改请求中的 roleCode 或 action;利用 Mass Assignment 写入管理员字段。

跨租户越权

将 tenant 参数改为 T2001、访问 O2001、复用其他租户缓存 Key、搜索索引缺少 tenant filter、异步任务读取错误租户、对象存储路径未隔离。

测试不能只验证 HTTP 403,还要检查未授权数据是否出现在响应、日志、缓存、消息和指标标签中。

5. ACL 测试

至少覆盖:

  • 直接 Allow 与用户组 Allow;
  • 直接 Deny 与继承 Allow 冲突;
  • INHERIT、BREAK_COPY、BREAK_EMPTY;
  • 恢复继承;
  • 资源移动到更宽松目录;
  • 用户退出项目组后的缓存与 List Objects;
  • 分享链接到期、撤销、次数限制和密码;
  • 资源删除后对象存储签名 URL;
  • 外部用户下载机密文档。

属性化测试可以随机生成资源树和 ACE,验证算法始终满足“系统强制 Deny 不被普通 Allow 覆盖”“子资源不会反向赋予父资源权限”等不变量。

6. RBAC 测试

  • 直接和间接 Role Assignment;
  • 多角色权限并集但 Scope 分离;
  • 角色层级单继承、多继承和循环检测;
  • 继承不扩大作用域;
  • 静态互斥角色分配失败;
  • 动态职责分离在交易中生效;
  • 基数约束和前置条件;
  • 会话只激活部分角色;
  • 转岗撤销旧岗位来源,但保留其他有效来源;
  • 角色版本变化触发主体缓存失效。

7. ABAC 测试

使用表驱动方式覆盖属性边界:

@ParameterizedTest
@CsvSource({
    "99999, true",
    "100000, true",
    "100001, false"
})
void approval_limit_boundary(long amount, boolean expected) {
    Decision decision = policy.evaluate(request(amount));
    assertEquals(expected, decision.allowed());
}

还要测试:

  • 必需属性缺失 → Indeterminate → Deny;
  • 来源属性被客户端伪造;
  • Deny Overrides、First Applicable 和优先级;
  • 时间窗口起止边界和时区;
  • MFA、设备风险和代理会话;
  • 策略新旧版本 Shadow 差异;
  • Obligation 无法执行时拒绝。

8. 数据权限测试

同一业务语义必须覆盖:列表、详情、更新、删除、批量操作、统计、搜索、导出和异步任务。

重点断言:

  • tenant 条件始终存在;
  • O1001 对张三/李四允许,对孙伟拒绝;
  • O2001 对 T1001 任意普通主体拒绝;
  • 写 SQL 同时校验权限、状态和 version;
  • 字段在 API、导出、日志和缓存中都脱敏;
  • 分页 total 与实际授权结果一致;
  • 聚合数据不会泄露其他部门规模。

对于查询构造器和 MyBatis 拦截器,应使用 SQL 快照测试和真实数据库集成测试,避免字符串单元测试掩盖 JOIN/别名问题。

9. 生命周期和治理测试

  • 申请审批后授权立即生效;
  • 驳回和撤回不产生授权;
  • 临时授权在精确时间点到期;
  • 原授权撤销后委托同步失效;
  • 转岗回收旧 Scope;
  • 离职禁用身份、会话和授权;
  • 资源所有权转移;
  • 复核决定撤销后缓存和 Token 处理;
  • Deprecated 权限禁止新增授权但旧授权按迁移期规则执行。

10. 代理与 Agent 测试

管理员模拟张三时,系统应按张三权限执行,不能隐式叠加管理员权限;审计同时记录赵强和张三;模拟会话到期后拒绝。

Agent 测试包括:

  • Agent 自身没有的工具即使用户有权限也不能调用;
  • 用户没有的数据范围,Agent 不能通过提示词扩大;
  • 工具参数被提示注入修改时,执行端重新授权;
  • 高风险调用需要人工确认,确认 Token 不能重放到其他资源;
  • 日志记录 Agent、用户、工具、参数摘要和决策版本。

11. 缓存一致性和故障测试

一致性故障测试

模拟:

  • PermissionChanged 消息丢失;
  • 重复和乱序;
  • 节点离线后恢复;
  • Redis 故障;
  • 旧 Token;
  • 快照过期或签名损坏;
  • 策略节点版本不一致;
  • PIP 和审计服务超时。

高风险权限撤销后,测试在定义的安全窗口内所有节点都拒绝。不能只验证最终一致,要测量撤销传播延迟的 P95/P99。

12. 性能与容量

构造接近生产的数据分布:

  • 大量用户与组织成员;
  • 深层角色继承;
  • 百万级 ACL 和高扇出用户组;
  • 大型组织闭包表;
  • 大量策略和属性调用;
  • 冷缓存、热缓存和变更风暴。

指标:决策 P50/P95/P99、吞吐、缓存命中、PIP 延迟、List Objects 延迟、权限传播延迟和错误率。

性能测试不能只使用一个超级管理员,因为它可能走最短通配符路径;要覆盖普通用户、多 Scope 和大量关系的最坏情况。

13. 自动化测试分层

权限测试金字塔

单元测试

角色合并、ACL 继承、策略组合、Scope 集合运算和原因码。

策略与矩阵测试

参数化测试、属性边界、固定策略回归和不变量测试。

集成测试

真实数据库、缓存、消息和 PDP,验证 SQL、版本和失效。

端到端与安全测试

从前端/API 到数据库验证横向、纵向、跨租户越权和代理链路。

Shadow Decision

新旧权限系统同时决策,比较差异但只使用一方执行。差异必须人工分类,不能只追求百分之百一致。

14. 上线检查清单

模型

  • [ ] 每个 Action 都有明确权限编码和 Owner。
  • [ ] Scope 与权限成对保存。
  • [ ] ACL、RBAC、ABAC 冲突规则已文档化。
  • [ ] 角色层级无循环,高风险权限有职责分离。

数据

  • [ ] 列表、详情、导出、统计和写操作使用一致数据范围。
  • [ ] tenant 条件覆盖数据库、缓存、搜索、消息和文件。
  • [ ] 字段权限覆盖日志和导出。

生命周期

  • [ ] 临时权限自动到期。
  • [ ] 转岗和离职有自动回收流程。
  • [ ] 委托不超过原权限和有效期。
  • [ ] 权限和策略支持版本、废弃和回滚。

运行时

  • [ ] 权限撤销传播延迟达到目标。
  • [ ] 权限中心、PIP、缓存和审计故障策略已演练。
  • [ ] 高风险操作不使用过期快照放行。
  • [ ] 决策日志包含 Actor、Subject、reasonCode 和版本。

测试

  • [ ] 每个 Allow 有相邻 Deny 用例。
  • [ ] 已覆盖横向、纵向和跨租户越权。
  • [ ] 已覆盖非人主体、代理和 Agent。
  • [ ] 性能测试使用真实关系和权限分布。

15. 小结

权限测试的标准不是“正常用户能用”,而是能够系统性证明:允许路径正确、拒绝路径完整、生命周期及时、分布式节点一致,并且在生产规模下仍能稳定决策。权限模型、治理和运行时只有通过这套测试闭环,才真正成为可靠安全边界。

参考资料