ACL不宜直接构建多租户权限体系,应作为底层能力嵌入租户感知模型;需前置注入tenant_id实现逻辑隔离,分层协作RBAC(管角色成员)与ACL(管资源操作),并通过通配、继承、动作组压缩策略,审计日志须按租户维度聚合。

Access Control Lists(ACL)本身不是为多租户权限隔离而设计的,直接用它构建“复杂租户权限隔离体系”容易走入误区——ACL适合资源粒度明确、主体固定、规则静态的访问控制场景,而多租户系统通常要求租户间逻辑强隔离、策略动态可配、权限可继承与组合。因此,真正可行的做法是:以ACL为底层能力之一,嵌入更上层的租户感知权限模型中,而非把ACL当核心架构。
租户上下文必须前置注入
ACL规则若不绑定租户标识(如 tenant_id),就无法区分“A租户的用户能否读B租户的订单”。所有数据访问路径(SQL查询、API入口、服务调用)需在执行前完成租户识别(如从JWT、HTTP Header或数据库连接池上下文提取tenant_id),并将其作为隐式过滤条件或ACL校验输入。否则ACL规则会跨租户生效,造成越权。
- 数据库层:在ORM或DAO中自动拼接 WHERE tenant_id = ?,禁止应用层裸写SQL绕过
- 服务层:用拦截器/Filter统一解析租户ID,并透传至权限检查模块
- ACL引擎:每条规则应含 tenant_id 字段,校验时强制匹配当前请求租户
ACL只管“资源-操作”,不管“租户-角色-成员”关系
租户内的权限分配(比如“财务组可导出报表”)属于RBAC范畴;ACL更适合表达“资源X允许角色Y执行操作Z”。二者要分层协作:RBAC解决“谁属于谁”,ACL解决“谁能对什么做什么”。例如:
- 租户T1定义角色:admin、analyst、viewer
- 用户U1属于T1的analyst角色
- ACL规则:(tenant=T1, role=analyst, resource=report, action=export) → allow
这样,ACL不存储用户列表,也不处理租户创建/删除,只专注授权决策,保持轻量可缓存。
避免ACL规则爆炸,用通配与继承压缩策略集
每个租户单独配置上百条ACL规则不可维护。应支持:
- 资源路径通配:report/* 允许 analist 导出,比逐条配 report/q1、report/q2 更可持续
- 租户模板继承:新建租户时,自动继承“标准SaaS模板”的ACL基线,再叠加定制规则
- 操作分组抽象:将 export、download、print 归为 “data_export” 动作组,ACL按组授权,降低规则数量
审计与变更必须带租户维度
ACL修改日志、访问拒绝日志、权限诊断工具,全部需按 tenant_id 聚合与检索。否则运维时无法快速判断:“是T5租户的规则写错了,还是全量策略同步失败?” 建议在ACL存储(如PostgreSQL表或Redis Hash)中,将 tenant_id 作为主键前缀或分区字段,确保查询和清理都天然租户隔离。

















