安装
$ go get github.com/casbin/casbin/v2
import "github.com/casbin/casbin/v2"
func main() {
e, err := casbin.NewEnforcer("path/to/model.conf", "path/to/policy.csv")
}
创建文件
在当前目录下创建model.conf
与policy.csv
文件,JetBrains有Casbin插件,如果装有该插件,model.conf
图标会变
model.conf
内装的就是模型,policy.csv
装的就是policy(暂时先用csv装一下)
示例:
[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 && r.obj == p.obj && r.act == p.act
p,zhangsan,data1,read
开始用
package main
import (
"fmt"
"github.com/casbin/casbin/v2"
)
func main() {
e, err := casbin.NewEnforcer("model.conf", "policy.csv")
sub := "alice"
obj := "data1"
act := "read"
ok, err := e.Enforce(sub, obj, act)
if err != nil {
fmt.Println(err)
return
}
if ok == true {
fmt.Println("允许alice的操作")
} else {
fmt.Println("拒绝alice的操作")
}
}
此时运行结果一定是
拒绝alice的操作
进程 已完成,退出代码为 0
因为alice没有在policy中给予任何权限
查询指定字段的policy
GetFilteredPolicy()
GetFilteredPolicy 获取策略中的所有授权规则,我们可以指定字段筛选器。
例如:
filteredPolicy := e.GetFilteredPolicy(0, "alice")
v0字段:存放到数据库中的policy有这样几列
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4wq5VXp0-1651581293719)(casbin图片/image-20220503172422514.png)]
而v0字段就是sub字段
适配器
全部适配器
gorm 适配器
gorm适配器
直接把这玩意儿粘贴过去就行,这玩意儿就在github的readme里
import (
"github.com/casbin/casbin/v2"
gormadapter "github.com/casbin/gorm-adapter/v3"
_ "github.com/go-sql-driver/mysql"
)
func main(){
a, _ := gormadapter.NewAdapter("mysql", "mysql_username:mysql_password@tcp(127.0.0.1:3306)/")
e, _ := casbin.NewEnforcer("./model.conf", a)
}
增删改查Policy
增
这里就先使用AddPolicy()
来写增,其他的查API
addPolicy, err := e.AddPolicy("alice", "data2", "read")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(addPolicy)
增加一个grouping
这一步一定要注意看自己的Model是否有,否则会报错
[role_definition]
g = _, _
[matchers]
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act
added,err := e.AddGroupingPolicy("alice", "data1_admin")
fmt.Println(added)
fmt.Println(err)
删
用RemovePolicy()
,其他查api
removed, err := e.RemovePolicy("alice", "data2", "read")
删 groupingPolicy 用RemoveGroupingPolicy()
改
用UpdatePolicy()
改,其他查api
func (e *Enforcer) UpdatePolicy(oldPolicy []string, newPolicy []string) (bool, error)
updated, err := e.UpdatePolicy([]string{"alice", "data1", "read"}, []string{"alice", "data2", "read"})
改groupingPolicy查api
查
policy := e.GetPolicy()
fmt.Println(policy)
自定义函数
首先自己写一个函数,返回一个布尔类型
func KeyMatch(key1 string, key2 string) bool {
return key1 == key2
}
然后用interface{}
类型的接口包装它
func KeyMatchFunc(args ...interface{}) (interface{},error){
name1 := args[0].(string)
name2 := args[1].(string)
return (bool)(keyMatch(name1,name2)),nil
}
最后在casbin的执行者(enforcer)中注册这个函数
e.AddFunction("my_func",KeyMatchFunc)
最后便可在模型conf中使用这个函数
[matchers]
m = my_func(r.sub, p.sub) && r.obj == p.obj && r.act == p.act
记了一点点的api
Casbin API
添加权限
AddPolicy()
AddPolicy 向当前策略添加授权规则。 如果规则已经存在,函数返回false,并且不会添加规则。 否则,函数通过添加新规则并返回true。
如果当前的policy是在本地的csv文件中存储,则这条policy不会添加进csv文件中
但在数据库中存储的话,这条policy会存进数据表中
added, err := e.AddPolicy('eve', 'data3', 'read')
查询所有policy
policy := e.GetPolicy()
PERM元模型
定义一个策略(Policy) 定义一个匹配规则(Matchers) 通过请求(Request)过来的参数与策略通过规则进行匹配获得一个影响(Effect),拿到影响的结果,进到影响的表达式,返回一个布尔值
PERM(Policy Effect Request Matchers)
Policy策略
一般存储到数据库
p = {sub, obj, act, eft}
[policy_definition]
p = sub,obj,act
Matchers 匹配规则
Request和Policy的匹配规则
m = r.sub == p.sub && r.act == p.act && r.obj == p.obj
Effect 影响
支持的Policy effects如下:
Policy effect | 意义 |
---|
some(where (p.eft == allow)) | 只要有一个allow就通过 |
!some(where (p.eft == deny)) | 没有deny就通过 |
some(where (p.eft == allow)) && !some(where (p.eft == deny)) | 有allow并且没有deny通过 |
priority(p.eft) || deny | priority |
subjectPriority(p.eft) | 基于角色的优先级 |
Request 请求
r = {sub, obj, act}
ACL
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act // 这里不加 ', eft'的话,police_effect就没有用到
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act
p, alice, data1, read
p, bob, data2, write
alice, data1, read
true
RBAC
单商户模型
和ACL模型相比,多了一个[role_definition] g后面的两个横线,一个表示用户,一个表示角色,
在[matchers]中,也有了g(r.sub, p.sub)
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, 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
p, alice, data1, read
p, bob, data2, write
p, data2_admin, data2, read
p, data2_admin, data2, write
g, alice, data2_admin
Policy最后一行,用户alice有作为data2_admin角色,感觉就像是alice他有另一个马甲,叫做data2_admin,这两个都是它的身份,像一个人,他既是作为游戏开发者,也是作为玩家,这两个都是它的身份,而他既能行驶玩家的权限,游玩游戏,又能作为开发者,修改自己游戏的数据。
alice, data2, read
true
RBAC with domains/tenants
多商户模型
与单商户模型相比,又多了一个domains
在[request_definition],[policy_definition]中,都多出来了一个dom
[role_definition]多出一条横线
[request_definition]
r = sub, dom, obj, act
[policy_definition]
p = sub, dom, obj, act
[role_definition]
g = _, _, _
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = g(r.sub, p.sub, r.dom) && r.dom == p.dom && r.obj == p.obj && r.act == p.act
p, admin, domain1, data1, read
p, admin, domain1, data1, write
p, admin, domain2, data2, read
p, admin, domain2, data2, write
g, alice, admin, domain1
g, bob, admin, domain2
对于domain(域)我的理解是,
像一个人,他是一个游戏玩家,还是一个游戏开发者,在电脑上(domain1),他可以行驶游戏角色的权利,对其他角色发起攻击,他也行驶游戏开发者的权利,修改自己角色数值。离开了电脑,到现实世界(domain2),他作为游戏玩家,什么都做不了,但作为游戏开发者,他有领取薪水的权利
alice, domain1, data1, read
true
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)