Model 语法
每个 model CONF 文件都必须定义以下四个部分:[request_definition]、[policy_definition]、[policy_effect] 和 [matchers]。
- 对于 RBAC,需要添加
[role_definition]部分。 - 对于带约束的 RBAC(例如职责分离),可以添加
[constraint_definition]。 - 以
#开头的行是注释;该行其余内容会被忽略。
请求定义(Request Definition)
[request_definition] 部分定义了传给 e.Enforce(...) 的参数。
[request_definition]
r = sub, obj, act
这里的 sub、obj 和 act 是标准三元组:subject(主体)、object(客体)和 action(操作)。你可以改变其格式——例如没有资源时用 sub, act,涉及两个主体时用 sub, sub2, obj, act。
Policy 定义(Policy Definition)
[policy_definition] 部分描述 policy 规则的结构。例如:
[policy_definition]
p = sub, obj, act
p2 = sub, act
对应的 policy 文件如下:
p, alice, data1, read
p2, bob, write-all-objects
policy 文件中的每一行都是一条规则。第一个 token 是 policy 类型(p、p2 等),并且必须与某个 policy 定义相对应。上面的示例会为 matcher 产生如下绑定:
(alice, data1, read) -> (p.sub, p.obj, p.act)
(bob, write-all-objects) -> (p2.sub, p2.act)
policy 规则的元素始终被视为字符串。相关讨论参见 casbin/casbin#113。
Policy 效果(Policy Effect)
[policy_effect] 部分定义了当多条 policy 同时匹配时(例如一条允许、另一条拒绝)如何组合结果。
[policy_effect]
e = some(where (p.eft == allow))
这产生allow-override(允许优先):只要任一匹配的 policy 的 effect 为 allow,结果就是允许。p.eft 字段表示 policy 的 effect(allow 或 deny)。它是可选的,省略时默认为 allow。
下面是另一种 policy effect:
[policy_effect]
e = !some(where (p.eft == deny))
这实现了 deny-override(拒绝优先):只有当没有匹配的 policy 的 effect 为 deny 时,结果才为允许。你可以用逻辑运算符组合表达式:
[policy_effect]
e = some(where (p.eft == allow)) && !some(where (p.eft == deny))
该表达式要求至少有一个 allow 且没有 deny。Casbin 同时支持 allow 和 deny;当两者同时匹配时,deny 优先。
policy effect 必须是下面列出的内置 effect 之一。当前实现不支持自定义的 effect 表达式。
可用的内置 policy effect:
| Policy Effect(策略效果) | Meaning(含义) | Example(示例) |
|---|---|---|
| some(where (p.eft == allow)) | allow-override(允许优先) | ACL, RBAC, etc. |
| !some(where (p.eft == deny)) | deny-override(拒绝优先) | Deny-override |
| some(where (p.eft == allow)) && !some(where (p.eft == deny)) | allow-and-deny(允许且拒绝) | Allow-and-deny |
| priority(p.eft) || deny | priority(优先级) | Priority |
| subjectPriority(p.eft) | priority based on role(基于角色的优先级) | Subject-Priority |
约束定义(Constraint Definition)
可选的 [constraint_definition] 部分为 RBAC 定义不变量(例如职责分离)。当角色分配发生变化时会检查约束。要使用约束,必须先有 [role_definition]。
[constraint_definition]
c = sod("finance_requester", "finance_approver")
c2 = sodMax(["payroll_view", "payroll_edit", "payroll_approve"], 1)
c3 = roleMax("superadmin", 2)
c4 = rolePre("db_admin", "security_trained")