GO 权限管理之 Casbin

GO 权限管理之 Casbin

GO权限管理之Casbin.jpg

我们来回顾一下上次分享的 GO中 gjson 库的应用和分享,它主要是提供了一种非常快速简单的方式从json文档中获取相应值

  • 分享了 jsongjson分别代表什么
  • gjson 的简单使用
  • gjson 校验,获取值
  • gjsonjson 行
  • gjson的键路径匹配规则
  • gjson的修饰符和自定义修饰符

要是对 gjson还有点兴趣的话,可以查看文章 GO中gjson的应用和分享

image

今天咱们来分享一下 GO里面的权限管理,Casbin

权限管理是什么?

一般指根据系统设置的安全规则或者安全策略

用户可以访问而且只能访问自己被授权的资源,不多不少刚刚好

权限管理几乎出现在任何系统里面

我们可能会把 用户身份认证密码加密系统管理权限管理弄混淆,那么他们具体的侧重点是什么呢?

  • 用户身份认证

不属于权限管理范畴

用户身份认证指的是通过某种凭证来证明自己的身份,例如账号密码,指纹,人脸识别等等

  • 系统管理

是系统中的一个模块,该模块一般还含有权限管理子模块 , 该模块相当于给权限管理模块提供了一些数据

  • 密码加密

也是不属于权限管理范畴 , 他只是用户身份认证领域的一个部分

image

Casbin 是个啥?

是 GO 项目的功能强大且高效的开源访问控制库,casbin支持常用的多种访问控制模型,例如:

  • RBAC
  • ABAC
  • ACL

使用casbin来做权限管理有一个比较好的地方是,casbin是支持多种语言的,就像protobuf一样也是支持多种语言

咱们来看看 Casbin 有啥特性

  • 实施策略是这样子的 {subject, object, action}

我们也可以自定义,同时他支持允许授权和拒绝授权

  • 他可以处理访问控制模型以及其存储对应的策略
  • RBAC中的角色层次结构 中,他可以管理角色用户映射和角色角色映射
  • 他支持内置的超级用户

rootadministrator

  • 支持多个内置运算符规则匹配

例如 hello/world ,就可以将其映射到 hello*模式

  • 不支持身份验证
  • 不支持管理用户或角色列表

咱们看一下 Casbin 的基本模型

Casbin 库中,他是基于PERM元模型将访问控制模型抽象为CONF文件,有如下4个部分

  • 策略
  • 效果
  • 请求
  • 匹配器

一起来了解一个最简单的模型,ACLCONF模型

#请求定义
[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.obj == p.obj && r.act == p.act

例如一个ACL模型的示例策略

p, xiaomt, data1, read
p, xiaomt, data2, write

咱们来写一个DEMO

  • main.go 文件写gin 对应的接口以及 casbin 的使用
  • rbac_models.conf RBAC CONF文件
image

咱们写一个路由,里面添加一个拦截器,再写一个接口/api/v1/hello,使用GET方法验证效果

package main

import (
   "fmt"
   "log"

   "github.com/casbin/casbin"
   xd "github.com/casbin/xorm-adapter"
   "github.com/gin-gonic/gin"
   _ "github.com/go-sql-driver/mysql"
)

// myAuth 拦截器
func myAuth(e *casbin.Enforcer) gin.HandlerFunc {
   return func(c *gin.Context) {
      obj := c.Request.URL.RequestURI()
      // 获取方法
      act := c.Request.Method
      sub := "root"

      // 判断策略是否已经存在了
      if ok := e.Enforce(sub, obj, act); ok {
         log.Println("Check successfully")
         c.Next()
      } else {
         log.Println("sorry , Check failed")
         c.Abort()
      }
   }
}

func main() {
   // 使用自己定义rbac_db
   // 最后的一个参数咱们写true ,否则默认为false,使用缺省的数据库名casbin,不存在则创建
   a := xd.NewAdapter("mysql", "root:123456@tcp(127.0.0.1:3306)/mycasbin?charset=utf8", true)

   e := casbin.NewEnforcer("./rbac_models.conf", a)

   //从DB中 load 策略
   e.LoadPolicy()

   //new 一个路由
   r := gin.New()

   r.POST("/api/v1/add", func(c *gin.Context) {
      log.Println("add a policy")
      if ok := e.AddPolicy("root", "/api/v1/hello", "GET"); !ok {
         log.Println("The strategy already exists")
      } else {
         log.Println("add successfully ...")
      }
   })

   //使用自定义拦截器中间件,每一个接口的访问,都会通过这个拦截器
   r.Use(myAuth(e))
   //创建请求
   r.GET("/api/v1/hello", func(c *gin.Context) {
      fmt.Println("hello wolrd")
   })

   // 监听 127。0.0.1:8888
   r.Run(":8888")
}

对于上述 xd.NewAdapter 读取数据的操作,咱们可以看看具体实现

image

具体源码在 "github.com/casbin/xorm-adapter" 中的 adapter.go

// NewAdapter is the constructor for Adapter.
// dbSpecified is an optional bool parameter. The default value is false.
// It's up to whether you have specified an existing DB in dataSourceName.
// If dbSpecified == true, you need to make sure the DB in dataSourceName exists.
// If dbSpecified == false, the adapter will automatically create a DB named "casbin".
func NewAdapter(driverName string, dataSourceName string, dbSpecified ...bool) *Adapter {
   a := &Adapter{}
   a.driverName = driverName
   a.dataSourceName = dataSourceName

   if len(dbSpecified) == 0 {
      a.dbSpecified = false
   } else if len(dbSpecified) == 1 {
      a.dbSpecified = dbSpecified[0]
   } else {
      panic(errors.New("invalid parameter: dbSpecified"))
   }

   // Open the DB, create it if not existed.
   a.open()

   // Call the destructor when the object is released.
   runtime.SetFinalizer(a, finalizer)

   return a
}

再来看看casbin.NewEnforcer

源码文件在 "github.com/casbin/casbin"enforcer.go

NewEnforcer 通过文件或 DB 创建一个 enforcer , 如下是官方的案例写法,注意如下案例

// e := casbin.NewEnforcer("path/to/basic_model.conf", "path/to/basic_policy.csv")
// MySQL DB:
// a := mysqladapter.NewDBAdapter("mysql", "mysql_username:mysql_password@tcp(127.0.0.1:3306)/")
// e := casbin.NewEnforcer("path/to/basic_model.conf", a)
func NewEnforcer(params ...interface{}) *Enforcer {
   e := &Enforcer{}

   parsedParamLen := 0
   // 判断参数个数
   if len(params) >= 1 {
      enableLog, ok := params[len(params)-1].(bool)
      if ok {
         e.EnableLog(enableLog)

         parsedParamLen++
      }
   }
   // 省略 部分代码
   return e
}

上述代码,大家感兴趣的话,可以将代码贴到自己的环境中

使用类似postman工具来访问接口,查看效果哦,需要配置好mysql数据库

image

对于上述的 gin拦截器 若感兴趣的话, 可以查看文章

总结

  • 分享了权限管理是什么
  • Casbin 是什么
  • Casbin 的特性
  • Casbin 的应用案例

欢迎点赞,关注,收藏

朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力

[图片上传失败...(image-58d9bc-1624578579593)]

好了,本次就到这里,下一次 工作中后端是如何将API提供出去的?swaggo很不错

技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。

我是小魔童哪吒,欢迎点赞关注收藏,下次见~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335