Golang 权限管理库 Casbin

  1. 代码示例
  • Model语法
    1. Request定义
    2. Policy定义
    3. Policy effect定义
    4. Matchers
      1. Expression evaluator
  • 代码示例

    1. 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 == "*")
      
    2. policy文件

      p, admin, /*, *
      p, anonymous, /login, POST
      p, member, /logout, GET
      p, member, /member/*, GET
      
    3. 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, p2policy 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

    目录