前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Casbin:GoEasyAdmin权限控制的详细解析与实践

Casbin:GoEasyAdmin权限控制的详细解析与实践

作者头像
用户1107783
发布2024-02-03 15:24:04
2600
发布2024-02-03 15:24:04
举报

背景概述

Genbu基础服务go-easy-admin中,在权限控制中我们使用了casbin来进行细粒度的把控。简单总结就是那个用户可以使用那种方法访问那个api接口。

Casbin介绍

Casbin 是一个开源的访问控制库,用于实现权限管理和访问控制模型。它提供了一种简单而灵活的方式来定义和强制应用程序中的访问控制规则。

Casbin 的核心思想是基于访问控制列表(Access Control List, ACL)和角色访问控制(Role-Based Access Control,RBAC)模型。它允许你通过编程方式定义资源、操作和角色之间的关系,并在运行时根据这些规则进行验证和授权。

Casbin 的访问控制模型由三个主要概念组成:

  1. 模型规则(Model Rule):定义资源、操作和角色之间的关系。使用类似于自然语言的策略语法来描述访问控制规则。
  2. 策略规则(Policy Rule):存储了用户、角色、资源和操作之间的映射关系。可以从外部数据源(如数据库或配置文件)加载或保存策略规则。
  3. 执行器(Enforcer):负责验证访问请求是否符合访问控制规则。根据模型规则和策略规则,决定是否允许或拒绝访问。

Casbin 支持多种编程语言和框架,包括 Go、Java、Python、Node.js 等,并提供了与常见存储(如文件、数据库等)的集成。

通过 Casbin,你可以轻松实现复杂的访问控制逻辑,例如 RBAC(基于角色的访问控制)、ABAC(基于属性的访问控制)和多租户访问控制等。它提供了一种可扩展和灵活的方式来管理应用程序中的权限和访问控制策略。

代码示例

model文件

rbac_model.conf

代码语言:javascript
复制
[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 == "*")

数据库定义

代码语言:javascript
复制
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"`
}

初始化执行器

代码语言:javascript
复制
func InitCasbinEnforcer() {
 e, err := mysqlCasbin()
 if err != nil {
  TPLogger.Error("初始化casbin策略管理器失败:", err)
  panic(err)
 }
 e.EnableAutoSave(true)
 CasbinEnforcer = e
}

模型加载

代码语言:javascript
复制
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存储的策略哦。更多存储方式可以参考官网合理选择。

中间件定义

代码语言:javascript
复制
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()
   }
  }

 }
}

案例演示

管理员用户(拥有所有权限)

用户列表接口

没有该权限人员访问

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2024-01-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 云原生运维圈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景概述
  • Casbin介绍
  • 代码示例
  • 案例演示
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档