Golang 权限管理库 Casbin
代码示例
model文件
[request_definition] r = sub, obj, act [policy_definition] p = sub, obj, act [policy_effect] e = some(where (p.eft == allow)) [matchers] m = r.sub == p.sub && keyMatch(r.obj, p.obj) && (r.act == p.act || p.act == "*")
policy文件
p, admin, /*, * p, anonymous, /login, POST p, member, /logout, GET p, member, /member/*, GET
go代码
package main import ( "github.com/casbin/casbin" "github.com/gin-gonic/gin" "log" "net/http" ) var ( webEng *gin.Engine enforce *casbin.Enforcer ) func main() { var err error enforce, err = casbin.NewEnforcerSafe("./model.conf", "./policy.csv") if err != nil { log.Fatalln(err) } webEng = gin.Default() webEng.GET("/", Home) webEng.POST("/login", Login) webEng.GET("/logout", Logout) webEng.GET("/member/", Member) webEng.Run() } func Member(c *gin.Context) { role, path, method := getParams(c) result, err := enforce.EnforceSafe(role, path, method) c.JSONP(http.StatusOK, gin.H{ "result": result, "err": err, }) } func Logout(c *gin.Context) { role, path, method := getParams(c) result, err := enforce.EnforceSafe(role, path, method) c.JSONP(http.StatusOK, gin.H{ "result": result, "err": err, }) } func Login(c *gin.Context) { role, path, method := getParams(c) result, err := enforce.EnforceSafe(role, path, method) c.JSONP(http.StatusOK, gin.H{ "result": result, "err": err, }) } func Home(c *gin.Context) { role, path, method := getParams(c) result, err := enforce.EnforceSafe(role, path, method) c.JSONP(http.StatusOK, gin.H{ "result": result, "err": err, }) } func getParams(c *gin.Context) (role, path, method string) { role = c.DefaultQuery("role", "guest") path = c.Request.URL.Path method = c.Request.Method log.Printf("\trole=%s path=%s method=%s\n", role, path, method) return }
Model语法
Model CONF 至少应包含四个部分:
[request_definition], [policy_definition], [policy_effect], [matchers]
。如果 model 使用 RBAC, 还需要添加
[role_definition]
部分。model配置文件可以包含注释信息。注释信息以
#
开始,直至行尾结束。
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)
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
优先。
The supported built-in policy effects are:
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 |
Matchers
[matchers]
is the definition for policy matchers. The matchers are expressions. It defines how the policy rules are evaluated against the request.
[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act
The above matcher is the simplest, it means that the subject, object and action in a request should match the ones in a policy rule.
You can use arithmetic like +, -, *, /
and logical operators like &&, ||, !
in matchers.
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:
Implementation | Language | Expression evaluator |
---|---|---|
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](https://github.com/casbin4d/Casbin4D/tree/master/SourceCode/Common/Third Party/TExpressionParser) |
casbin-rs | Rust | https://github.com/jonathandturner/rhai |
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 irvin.em@live.com。
文章标题:Golang 权限管理库 Casbin
文章字数:1.3k
本文作者:dino
发布时间:2019-11-20, 23:30:26
最后更新:2019-12-02, 15:35:05
原始链接:https://blog.walkbc.com/2019/11/20/casbin/版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。
QQ交流群:273078549