RBAC
角色定义
[role_definition] 用于定义 RBAC 角色继承关系。 Casbin 支持多个实例的 RBAC 系统,其中用户可以拥有角色及其继承关系,资源也可以拥有角色及其继承关系。 这两个 RBAC 系统不会相互干扰。
此部分为可选。 如果你在模型中不使用 RBAC 角色,那么省略此部分。
[role_definition]
g = _, _
g2 = _, _
上述角色定义显示 g 是一个 RBAC 系统,而 g2 是另一个 RBAC 系统。 ,表示在继承关系中涉及两个方。 在最常见的情况下,如果你只需要用户的角色,通常只使用g。 当你需要用户和资源的角色(或组)时,也可以同时使用 g和g2`。 请参阅 rbac_model.conf 和 rbac_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。
- Casbin 只存储用户-角色映射。
- Casbin 不验证用户是否是有效用户或角色是否是有效角色。 这应由身份验证来处理。
- 不要在 RBAC 系统内为用户和角色使用相同的名称,因为 Casbin 将用户和角色识别为字符串,Casbin 无法知道你是指定用户
alice还是角色alice。 你可以简单地通过使用role_alice来解决这个问题。 - 如果
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 的角色层次结构特性,这意味着如果 alice 有 role1,并且 role1 有 role2,那么 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 中使用模式匹配
角色管理器
详见 Role Managers 部分。