一、使用数据库存储 policy
使用gorm适配器进行存储
- 首先引用包
go get github.com/casbin/gorm-adapter
go get github.com/casbin/gorm-adapter/v3
go get github.com/go-sql-driver/mysql
- 其次给数据库建一个casbin数据库
- 下面是一个基础用法,详细看注释
package main
import (
"fmt"
"github.com/casbin/casbin/v2"
gormadapter "github.com/casbin/gorm-adapter/v3"
_ "github.com/go-sql-driver/mysql"
)
func main() {
a, _ := gormadapter.NewAdapter("mysql", "root:u_password@tcp(127.0.0.1:3306)/casbin",true) // Your driver and data source. 后面的参数true是自动建表
e, _ := casbin.NewEnforcer("./model.conf", a)
sub := "alice" // 想要访问资源的用户。
obj := "data1" // 将被访问的资源。
act := "read" // 用户对资源执行的操作。
added, err := e.AddPolicy("alice", "data1", "read") // 给数据库添加数据
fmt.Println(added) // 第一次添加成功就为true,第二次就为false,因为已经存在了这个数据
fmt.Println(err)
ok, err := e.Enforce(sub, obj, act)
if err != nil {
// 处理err
fmt.Println(err)
}
if ok == true {
// 允许alice读取data1
fmt.Println("access")
} else {
// 拒绝请求,抛出异常
fmt.Println("not access")
}
}
输出
/*
true
<nil>
access
*/
下面是数据库之中自动建表的字段
二、go实现增删改查操作
// 添加单个角色
added, err := e.AddGroupingPolicy("alice", "data2_admin") // 这就是给alice这个角色添加到data2_admin组
// 需要在model.conf 里面添加 [role_definition] g = _, _
// 添加多个角色
rules := [][] string {
[]string {"alex", "data1", "read"},
[]string {"mita", "data1", "write"},
[]string {"rivo", "data1", "read"},
[]string {"brooks", "data1", "write"},
}
areRulesAdded := e.AddGroupingPolicies(rules)
// 类型为g的
added := e.AddNamedGroupingPolicy("g", "alice", "data2_admin")
// 添加多个
rules := [][] string {
[]string {"jack", "data4", "read"},
[]string {"katy", "data4", "write"},
[]string {"leyo", "data4", "read"},
[]string {"ham", "data4", "write"},
}
areRulesAdded := e.AddNamedGroupingPolicies("g", rules)
removed, err := e.RemoveFilteredGroupingPolicy(0, "alice") // 指定字段删除alice数据,0代表的就是数据库里面的v0字段,当然会删除所有的alice字段,其余的都大同小异,和增加方法差不多
// UpdatePolicy 把旧的策略更新到新的策略
updated, err := e.UpdatePolicy([]string{"alice", "data1", "read"}, []string{"alice", "data3", " read"})
// UpdatePolicies 将所有的旧策略更新到新策略
updated, err := e.UpdatePolicies([][]string{{"eve", "data3", "read"}, {"jack", "data3", "read"}}, [][]string{{"eve", "data3", "write"}, {"jack", "data3", "write"}})
// GetFilteredPolicy 获取策略中的所有授权规则,我们可以指定字段筛选器。
filteredPolicy := e.GetFilteredPolicy(0, "alice")
// GetNamedPolicy 获取命名策略中的所有授权规则
namedPolicy := e.GetNamedPolicy("p")
// GetFilteredGroupingPolicy 获取策略中的所有角色继承规则,可以指定字段筛选器。
filteredGroupingPolicy := e.GetFilteredGroupingPolicy(0, "alice")
// GetNamedGroupingPolicy 获取策略中的所有角色继承规则。
namedGroupingPolicy := e.GetNamedGroupingPolicy("g")
// HasNamedPolicy 判断这个名字的权限类型是否存在
hasNamedPolicy := e.HasNamedPolicy("p", "data2_admin", "data2", "read")
三、自定义比较函数
我们可以自定义比较函数,其实g匹配规则的内核原理也和这个差不多
// 在函数里面执行这个 KeyMatchFunc 函数
e.AddFunction("my_func", KeyMatchFunc)
// KeyMatch 比较规则,实际就是做了层包装,里面的规则看自己需要做修改
func KeyMatch(key1 string, key2 string) bool {
i := strings.Index(key2, "*")
if i == -1 {
return key1 == key2
}
if len(key1) > i {
return key1[:i] == key2[:i]
}
return key1 == key2[:i]
}
// KeyMatchFunc 用一个接口类型封装它
func KeyMatchFunc(args ...interface{}) (interface{}, error) {
name1 := args[0].(string)
name2 := args[1].(string)
return (bool)(KeyMatch(name1, name2)), nil
}
// 现在就可以在 model.conf 里面使用这个函数了
[matchers]
m = r.sub == p.sub && my_func(r.obj, p.obj) && r.act == p.act