RBAC
RBAC在用户和权限之间引入了“角色(Role)”的概念
用户关联角色,角色关联权限
每个用户关联一个或多个角色,每个角色关联一个或多个权限,从而可以实现了非常灵活的权限管理。角色可以根据实际业务需求灵活创建,这样就省去了每新增一个用户就要关联一遍所有权限的麻烦
casbin相关方法
// 初始化
func (casbinService *CasbinService) Casbin() *casbin.SyncedEnforcer {
once.Do(func() {
a, _ := gormadapter.NewAdapterByDB(global.GVA_DB) //设置数据库的表
syncedEnforcer, _ = casbin.NewSyncedEnforcer(global.GVA_CONFIG.Casbin.ModelPath, a)
//将模型与表关联
})
_ = syncedEnforcer.LoadPolicy() //读取策略,加载表的内容
return syncedEnforcer
}
// 添加策略
e := casbinService.Casbin()
success, _ := e.AddPolicies(rules)//全量策略
// 获取策略
e := casbinService.Casbin()
list := e.GetFilteredPolicy(0, authorityId)
//是否存在权限
模型
### 在官方restful基础上添加了角色组
[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)&& keyMatch2(r.obj, p.obj) && regexMatch(r.act, p.act)
示例代码
package main
import (
"fmt"
"github.com/casbin/casbin/v2"
gormadapter "github.com/casbin/gorm-adapter/v3"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
var (
syncedEnforcer *casbin.SyncedEnforcer //异步Enforcer,当策略改变时需要重新LoadPolicy
db *gorm.DB
)
// ConnDB 数据库链接
func ConnDB(user, password, host string, port int, Dbname string) *gorm.DB {
dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=True&loc=Local", user, password, host, port, Dbname)
//连接MYSQL, 获得DB类型实例,用于后面的数据库读写操作。
db_, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
panic("连接数据库失败, error=" + err.Error())
}
db = db_
return db
}
// CasbinInit 初始化
func CasbinInit(db *gorm.DB) {
a, err := gormadapter.NewAdapterByDB(db) //设置数据库的表
if err != nil {
panic("NewAdapterByDB, error=" + err.Error())
}
syncedEnforcer, err = casbin.NewSyncedEnforcer("./rbac.conf", a)
if err != nil {
panic("NewAdapterByDB, error=" + err.Error())
}
Casbin()
}
// 获取syncedEnforcer
func Casbin() *casbin.SyncedEnforcer {
err := syncedEnforcer.LoadPolicy() //读取策略,加载表的内容
if err != nil {
panic("LoadPolicy, error=" + err.Error())
}
return syncedEnforcer
}
// AddPolicy 添加策略
func AddPolicy(role, path, method string) bool {
e := Casbin()
rules := []string{role, path, method}
success, _ := e.AddPolicy(rules)
return success
}
// RemovePolicy 删除策略
func RemovePolicy(role, path, method string) bool {
e := Casbin()
rules := []string{role, path, method}
success, _ := e.RemovePolicy(rules)
return success
}
// GetFilteredPolicy 获取策略
func GetFilteredPolicy(role string) [][]string {
// 获取策略
e := Casbin()
return e.GetFilteredPolicy(0, role) //0就代表v0列,1就代表v1列
}
// Enforce 判断权限
func Enforce(sub, obj, act string) bool {
e := Casbin()
success, _ := e.Enforce(sub, obj, act)
return success
}
func main() {
ConnDB("root", "zz123456*", "localhost", 3306, "casbin")
CasbinInit(db)
e := Casbin()
AddPolicy("bob", "/api", "(POST)|(GET)") //同时新增多个act
e.AddRoleForUser("1112", "bob")
fmt.Println(e.GetPolicy()) //0就代表v0列,1就代表v1列
fmt.Println(Enforce("1112", "/api", "POST"))
}