golang gin 基于 Casbin 实现权限控制

更新日期: 2025-05-26 阅读次数: 199 字数: 2253 分类: golang

最近在使用 golang gin 开发一套公司内部的人事管理系统,但是发现权限管理比之前搞的系统要复杂不少, 所以我想借机了解一下传说中的 Casbin 权限控制库,看看是否可以借鉴一下。

涉及权限控制的需求场景

  • 人事部门负责人需要能看到所有的人事数据
  • 人事部门的普通 HR,只能看到部分部门的人事数据。即只能看到自己负责的部门数据
  • IT 部门或者行政部门指定人员,能看到资产管理模块的数据。即每个员工有哪些名下资产,显示器,主机,桌子椅子之类的。方便离职时进行资产回收。
  • 部门负责人能看到自己部门的所有员工数据,除了薪资相关的字段。且只有看的权限。不能修改和删除。
  • 员工个人能通过企业微信的授权登录,查看自己的个人信息。包括姓名,工号,入职时间,部门,岗位等。能修改一些基础信息等。
  • 一个集团公司下,有多个子公司。每个子公司都有自己的 HR 系统。HR 系统的权限控制需要支持集团公司下的多租户模式。

现有 gin route group 的缺陷

总感觉,我目前实用的 gin route group + middleware 的方式,无法满足复杂的权限控制需求。 而且对于粒度更细的权限控制,无法做到灵活的配置。

我目前实现的系统,都是基于角色的权限控制。即每个角色对应一组权限。 还是不太灵活。

当然根源是,gin 没有内置权限控制的功能,我自己实现的这套感觉很乱。我不知道规范的做法是怎样的。 所以,需要找个开源的权限控制库,学习参考一下。

Casbin 示例

policy.csv 文件内容

p, alice, /api/*, read
p, bob, /version, write

预定义一些策略,也可以存储到数据库, alice 可以访问所有 /api 开头的路径,bob 只能访问 /version 路径。

go 代码

// 加载模型与策略,也可以存储到数据库
e, err := casbin.NewEnforcer("path/to/model.conf", "path/to/policy.csv")

sub := "alice" // the user that wants to access a resource.
obj := "data1" // the resource that is going to be accessed.
act := "read" // the operation that the user performs on the resource.

ok, err := e.Enforce(sub, obj, act) //判断用户是否有权限

实际使用中,e.Enforce() 方法通常会在中间件 (middleware) 中调用,以便在处理请求之前进行权限检查。

参考:

https://juejin.cn/post/7108533587292454949

Casbin 的功能简介

一种基于元模型的访问控制策略描述语言 PML (PERM modeling language) 及其实施机制 PML-EM (PML enforcement mechanism)

  • 策略语言无关性
  • 访问控制模型无关性: 即支持多种访问控制模型,如基于角色的访问控制(RBAC)、基于属性的访问控制(ABAC)以及 BLP 模型等。
  • 程序设计语言无关性

参考论文:

https://www.jos.org.cn/jos/article/pdf/5624

一些术语

  • 访问控制模型(Access Control Model):定义了如何对资源进行访问控制的规则和方法。
  • 访问控制策略(Access Control Policy):具体的规则和策略,用于定义哪些用户或角色可以访问哪些资源以及可以执行哪些操作。
  • 访问控制列表(Access Control List, ACL):一种常见的访问控制策略,列出了每个用户或角色对特定资源的访问权限。
  • 角色(Role):一组权限的集合,用户可以被分配到一个或多个角色中,以简化权限管理。
  • 权限(Permission):对资源的具体操作权限,如读取、写入、删除等。
  • 策略(Policy):定义了访问控制的规则,通常包括主体(用户或角色)、客体(资源)和操作(权限)。
  • 策略引擎(Policy Engine):用于评估访问控制策略并决定是否允许访问的组件。
  • 策略存储(Policy Store):存储访问控制策略的地方,可以是文件、数据库或其他存储系统。
  • 基于属性访问控制 (attribute-based access control, 简称 ABAC) 模型
  • 基于角色访问控制 (role-based access control, 简称 RBAC) 模型
  • PERM (Policy, Effect, Request, Matchers) 模型
  • 策略描述语言 PML (PERM modeling language)
  • 基于请求(request)、策略(policy)、匹配器(matcher)、策略效果(effect) 的访问控制元模型 PERM (policy-effect-request-matcher)
  • 策略实施机制 PML-EM (PML enforcement mechanism)
  • 认证(Authentication): 在 Web 程序中对应的是 HTTP Status 401 错误
  • 授权(Authorization): 在 Web 程序中对应的是 HTTP Status 403 错误

Casbin 入门介绍

https://casbin.org/docs/tutorials/

里面有一堆高质量的介绍文档,找几篇读读,就能有个大概的了解。剩下的就是动手测试一下了。

Request 原语

一个访问请求通常由经典的三元组构成:

  • Subject:请求的主体,通常是用户或角色。
  • Object:请求的对象,通常是资源或数据。
  • Action:请求的操作,通常是对资源的具体操作,如读取、写入等。

Policy 原语 (策略规则) 类似,也是这三个部分。

ACL (Access Control List) 与 RBAC (Role-Based Access Control),ABAC (Attribute-Based Access Control) 的区别

  • ACL 需要存储每个用户对每个资源的权限,适用于用户数量较少的场景。
  • RBAC 通过角色来管理权限,适用于用户数量较多的场景。用户可以被分配到一个或多个角色中,角色定义了一组权限。但是,不能做的很细粒度的控制。这也是我目前遇到的困扰。但是我感觉,就算在代码中写死部分细微的权限控制逻辑,也能满足需求。唯一的问题就是对于管理员来说不可见,也不能灵活配置。例如,同样是人事部门的角色,有的 HR 能修改一些基础信息等,有的 HR 只能查看数据。
  • ABAC 通过属性来管理权限,适用于需要更细粒度控制的场景。用户、资源和环境的属性可以用来定义访问控制策略。

参考:

https://github.com/xizhibei/blog/issues/101

多租户的支持

参考:

https://www.cnblogs.com/wang_yb/p/9987397.html

策略规则 Policy 存储到数据库的方法

保存到 CSV 不是一个好的选择,应该存储到数据库中。这样可以更灵活地管理和查询策略规则。

否则,每次都需要登录服务器,修改 CSV 文件,然后重启服务,才能生效。这样不够灵活。

参考:

https://casbin.org/zh/docs/policy-storage/

这里支持 Gorm MySQL 的适配器:

https://casbin.org/zh/docs/adapters

实际场景实用

https://www.cnblogs.com/studyzy/p/11380736.html

gin middleware 插件

https://casbin.org/zh/docs/middlewares

这里推荐了两个插件 authz (这个居然是 gin 官方的,不可思议) 和 go-casbin, 不过这么简单的 middleware,我感觉并不需要三方的实现。 不过可以参考一下代码。

感想

  • 涉及的概念比较多,需要耐心学习和理解,即便拿出半天时间来阅读理解,都是值得的。
  • 即便最后不使用 Casbin 作为权限控制的实现,也能从中学到很多关于权限控制的设计思路和实现方式。
  • 是否有简化版的 casbin 实现,只保留策略规则的部分。

今天就到这里吧,实在看不下去了,太枯燥了。

微信关注我哦 👍

大象工具微信公众号

我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式