2.1 认证和授权要分开
认证回答“你是谁”,涉及登录名、密码、API Key、OAuth、MFA 等。授权回答“这个身份现在能做什么”。本教材从请求已经得到一个 Odoo Environment 开始。
Environment 的核心安全状态是:
| 属性 | 含义 |
|---|---|
cr |
当前数据库事务游标 |
uid |
当前用户 ID |
context |
语言、当前启用公司等请求上下文 |
su |
是否处于超级用户模式 |
源码入口:odoo/api.py:529-634。UID=1 按约定始终处于超级用户模式。env.user 返回的是以 sudo 读取的当前用户记录,目的是避免读取当前用户本身时递归触发权限,并不意味着当前业务 recordset 已经 sudo,见 odoo/api.py:670-676。
2.2 分层而不是一张万能权限表
Odoo 没有把所有权限塞进一个“角色-资源-操作”大表,而是拆成多层:
- 组:复用授权配置,并表达隐含关系。
- ACL:规定某个模型的 CRUD 能力上限。
- 记录规则:把模型中的记录按 domain 切成可访问范围。
- 字段组:保护模型中的敏感字段。
- 业务代码:表达 CRUD 无法描述的审批状态、额度、职责分离。
- UI 元数据:按角色裁剪工作台,降低干扰。
这样做的核心好处是模块化和组合性。代价是“最终有效权限”分散在多处,管理员很难直接解释某个用户为什么能或不能做一件事。
2.3 默认拒绝和默认允许并存
两层默认语义不同:
- ACL:没有任何适用 grant 时,默认拒绝该模型操作。
- 记录规则:ACL 已放行且没有任何适用规则时,记录范围默认全部允许。
因此,新模型若只建规则但忘记 ACL,任何规则都救不了;若只建 ACL 却忘记记录规则,获得 ACL 的用户通常可以访问模型中的全部记录。
2.4 UI 和安全边界为什么分离
菜单和视图需要快速生成,并允许同一业务功能从菜单、消息链接、收藏、RPC、移动端等多个入口访问。Odoo 因此把它们定位为工作台和呈现层,而把最终授权放在 ORM 和业务方法中。
这是一种合理的架构分工,但开发者必须承担一个责任:任何公开模型方法、控制器和报表入口都不能假设调用者一定先经过了那个按钮或菜单。
老赵解读
Odoo 权限体系的成熟之处,在于它没有试图用一张万能权限表解决所有问题。ACL、记录规则、字段组、业务方法和界面裁剪各司其职。真正的工程能力,是知道一条需求该落在哪一层,并让最终约束尽量靠近数据和业务动作,而不是停在“用户看不见按钮”。
目前没有任何评论。