跳转到主要内容

ABAC

什么是 ABAC?​

基于属性的访问控制(Attribute-Based Access Control,ABAC) 通过评估 subject、object 和 action 的 属性(例如 resource.Owner、user.Role)来决定访问,而不仅仅依据身份字符串。Casbin 让这件事变得简单:你把 struct 或对象传入 Enforce(),并在 matcher 中引用它们的字段。

最简示例:

[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. 在 matcher 中引用属性(例如 r.sub.Role、r.obj.Owner)。
  2. 将 struct 或 class 实例(或 JSON)传入 Enforce()。
警告

ABAC 属性访问仅对请求元素(r.sub、r.obj、r.act)有效。像 p.sub 这样的策略元素无法使用 ABAC,因为策略中不能存储 struct 或 class 定义。

提示

Matcher 可以同时引用多个属性。示例: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 是一个基于请求属性的表达式,在 enforce 时求值。示例策略:

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