Genbu
基础服务go-easy-admin
中,在权限控制中我们使用了casbin
来进行细粒度的把控。简单总结就是那个用户可以使用那种方法访问那个api
接口。
Casbin 是一个开源的访问控制库,用于实现权限管理和访问控制模型。它提供了一种简单而灵活的方式来定义和强制应用程序中的访问控制规则。
Casbin 的核心思想是基于访问控制列表(Access Control List, ACL)和角色访问控制(Role-Based Access Control,RBAC)模型。它允许你通过编程方式定义资源、操作和角色之间的关系,并在运行时根据这些规则进行验证和授权。
Casbin 的访问控制模型由三个主要概念组成:
Casbin 支持多种编程语言和框架,包括 Go、Java、Python、Node.js 等,并提供了与常见存储(如文件、数据库等)的集成。
通过 Casbin,你可以轻松实现复杂的访问控制逻辑,例如 RBAC(基于角色的访问控制)、ABAC(基于属性的访问控制)和多租户访问控制等。它提供了一种可扩展和灵活的方式来管理应用程序中的权限和访问控制策略。
model文件
rbac_model.conf
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act,desc
[role_definition]
g = _, _
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = r.sub == p.sub && (keyMatch2(r.obj, p.obj) || keyMatch(r.obj, p.obj)) && (r.act == p.act || p.act == "*")
数据库定义
type CasbinPolicy struct {
PType string `json:"p_type" binding:"required"`
RoleID string `json:"role_id" binding:"required"`
Path string `json:"path" binding:"required"`
Method string `json:"method" binding:"required"`
Desc string `json:"desc" binding:"required"`
}
初始化执行器
func InitCasbinEnforcer() {
e, err := mysqlCasbin()
if err != nil {
TPLogger.Error("初始化casbin策略管理器失败:", err)
panic(err)
}
e.EnableAutoSave(true)
CasbinEnforcer = e
}
模型加载
func mysqlCasbin() (*casbin.Enforcer, error) {
a, err := gormadapter.NewAdapterByDB(GORM)
if err != nil {
TPLogger.Error("casbin adapter gorm failed: ", err)
return nil, err
}
e, err := casbin.NewEnforcer("config/rbac_model.conf", a)
if err != nil {
return nil, err
}
if err = e.LoadPolicy(); err != nil {
return nil, err
}
return e, nil
}
我们使用的是mysql存储的策略哦。更多存储方式可以参考官网合理选择。
中间件定义
func CasbinMiddle() gin.HandlerFunc {
return func(c *gin.Context) {
// 从上下文中获取username
ctxUser := c.GetString("username")
if ctxUser == "admin" {
c.Next()
} else {
// TODO 从缓存中获取用户相关的信息,例如:role、dept、menu
// 从数据库中获取用户角色信息sub
usersInfo, err := system.NewUserInterface().GetUserFromUserName(ctxUser)
if err != nil {
global.TPLogger.Error("从数据库中获取用户角色信息sub失败:", err)
global.ReturnContext(c).Failed("failed", "权限访问失败,请联系管理员")
c.Abort()
return
}
sub := usersInfo.RoleId
//获取请求路径
obj := strings.Split(c.Request.RequestURI, "?")[0]
// 获取请求方法
act := c.Request.Method
success, err := global.CasbinEnforcer.Enforce(strconv.Itoa(int(sub)), obj, act)
if err != nil || !success {
global.TPLogger.Error("权限验证失败:", err, success)
global.ReturnContext(c).Failed("failed", "权限验证失败")
c.Abort()
return
} else {
c.Next()
}
}
}
}
管理员用户(拥有所有权限)
用户列表接口
没有该权限人员访问