跳转至主要内容

RBAC

角色定义

[role_definition] 用于定义 RBAC 角色继承关系。 Casbin 支持多个实例的 RBAC 系统,其中用户可以拥有角色及其继承关系,资源也可以拥有角色及其继承关系。 这两个 RBAC 系统不会相互干扰。

此部分为可选。 如果你在模型中不使用 RBAC 角色,那么省略此部分。

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

上述角色定义显示 g 是一个 RBAC 系统,而 g2 是另一个 RBAC 系统。 ,表示在继承关系中涉及两个方。 在最常见的情况下,如果你只需要用户的角色,通常只使用g。 当你需要用户和资源的角色(或组)时,也可以同时使用 gg2`。 请参阅 rbac_model.confrbac_model_with_resource_roles.conf 以获取示例。

Casbin 在策略中存储实际的用户-角色映射(如果你在资源上使用角色,则为资源-角色映射)。 例如:

p, data2_admin, data2, read
g, alice, data2_admin

这意味着 alice 继承/是角色 data2_admin 的成员。 在这里,alice 可以是用户,资源,或者角色。 Casbin 只将其识别为字符串。

然后,在匹配器中,你应该如下所示检查角色:

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

这意味着请求中的 sub 应该在策略中拥有角色 sub

备注
  1. Casbin 只存储用户-角色映射。
  2. Casbin 不验证用户是否是有效用户或角色是否是有效角色。 这应由身份验证来处理。
  3. 不要在 RBAC 系统内为用户和角色使用相同的名称,因为 Casbin 将用户和角色识别为字符串,Casbin 无法知道你是指定用户 alice 还是角色 alice。 你可以简单地通过使用 role_alice 来解决这个问题。
  4. 如果 A 有角色 B,并且 B 有角色 C,那么 A 有角色 C。 这种传递性目前是无限的。
令牌名称约定

按照惯例,策略定义中的主题令牌名称为 sub 并放在开头。 现在,Golang Casbin 支持自定义令牌名称和位置。 如果主题令牌名称是 sub,则主题令牌可以放在任意位置,无需任何额外操作。 如果主题令牌名称不是 sub,无论其位置如何,都应在初始化执行器后调用 e.SetFieldIndex()constant.SubjectIndex

# `subject` here is for sub
[policy_definition]
p = obj, act, subject
e.SetFieldIndex("p", constant.SubjectIndex, 2) // index starts from 0
ok, err := e.DeleteUser("alice") // without SetFieldIndex, it will raise an error

角色层次结构

Casbin 的 RBAC 支持 RBAC1 的角色层次结构特性,这意味着如果 alicerole1,并且 role1role2,那么 alice 也将拥有 role2 并继承其权限。

在这里,我们有一个叫做层次级别的概念。 所以,在这个例子中,层次级别是 2。 对于 Casbin 中的内置角色管理器,你可以指定最大层次级别。 默认值是 10。 这意味着像 alice 这样的最终用户只能继承 10 个级别的角色。

// NewRoleManager is the constructor for creating an instance of the
// default RoleManager implementation.
func NewRoleManager(maxHierarchyLevel int) rbac.RoleManager {
rm := RoleManager{}
rm.allRoles = &sync.Map{}
rm.maxHierarchyLevel = maxHierarchyLevel
rm.hasPattern = false

return &rm
}

如何区分角色和用户?

Casbin 在其 RBAC 中并不区分角色和用户。 它们都被视为字符串。 如果你只使用单级 RBAC(其中角色永远不会是另一个角色的成员),你可以使用 e.GetAllSubjects() 获取所有用户和 e.GetAllRoles() 获取所有角色。 它们将分别列出所有 g, u, r 规则中的所有 u 和所有 r

但是,如果你正在使用多级 RBAC(具有角色层次结构)并且你的应用程序不记录名称(字符串)是用户还是角色,或者你有一个用户和一个角色具有相同的名称,你可以在将其传递给 Casbin 之前为角色添加前缀,如 role::admin。 这样,你可以通过检查这个前缀来知道它是否是一个角色。

如何查询隐式角色或权限?

当用户通过 RBAC 层次结构继承角色或权限,而不是在策略规则中直接分配它们时,我们称这种类型的分配为“隐式”。 要查询此类隐式关系,你需要使用这两个 API:GetImplicitRolesForUser()GetImplicitPermissionsForUser(),而不是 GetRolesForUser()GetPermissionsForUser()。 有关更多详细信息,请参阅 此 GitHub 问题

在 RBAC 中使用模式匹配

参见 RBAC with Pattern

角色管理器

详见 Role Managers 部分。