写点什么

基于 Casbin 的 ABAC 授权模型设计与开发踩坑实录

  • 2025-06-20
    北京
  • 本文字数:2806 字

    阅读完需:约 9 分钟

本文分享自天翼云开发者社区《基于Casbin的ABAC授权模型设计与开发踩坑实录》,作者:upclose


最近因项⽬需求,需要寻求⼀个好⽤强⼤的权限管理⽅案。天翼云安全实验室经过仔细调研,最终选择了 ABAC(Attribute Based Access Control,基于标签的访问控制)作为授权模型的基础,在具体实现上则青睐于后起之秀 Casbin。ABAC 被称为“下一代”授权模型,具有更细粒度的权限设定、更灵活的权限管理等优势。Casbin 是一个开源的权限管理框架,其主要优势有:

支持多种权限模型如 ACL、RBAC、ABAC 等;

支持多种语言,以 Golang 为主,同时支持 java、PHP 等;

活跃的社区和持续更新,这对于开源软件来说是很可贵的品质;

功能强大,上手也不复杂。

下面是一篇基于 Casbin 实现 ABAC 授权模型的避坑指南,负重前行只为你的岁月安好。

一、授权模型

虽然开篇就明确了使用 ABAC,不过在此还是要多言两句,对历来经典授权模型进行一些介绍,也好说明为什么最终选择了使用 ABAC。

二、ACL(Access Control Lists,访问控制列表)

用户 A 可以访问代码仓库。

所谓,就形成了一一对应的关系,谁可以访问什么资源,都清楚列在表上。ACL 的优点是容易理解与实现。ACL 的缺点是需要维护的数据庞大,对于 m 个用户和 n 个资源,就会产生 m*n 的访问控制表。

三、RBAC(Role Based Access Control,基于角色的访问控制)

开发人员可以访问代码仓库。

RBAC 之于 ACL 的一大改进,在于把用户聚类成了角色,而以角色的粒度进行权限管理。RBAC 的优点包括了 ACL 的优点,同时大幅度减小了需要维护的权限数据表。RBAC 的缺点则是缺乏灵活性,因为角色是管理用户最小粒度。

四、ABAC(Attribute Based Access Control,基于标签的访问控制)

9am-6pm 之间可以访问代码仓库。

有了 ACL 和 RBAC 的前车之鉴,ABAC 是在灵活性上下了功夫,提出基于标签进行授权管理,从而给授权管理这一历史性课题带来了动态性。相比与 ACL 中小明可以访问资源,以及 RBAC 中开发人员可以访问资源,ABAC 中采用了上班时间在办公网络中可以访问资源的说法,而时间网络环境则成为 ABAC 中作为授权决策的关键因素,即标签。ABAC 的优点是灵活性极大,不在拘泥于特定的对象,而是把审时度势的思考带入到的权限管理中;不再维护巨大的角色-资源对应表也是其一大优势。ABAC 的缺点在于门槛较高,因为标签这一概念并不直观,维护工作也往往需要专门的人员才能进行。

五、PBAC(Policy Based Access Control,基于策略的访问控制)

PBAC 并不是学院提出的,更像民间的说法,是一种在 ABAC 的基础上增加策略的授权管理。然而 ABAC 并不是没有策略,ABAC 的标签是需要策略才能执行的。所以笔者认为 PBAC 只是 ABAC 的另一种理解方式,而非新的授权模型。

六、PERM 描述语言

PERM 即 Policy, Effect, Request, Matchers,是 Casbin 中用来描述授权模型的一门语言。基于 PERM 语言,就可以实现各种授权模型,而 PERM 也赋予了 Casbin 在各种传统授权模型上进行自定义改进的能力。使用 Casbin 官方提供的在线编辑器可以实时进行 PERM 编写实验。

PERM 中的四大元素含义如下:

  • Request:授权请求,至少需要包含请求者(sub)、请求资源(obj)和请求行为(act);

  • Policy:授权决策,与授权请求相匹配;

  • Effect:策略影响,决定策略的最终效果;

  • Matcher:授权模型的核心行为,描述了上述几大元素在模型中是如何协作完成授权工作。

Casbin 提供了用 PERM 描述 ABAC 模型的示例代码:

[request_definition]r = sub, obj, act
[policy_definition]p = sub_rule, obj, act
[policy_effect]e = some(where (p.eft == allow))
[matchers]m = eval(p.sub_rule) && r.obj == p.obj && r.act == p.act
复制代码

