跳转至主要内容

ABAC

什么是 ABAC?​

基于属性的访问控制(ABAC) 通过评估主体、对象和操作的 属性(例如 resource.Owner、user.Role)来决定访问,而不只是比较身份字符串。 Casbin 让这件事很简单:把结构体或对象传给 Enforce(),在匹配器中引用它们的字段即可。

完整的应用示例,见 Go、Node.js(Express) 和 Python(Flask) 的 ABAC 教程。在 ABAC 和 RBAC 之间如何选择,见 选择访问控制模型。

最小示例:

[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 字段的对象;Casbin 通过反射读取它。在 Go 中可以这样定义:

type testResource struct {
Name string
Owner string
}

也可以传入 JSON 字符串;启用 JSON 处理后,Casbin 会解析它们:

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

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

ok, err := e.Enforce("alice", data1Json, "read")
if err != nil {
// Handle JSON parsing errors
fmt.Printf("Enforcement failed: %v\n", err)
return
}

启用后,任何以 { 或 [ 开头的参数都会被当作 JSON 解析。无效的 JSON 会给出明确的错误;其他字符串保持原样。

// Valid JSON - automatically parsed
validJSON := `{"Name": "alice", "Age": 25}`
ok, err := e.Enforce(validJSON, "data1", "read") // Works correctly

// Invalid JSON - returns descriptive error
invalidJSON := `{"Name": "alice",}` // Trailing comma is invalid in JSON
ok, err := e.Enforce(invalidJSON, "data1", "read")
// Returns: "failed to parse JSON parameter at index 0: ..."

// Plain string - no parsing attempted
plainString := "alice"
ok, err := e.Enforce(plainString, "data1", "read") // Treated as plain string
备注

启用 JSON 参数支持会带来大约 1.1 到 1.5 倍的性能开销。

使用 ABAC​

  1. 在匹配器中引用属性(例如 r.sub.Role、r.obj.Owner)。
  2. 把结构体或类的实例(或 JSON)传给 Enforce()。
警告

ABAC 的属性访问只适用于请求元素(r.sub、r.obj、r.act)。 p.sub 这类策略元素不能使用 ABAC,因为策略中无法存储结构体或类的定义。

提示

匹配器可以同时引用多个属性。示例:m = r.sub.Domain == r.obj.Domain。

提示

当策略中需要使用会与 CSV 解析冲突的逗号时,用引号把表达式括起来。示例:"keyMatch("bob", r.sub.Role)" 可以避免被错误拆分。

用 eval() 实现复杂规则​

对于更复杂的条件,把表达式放在 策略 中,用 eval() 求值,这样模型保持精简,策略保持灵活。

使用 eval() 的模型配置:

[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 是基于请求属性的表达式,在执行时求值。策略示例:

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

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