Model语法

  • 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 Although it seems like there will be multiple matchers such as m1, m2 like other primitives, currently, we only support one matcher m. 通常情况下,您可以在一个matcher中使用上文提到的逻辑运算符来实现复杂的逻辑判断, 因此,我们认为现在没有必要支持多个匹配器。 如果您对此有疑问,请告知我们(https://github.com/casbin/casbin/issues)。

Speical Grammer
You could also use in, the only operator with a text name. This operator checks the right-hand side array to see if it contains a value that is equal to the left-side value. Equality is determined by the use of the == operator, and this library doesn’t check types between the values. Any two values, when cast to interface{}, and can still be checked for equality with == will act as expected. Note that you can use a parameter for the array, but it must be an []interface{}.

Also refer to rbac_model_matcher_using_in_op, keyget2_model and keyget_model

Example:

[request_definition]
r = sub, obj
...
[matchers]
m = r.sub.Name in (r.obj.Admins)
e.Enforce(Sub{Name: "alice"}, Obj{Name: "a book", Admins: []interface{}{"alice", "bob"}})

Expression evaluator
The matcher evaluation in Casbin is implemented by expression evaluators in each language. Casbin integrates their powers to provide the unified PERM language. Besides all the model syntax provided here, those expression evaluators may provide extra functionality, which may be not supported by another language or implementation. Use it at your own risk.

The expression evaluators used by each Casbin implementation are:

实现 语言 表达式运算器
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/DynamicExpressohttps://github.com/casbin4d/Casbin4D/tree/master/SourceCode/Conce/Third%20Party/TExpressionParser
Casbin4D Delphi https://github.com/casbin4d/Casbin4D/tree/master/SourceCode/Conce/Third%20Party/TExpressionParser
casbin-rs Rust https://github.com/jonathandturner/rhai

NOTE
If you encounter performance issue about Casbin, it’s probably caused by the low efficiency of the expression evaluator. You can both send issue to Casbin or the expression evaluator directly for advice to speed up. See Benchmarks section for details.

最后编辑: kuteng  文档更新时间: 2021-06-22 19:03   作者:kuteng