跳转至主要内容

ABAC

什么是ABAC模型?

ABAC代表基于属性的访问控制。 它允许你通过使用主体、对象或行为的属性(属性)来控制访问,而不是使用字符串值本身。 你可能听说过一种复杂的ABAC访问控制语言,叫做XACML。 另一方面,Casbin的ABAC要简单得多。 在Casbin的ABAC中,你可以使用结构体或类实例代替模型元素的字符串。

让我们来看一下官方的ABAC示例:

[request_definition]
r = sub, obj, act

[policy_definition]
p = sub, obj, act

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

[matchers]
m = r.sub == r.obj.Owner

在匹配器中,我们使用r.obj.Owner代替r.obj。 传递给Enforce()函数的r.obj将是一个结构体或类实例,而不是一个字符串。 Casbin将使用反射来为你检索该结构体或类中的obj成员变量。

这是r.obj结构体或类的定义:

type testResource struct {
Name string
Owner string
}

如果您想通过JSON向enforcer传递参数,则需要使用e.EnableAcceptJsonRequest(true)启用该功能。

例如:

e, _ := NewEnforcer("examples/abac_model.conf")
e.EnableAcceptJsonRequest(true)

data1Json := `{ "Name": "data1", "Owner": "bob"}`

ok, _ := e.Enforce("alice", data1Json, "read")
备注

启用接受JSON参数的功能可能会导致性能下降1.1到1.5倍。

如何使用ABAC?

要使用ABAC,你需要做两件事:

  1. 在模型匹配器中指定属性。
  2. 将结构体或类实例作为参数传递给Casbin的Enforce()函数。
危险

目前,只有像r.subr.objr.act等请求元素支持ABAC。 你不能在像p.sub这样的策略元素上使用它,因为在Casbin的策略中没有办法定义一个结构体或类。

提示

你可以在匹配器中使用多个ABAC属性。 例如:m = r.sub.Domain == r.obj.Domain

提示

如果你需要在与CSV分隔符冲突的策略中使用逗号,你可以通过用引号包围语句来转义它。 例如,"keyMatch("bob", r.sub.Role)"将不会被分割。

扩展模型以适应复杂和大量的ABAC规则

上述ABAC模型的实现在其核心上是简单的。 然而,在许多情况下,授权系统需要复杂和大量的ABAC规则。 为了满足这个需求,建议在策略中添加规则,而不是在模型中。 这可以通过引入eval()功能构造来实现。 这是一个例子:

这是用于定义ABAC模型的CONF文件的定义。

[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

在这个例子中,p.sub_rule是一个结构体或类(用户定义的类型),包含了在策略中使用的必要属性。

这是用于Enforcement的模型对应的策略。 现在,你可以使用传递给eval()的对象实例作为参数来定义某些ABAC约束。

p, r.sub.Age > 18, /data1, read
p, r.sub.Age < 60, /data2, write