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
- 在匹配器中引用属性(例如
r.sub.Role、r.obj.Owner)。 - 把结构体或类的实例(或 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.