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
- 在 matcher 中引用属性(例如
r.sub.Role、r.obj.Owner)。 - 将 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