casbin-权限管理
概要权限管理几乎是每个系统或者服务都会直接或者间接涉及的部分. 权限管理保障了资源(大部分时候就是数据)的安全,权限管理一般都是和业务强关联,每当有新的业务或者业务变化时,不能将精力完全放在业务实现上,权限的调整往往耗费大量的精力. 其实,权限的本质没有那么复杂,只是对访问的控制而已,有一套完善的访问控制接口,再加上简单的权限模型. 权限模型之所以能够简单,就是因为权限管理本身并不复杂,只是在和具体业务结合时,出现了各种各样的访问控制场景,才显得复杂. PERM 模型PERM(Policy,Effect,Request,Matchers)模型很简单,但是反映了权限的本质 – 访问控制
casbin 权限库casbin 使用了 PERM 模型来表达权限,并且提供了简单直接的 API. 核心概念model file用来定义具体的权限模型,目前支持的模型基本覆盖了常见的所有场景:
model file 定义语法casbin 是基于 PERM 的,所有 model file 中主要就是定义 PERM 4 个部分.
policy file定义具体的策略,权限的检查就是基于定义的 model file 和 policy file 来完成的. 相对于 model file 定义规则,policy file 中定义的就是具体的内容. RBAC 示例定义 model file[request_definition] r = sub,act [policy_definition] p = sub,act [role_definition] g = _,_ [policy_effect] e = some(where (p.eft == allow)) [matchers] m = g(r.sub,p.sub) && r.obj == p.obj && r.act == p.act 定义 policy filep,superAdmin,project,read p,write p,admin,asse,zhuangjia,shangshang,read g,quyuan,admin g,wenyin,zhuangjia 测试代码package rbac import ( "fmt" "log" "github.com/casbin/casbin" ) func TestRBAC() { e := casbin.NewEnforcer("rbac/rbac.conf","rbac/rbac.csv") fmt.Printf("RBAC test startn") // output for debug // superAdmin if e.Enforce("superAdmin","project","read") { log.Println("superAdmin can read project") } else { log.Fatal("ERROR: superAdmin can not read project") } if e.Enforce("superAdmin","write") { log.Println("superAdmin can write project") } else { log.Fatal("ERROR: superAdmin can not write project") } // admin if e.Enforce("quyuan","read") { log.Println("quyuan can read project") } else { log.Fatal("ERROR: quyuan can not read project") } if e.Enforce("quyuan","write") { log.Println("quyuan can write project") } else { log.Fatal("ERROR: quyuan can not write project") } if e.Enforce("quyuan","asse","read") { log.Println("quyuan can read asse") } else { log.Fatal("ERROR: quyuan can not read asse") } if e.Enforce("quyuan","write") { log.Println("quyuan can write asse") } else { log.Fatal("ERROR: quyuan can not write asse") } // zhuangjia if e.Enforce("wenyin","read") { log.Fatal("ERROR: wenyin can read project") } else { log.Println("wenyin can not read project") } if e.Enforce("wenyin","write") { log.Println("wenyin can write project") } else { log.Fatal("ERROR: wenyin can not write project") } if e.Enforce("wenyin","read") { log.Fatal("ERROR: wenyin can read asse") } else { log.Println("wenyin can not read asse") } if e.Enforce("wenyin","write") { log.Println("wenyin can write asse") } else { log.Fatal("ERROR: wenyin can not write asse") } // shangshang if e.Enforce("shangshang","read") { log.Println("shangshang can read project") } else { log.Fatal("ERROR: shangshang can not read project") } if e.Enforce("shangshang","write") { log.Fatal("ERROR: shangshang can write project") } else { log.Println("shangshang can not write project") } if e.Enforce("shangshang","read") { log.Println("shangshang can read asse") } else { log.Fatal("ERROR: shangshang can not read asse") } if e.Enforce("shangshang","write") { log.Fatal("ERROR: shangshang can write asse") } else { log.Println("shangshang can not write asse") } } 多租户示例定义 model file[request_definition] r = sub,dom,p.sub,r.dom) && r.dom == p.dom && r.obj == p.obj && r.act == p.act 定义 policy filep,gy,jn,write g,gy g,jn g,jn 测试代码package tenants import ( "fmt" "log" "github.com/casbin/casbin" ) // TestTenants test tenants func TestTenants() { e := casbin.NewEnforcer("tenants/tenants.conf","tenants/tenants.csv") fmt.Printf("RBAC TENANTS test startn") // output for debug // superAdmin if e.Enforce("superAdmin","gy","read") { log.Println("superAdmin can read project in gy") } else { log.Fatal("ERROR: superAdmin can not read project in gy") } if e.Enforce("superAdmin","write") { log.Println("superAdmin can write project in gy") } else { log.Fatal("ERROR: superAdmin can not write project in gy") } if e.Enforce("superAdmin","jn","read") { log.Println("superAdmin can read project in jn") } else { log.Fatal("ERROR: superAdmin can not read project in jn") } if e.Enforce("superAdmin","write") { log.Println("superAdmin can write project in jn") } else { log.Fatal("ERROR: superAdmin can not write project in jn") } // admin if e.Enforce("quyuan","read") { log.Println("quyuan can read project in gy") } else { log.Fatal("ERROR: quyuan can not read project in gy") } if e.Enforce("quyuan","write") { log.Println("quyuan can write project in gy") } else { log.Fatal("ERROR: quyuan can not write project in gy") } if e.Enforce("quyuan","read") { log.Fatal("ERROR: quyuan can read project in jn") } else { log.Println("quyuan can not read project in jn") } if e.Enforce("quyuan","write") { log.Fatal("ERROR: quyuan can write project in jn") } else { log.Println("quyuan can not write project in jn") } if e.Enforce("quyuan","read") { log.Fatal("ERROR: quyuan can read asse in gy") } else { log.Println("quyuan can not read asse in gy") } if e.Enforce("quyuan","write") { log.Fatal("ERROR: quyuan can write asse in gy") } else { log.Println("quyuan can not write asse in gy") } if e.Enforce("quyuan","read") { log.Println("quyuan can read asse in jn") } else { log.Fatal("ERROR: quyuan can not read asse in jn") } if e.Enforce("quyuan","write") { log.Println("quyuan can write asse in jn") } else { log.Fatal("ERROR: quyuan can not write asse in jn") } // wenyin if e.Enforce("wenyin","write") { log.Println("wenyin can write asse in gy") } else { log.Fatal("ERROR: wenyin can not write asse in gy") } if e.Enforce("wenyin","write") { log.Fatal("ERROR: wenyin can write asse in jn") } else { log.Println("wenyin can not write asse in jn") } // shangshang if e.Enforce("shangshang","write") { log.Println("shangshang can write project in jn") } else { log.Fatal("ERROR: shangshang can not write project in jn") } if e.Enforce("shangshang","write") { log.Fatal("ERROR: shangshang can write project in gy") } else { log.Println("shangshang can not write project in gy") } } 总结casbin 权限管理库比较简单,易上手,但是它的功能却不简单,支持了目前主流的所有权限管理场景. 在使用上,model file 和 poclicy file 的定义也简单明了,抽象出了权限管理最本质的东西. 将具体业务中的权限要求映射到 casbin 中 model file,就可以借助 casbin 的 API,快速的实现权限管理. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |