介绍
权限管理在几乎每个系统中都是必备的模块。如果项目开发每次都要实现一次权限管理,无疑会浪费开发时间,增加开发成本。因此,casbin库出现了。casbin是一个强大、高效的访问控制库。支持常用的多种访问控制模型,如ACL/RBAC/ABAC等。可以实现灵活的访问权限控制。同时,casbin支持多种编程语言,Go/Java/Node/PHP/Python/.NET/Rust。我们只需要一次学习,多处运用。
特征
- 以经典{subject, object, action}形式或您定义的自定义形式实施策略,同时支持允许和拒绝授权。
- 处理访问控制模型及其策略的存储。
- 管理角色用户映射和角色角色映射(RBAC中的角色层次结构)。
- 支持内置的超级用户,例如root或administrator。超级用户可以在没有显式权限的情况下执行任何操作。
- 多个内置运算符支持规则匹配。例如,keyMatch可以将资源键映射/foo/bar到模式
/foo*。
Casbin不执行的操作:
- 身份验证(又名验证username以及password用户登录时)
- 管理用户或角色列表。我相信项目本身管理这些实体会更方便。用户通常具有其密码,而Casbin并非设计为密码容器。但是,Casbin存储RBAC方案的用户角色映射。
gin集成casbin
第一步:编写conf文件
在项目根目录下增加rbac_model.conf文件
采用的是Casbin中最基本,最简单的模型是ACL
[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 = r.sub == p.sub && keyMatch2(r.obj,p.obj) && r.act == p.act
第二步:安装依赖包
go get github.com/casbin/casbin/v2
go get github.com/casbin/gorm-adapter/v3 //这里采用的是gorm,可根据自已业务更换
第三步:编写casbin帮助类
package system
import (
"github.com/casbin/casbin/v2"
gormadapter "github.com/casbin/gorm-adapter/v3"
"sync"
"wsn-gin/global"
)
type CasbinService struct {
}
var CasbinServiceApp = new(CasbinService)
//持久化到数据库
var (
syncedEnforcer *casbin.SyncedEnforcer
once sync.Once
)
func (c *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
}
global.GVA_DB为gorm对象,传入之后,会自动在数据库中生成casbin_rule表
第四步:编写gin中间件
func CasbinHandler() gin.HandlerFunc {
return func(c *gin.Context) {
//获取请求path
obj := c.Request.URL.Path
//获取请求方法
act := c.Request.Method
//角色应该从token解析出来,此处为了节约时间,写死了值
sub := "admin"
//引入casbin
e := casbinService.Casbin()
//新增几个策略
//e.AddPolicy("admin", "/v1/customer/customer", "GET")
////删除策略
//e.RemovePolicy("admin", "/api/v1/hello", "GET")
////获取策略
//list := e.GetPolicy()
//for _, vlist := range list {
// for _, v := range vlist {
// fmt.Printf("value: %s, ", v)
// }
//}
//判断策略是否存在
success, _ := e.Enforce(sub, obj, act)
//如果环境变量是开发者模式或者casbin校验通过
if global.GVA_CONFIG.System.Env == "develop" || success {
c.Next()
} else {
response.FailWithDetailed(gin.H{}, "权限不足", c)
c.Abort()
return
}
}
}
可以手动在数据库增加一些策略,或者通过上述e.AddPolicy()方法增加策略。
如果环境变量是本地模式,则可跳过此中间件。
新增策略之后,数据库如下:
第五步:引入中间件
注意中间件引入顺序,应该先域名,再jwt校验,再casbin校验。
这里为了测试方便,casbin放在了jwt前面。