casbin用来做权限认证。作用:我给某个用户分配角色,只有满足相应的匹配规则才能请求到资源。在gin框架中,就是某个用户用get/post等等方式访问某个接口的权限。
先来看perm模型
model中放的就是匹配规则,policy时事先给好的权限,为了数据灵活使用会人为添加到数据库中
request:是哪个用户用户使用哪种方式请求接口。
e就是允许还是不允许
在rbac模型中,会多一个角色域,g=用户,角色
即这个用户拥有这个角色的一切权限
在gin框架运用的整体思路就是先初始化casbin,调用LoadPolicy,请求每个接口时都经过一下casbin的中间件,在这里得到用户的完整信息,和匹配规则进行匹配即可。
casbin初始化代码
func Setup() (err error) {
//var err error
var Apter *gormAdapter.Adapter
var m model.Model
var e *casbin.SyncedEnforcer
// Initialize a gorm adapter with MySQL database. 使用MySQL数据库初始化gorm适配器。
Apter, err = gormAdapter.NewAdapterByDB(global.Eloquent)
if err != nil {
zap.L().Error("NewAdapterByDB()", zap.Error(err))
return err
}
// NewModelFromString从包含模型文本的字符串创建模型
m, err = model.NewModelFromString(text)
if err != nil {
zap.L().Error("NewModelFromString()", zap.Error(err))
return err
}
//NewSyncedEnforcer通过file或DB创建一个同步强制器
e, err = casbin.NewSyncedEnforcer(m, Apter)
if err != nil {
zap.L().Error("NewSyncedEnforcer()", zap.Error(err))
return err
}
global.CasbinEnforcer = e
return nil
}
func LoadPolicy() (*casbin.SyncedEnforcer, error) {
if err := global.CasbinEnforcer.LoadPolicy(); err == nil {
return global.CasbinEnforcer, err
} else {
zap.L().Error("casbin rbac_model or policy init error, message: %v \r\n", zap.Error(err))
return nil, err
}
}
权限检查中间件
//权限检查中间件
func AuthCheckRole() gin.HandlerFunc {
return func(c *gin.Context) {
data := new(api.UserInfo)
var role []string
var err error
userInfo, err := api.GetUserData(c)
data = userInfo
roles := data.Roles
for _, v := range *roles {
role = append(role, utils.IntToString(v.ID))
}
if err != nil {
c.Abort()
return
}
e, err := mycasbin.LoadPolicy()
if err != nil {
c.Abort()
return
}
//检查权限
//此处为多角色 要在做处理
var res bool
for _, roleID := range role {
res, err = e.Enforce(roleID, c.Request.URL.Path, c.Request.Method)
if err != nil {
c.Abort()
return
}
if res {
break
}
}
if res {
c.Next()
} else {
app.ResponseError(c, app.CodeIdentityNotRow)
c.Abort()
return
}
}
}
匹配规则
[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.sub == p.sub && keyMatch(r.obj, p.obj) && regexMatch(r.act, p.act)