其中 matcher 最为值得注意,其由 3 个布尔判断构成。当授权请求到来时,r.obj == p.objr.act == p.act用于通过请求的信息(r)查询得到对应的策略(p)。在得到策略之后,eval(p.sub_rule)执行策略中配置的标签条件判断,从而得到最终的授权请求决策结果。Casbin 举例的 ABAC 策略如下:

p, r.sub.Age > 18 && r.sub.Age < 60, /data1, read
复制代码

该策略在有用户请求对/data1资源进行read操作时生效,通过判断该请求者的 Age 标签是否在 18-60 的范围内,从而决策该请求者是否可以对/data1进行访问。

七、Casbin 实践

7.1 模型与策略设计

正如上文对 ABAC 的介绍,用一句话对 ABAC 的决策进行概括,可以举例为上班时间在办公网络中可以对代码仓库进行访问。其中代码仓库(例如 gitlab.xxx.com)是 obj,时间和网络环境是标签,分别为 sub.Time sub.IP,而访问行为就是 access。根据 PERM 的语法,针对代码仓库这一资源的访问策略可以写作:

p, r.sub.Time >= 9 && r.sub.Time <= 18 && r.sub.IP == 1.1.1.1, gitlab.xxx.com, access
复制代码

当然在实际场景中,仅仅通过时间和 IP 进行访问控制并不灵活,但针对策略进行修改,不需要修改模型,就可以赋予该 ABAC 授权模型动态的能力,例如增加对用户访问行为的检测、 对授权失败的用户增加二次授权认证的策略等。

7.2 基于 Casbin 的 ABAC 模型构建

Casbin 目前不支持 MongoDB 数据库,所以就先用 MySQL。在 Golang 中需要使用xormadapter与数据库进行交互:

// 连接MySQL数据库mysqlString := fmt.Sprintf("%s:%s@tcp(%s:%d)/", mysqlUser, mysqlPassword, mysqlIP, mysqlPort)a, err := xormadapter.NewAdapter("mysql", mysqlString)if err != nil {    return errors.New("Connect to database error: " + err.Error())}
复制代码

Casbin 数据库用来存储策略,也可以用来存储模型。不过模型一般不会修改(需要时常修改模型的设计一定有问题),所以模型可以直接硬编码在代码中:

// 创建ABAC模型abacModel := `[request_definition]r = sub, obj, act[policy_definition]p = sub_rule, obj, act[policy_effect]e = some(where (p.eft == allow)) && !some(where (p.eft == deny))[matchers]m = r.obj == p.obj && r.act == p.act && eval(p.sub_rule)`m, _ := model.NewModelFromString(abacModel)
复制代码

最后拥有了模型和数据库,Casbin 就可以跑起来了:

// 创建引擎enforcer, err = casbin.NewEnforcer(m, a)// 加载策略err = enforcer.LoadPolicy()
复制代码

还需要添加策略,以上述通过时间和环境进行访问授权决策的策略为例:

rule := "r.sub.Time >= 9 && r.sub.Time <= 18 && r.sub.IP == 1.1.1.1"object := "gitlab.xxx.com"action := "access"_, err := enforcer.AddPolicy(rule, object, action)
复制代码

7.3 ABAC 模型授权

在授权请求时需要首先定义请求者即 sub,sub 的字段名称需要和 Policy 中的定义一致(包括大小写):

type Subject struct {	Time int	IP string}
复制代码

最后在授权请求发生时,调用起 Casbin 的 API 对授权请求进行决策,在该过程中,Casbin 会从数据库中找找符合的 Policy,通过计算 Policy 中定义的规则,得到决策结果:

// 1. 根据授权请求,实例化请求者sub := Subject{	Time: time.Now().Unix(),    IP: ip,}// 2. 调用ABAC引擎,计算用户访问授权结果ok, _ := enforcer.Enforce(sub, obj, act)
复制代码


用户头像

还未添加个人签名 2022-02-22 加入

天翼云是中国电信倾力打造的云服务品牌,致力于成为领先的云计算服务提供商。提供云主机、CDN、云电脑、大数据及AI等全线产品和场景化解决方案。

评论

发布
暂无评论
基于Casbin的ABAC授权模型设计与开发踩坑实录_安全_天翼云开发者社区_InfoQ写作社区