- Model CONF 至少应包含四个部分:
[request_definition], [policy_definition], [policy_effect], [matchers]
。 - 如果 model 使用 RBAC, 还需要添加
[role_definition]
部分。 - Model CONF 文件可以包含注释。注释以
#
开头,#
会注释该行剩余部分。
Request定义
[request_definition]
部分用于request的定义,它明确了 e.Enforce(...)
函数中参数的含义。
[request_definition]
r = sub, obj, act
sub, obj, act
表示经典三元组: 访问实体 (Subject),访问资源 (Object) 和访问方法 (Action)。 但是, 你可以自定义你自己的请求表单, 如果不需要指定特定资源,则可以这样定义 sub、act
,或者如果有两个访问实体, 则为 sub、sub2、obj、act
。
Policy定义
[policy_definition]
部分是对policy的定义,以下文的 model 配置为例:
[policy_definition]
p = sub, obj, act
p2 = sub, act
这些是我们对policy规则的具体描述
p, alice, data1, read
p2, bob, write-all-objects
policy部分的每一行称之为一个策略规则, 每条策略规则通常以形如p
, p2
的policy type
开头。 如果存在多个policy定义,那么我们会根据前文提到的policy type
与具体的某条定义匹配。 上面的policy的绑定关系将会在matcher中使用, 罗列如下:
(alice, data1, read) -> (p.sub, p.obj, p.act)
(bob, write-all-objects) -> (p2.sub, p2.act)
NOTE
当前只支持形如 p
的单个policy定义. p2
类型的尚未支持。 通常情况下, 用户无需使用多个 policy 定义, 如果您有其他情形的policy定义诉求,请在 https://github.com/casbin/casbin/issues/new 提出issue告知我们。
TIP
Policy rule中的元素总会被视作string
。如果您对此有任何疑问,请查看讨论:https://github.com/casbin/casbin/issues/113
Policy effect定义
[policy_effect]
部分是对policy生效范围的定义, 原语定义了当多个policy rule同时匹配访问请求request时,该如何对多个决策结果进行集成以实现统一决策。 以下示例展示了一个只有一条规则生效,其余都被拒绝的情况:
[policy_effect]
e = some(where (p.eft == allow))
该Effect原语表示如果存在任意一个决策结果为allow
的匹配规则,则最终决策结果为allow
,即allow-override。 其中p.eft
表示策略规则的决策结果,可以为allow
或者deny
,当不指定规则的决策结果时,取默认值allow
。 通常情况下,policy的p.eft
默认为allow
, 因此前面例子中都使用了这个默认值。
这是另一个policy effect的例子:
[policy_effect]
e = !some(where (p.eft == deny))
该Effect原语表示不存在任何决策结果为deny
的匹配规则,则最终决策结果为allow
,即deny-override。 some
量词判断是否存在一条策略规则满足匹配器。 any
量词则判断是否所有的策略规则都满足匹配器 (此处未使用)。 policy effect还可以利用逻辑运算符进行连接:
[policy_effect]
e = some(where (p.eft == allow)) && !some(where (p.eft == deny))
该Effect原语表示当至少存在一个决策结果为allow
的匹配规则,且不存在决策结果为deny
的匹配规则时,则最终决策结果为allow
。 这时allow
授权和deny
授权同时存在,但是deny
优先。
NOTE
尽管我们设计了政策效果的语法。 目前的执行只是使用硬编码的政策效果,因为我们认为这种灵活性没有多大必要。 目前为止你必须使用内置的 policy effects,不能自定义。
支持的 policy effects 如下:
Policy effect | 意义 | 示例 |
---|---|---|
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 |
匹配器
matchers
定义了策略匹配者。匹配者是一组表达式。它定义了如何根据请求来匹配策略规则
[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act
上面的这个匹配器是最简单的,它表示请求的三元组:主题、对象、行为都应该匹配策略规则中的表达式。
在匹配器中,你可以使用算术运算符如 +, -, * , /
,也可以使用逻辑运算符如:&&,||,!
。
NOTE
虽然看起来会有多个匹配器,比如m1、m2,就像其他基元一样,但目前我们只支持一个匹配器m。您总是可以使用上面的逻辑运算符在一个匹配器中实现复杂的逻辑判断。所以我们认为目前没有必要支持多个匹配器。如果你有其他意见,请告诉我。
不同语言的Casbin实现使用的表达式运算器有:
实现 | 语言 | 表达式运算器 |
---|---|---|
Casbin | Golang | https://github.com/Knetic/govaluate |
jCasbin | Java | https://github.com/killme2008/aviator |
Node-Casbin | Node.js | https://github.com/donmccurdy/expression-eval |
PHP-Casbin | PHP | https://github.com/symfony/expression-language |
PyCasbin | Python | https://github.com/danthedeckie/simpleeval |
Casbin.NET | C# | https://github.com/davideicardi/DynamicExpresso |
Casbin4D | Delphi | https://github.com/casbin4d/Casbin4D/tree/master/SourceCode/Common/Third%20Party/TExpressionParser |
casbin-rs | Rust | https://github.com/jonathandturner/rhai |
NOTE
如果你遇到关于Casbin的性能问题,这可能是表达式运算器效率低下造成的。 您可以直接发送issue到Casbin或表达式运算器的开发团队以获得提高效率的建议。 详见 性能基准测试 部分。