跳到主要内容

深入理解 Casbin 匹配机制的工作原理

· 阅读需 6 分钟

本文解释了如何使用 Casbin 库设计和实现 RBAC。对于具有资源层级结构和继承权限角色的 SaaS 平台,Casbin 是一个高性能的选择。

RBAC 简介​

RBAC 根据用户持有的角色限制访问。为了了解分层 RBAC 的工作原理,我们首先查看 Azure 的 RBAC,然后在 Casbin 中实现类似的功能。

Azure 的分层 RBAC​

Azure Hierarchy

在 Azure 中,Owner 角色适用于不同的范围。如果我在订阅级别拥有 Owner 权限,那么我就是该订阅下所有资源组和资源的 Owner。如果我在资源组级别拥有 Owner 权限,那么我就是该组内所有资源的 Owner。

下图显示了订阅级别的 Owner 访问权限。Subscription Owner

检查该订阅下的某个资源组的 IAM,可以看到继承的 Owner 访问权限。RG Owner

这就是 Azure 的 RBAC 层级结构的工作方式。许多系统都使用类似的层级结构。在本教程中,我们将使用 Casbin 实现一个可比的模型。

Casbin 的工作原理​

了解 Casbin 的构建块(request、policy、matcher、effect)有助于更容易地设计和调整你的 RBAC 模型。

什么是 ACL?​

ACL (Access Control List) 将用户映射到操作,并将操作映射到资源。

模型定义​

一个最小的 ACL 模型:

[request_definition]
r = sub, act, obj

[policy_definition]
p = sub, act, obj

[policy_effect]
e = some(where (p.eft == allow))

[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act
  1. request_definition — 定义请求格式。例如 alice, write, data1 表示“Alice 可以写入 data1 吗?”
  2. policy_definition — 定义策略格式。例如,策略 alice, write, data1 授予 Alice 写入 data1 的权限。
  3. policy_effect — 多个匹配策略如何组合(例如 allow-override)。
  4. matchers — 必须满足的条件:r.sub == p.sub && r.obj == p.obj && r.act == p.act。

在 Casbin 编辑器中尝试​

打开 Casbin 编辑器 并将上述模型粘贴到 Model 编辑器中。

在 Policy 编辑器中粘贴以下内容:

p, alice, read, data1
p, bob, write, data2

并在 Request 编辑器中粘贴以下内容:

alice, read, data1

结果将是:

true

ACL 模型、策略和请求匹配的可视化表示​

acl

什么是 RBAC?​

RBAC (Role-Based Access Control) 将用户分配给角色;角色对资源拥有权限。请求会检查用户的角色是否允许对该资源执行操作。

模型定义​

一个简单的 RBAC 模型:

[request_definition]
r = sub, act, obj

[policy_definition]
p = sub, act, obj

[role_definition]
g = _, _
g2 = _, _

[policy_effect]
e = some(where (p.eft == allow))

[matchers]
m = r.sub == p.sub && g(p.act, r.act) && r.obj == p.obj
  1. role_definition — 定义图关系(例如用于角色间或用户与角色间的 g)。Matcher 使用这些关系来解析角色和权限。

在 Casbin 编辑器中尝试​

打开 编辑器 并粘贴上述模型。

在 Policy 编辑器中粘贴以下内容:

p, alice, reader, data1
p, bob, owner, data2

g, reader, read
g, owner, read
g, owner, write

并在 Request 编辑器中粘贴以下内容:

alice, read, data1
alice, write, data1
bob, write, data2
bob, read, data2
bob, write, data1

结果将是:

true
false
true
true
false

RBAC 模型、策略和请求匹配的可视化表示​

rbac

g(角色到操作)关系是一个图。在策略中它被写成边,例如:

g, reader, read
g, owner, read
g, owner, write
信息

p 是普通策略(使用 == 进行比较)。g 是图关系。你可以通过添加后缀来增加更多关系:g2、g3 等。

分层 RBAC​

在分层 RBAC 中,存在具有继承关系的多种资源类型(例如 Subscription → ResourceGroup)。订阅 sub1 可以包含资源组 rg1、rg2。同样,存在订阅级别的 roles/actions 和资源组级别的 roles/actions,它们之间也有继承关系。例如,订阅角色 sub-owner 可能会继承到资源组角色 rg-owner:如果我在 sub1 上拥有 sub-owner,我实际上就在 rg1 和 rg2 上拥有 rg-owner。

模型定义​

一个最小的分层 RBAC 模型:

[request_definition]
r = sub, act, obj

[policy_definition]
p = sub, act, obj

[role_definition]
g = _, _
g2 = _, _

[policy_effect]
e = some(where (p.eft == allow))

[matchers]
m = r.sub == p.sub && g(p.act, r.act) && g2(p.obj, r.obj)

这里 g 链接角色/操作,而 g2 链接资源(例如从订阅到资源组)。

在 Casbin 编辑器中尝试​

打开 编辑器 并粘贴上面的模型。

将以下内容粘贴到 Policy editor 中:

p, alice, sub-reader, sub1
p, bob, rg-owner, rg2

// subscription role to subscription action mapping
g, sub-reader, sub-read
g, sub-owner, sub-read
g, sub-owner, sub-write

// resourceGroup role to resourceGroup action mapping
g, rg-reader, rg-read
g, rg-owner, rg-read
g, rg-owner, rg-write

// subscription role to resourceGroup role mapping
g, sub-reader, rg-reader
g, sub-owner, rg-owner

// subscription resource to resourceGroup resource mapping
g2, sub1, rg1
g2, sub2, rg2

并将以下内容粘贴到 Request editor 中:

alice, rg-read, rg1

结果如下:

true

RBAC 模型、策略和请求匹配的可视化表示​

hrbac

g 边(角色 → 操作,角色 → 角色)可以在策略中写为:

// subscription role to subscription action mapping
g, sub-reader, sub-read
g, sub-owner, sub-read
g, sub-owner, sub-write

// resourceGroup role to resourceGroup action mapping
g, rg-reader, rg-read
g, rg-owner, rg-read
g, rg-owner, rg-write

// subscription role to resourceGroup role mapping
g, sub-reader, rg-reader
g, sub-owner, rg-owner

g2 边将订阅映射到资源组:

// subscription resource to resourceGroup resource mapping
g2, sub1, rg1
g2, sub2, rg2

主体匹配可视化表示​

hrbac-sub-match

操作匹配可视化表示​

hrbac-act-match

对象匹配可视化表示​

hrbac-obj-match

信息

Casbin 会根据所有策略评估请求。如果至少有一个策略匹配,结果为 true;否则为 false。

结论​

本教程展示了如何在 Casbin 中表达 ACL、RBAC 和层级 RBAC。在后续文章中,我们将在 Spring Boot 应用中实现这一点,并使用 Casbin 保护 API。

Comments are powered by giscus and GitHub Discussions. They load from giscus.app and GitHub only after you click the button below.