1、简介:
Casbin是功能强大且高效的开源访问控制库。支持 ACL,RBAC,ABAC 等常用的访问控制模型。官方文档链接:https://casbin.org/docs/zh-CN/overview
2、Golang使用
2.1初始化Casbin
go get -t github.com/casbin/mongodb-adapter
import (
"github.com/casbin/casbin"
"github.com/casbin/mongodb-adapter"
)
mgoAdapter := mongodbadapter.NewAdapter("mongodb://admin:123123123@10.136.104.179:27017/admin")
mgoEnforcer := casbin.NewEnforcer("/Volumes/liuchen/Go/src/awesomeProject1/test.conf", mgoAdapter) //casbin.NewEnforcer方法接收两个参数,一个是访问控制模型文件(基于PERM模型,见附录)的路径,一个是权限规则文件的路径,支持数据库和文件。
2.2 访问控制模型文件:
Module File 语法:
[request_definition], [policy_definition], [policy_effect], [matchers][role_definition]##
2.2.1 request_definition
[request_definition]
r = sub, obj, act
sub, obj, act
2.2.2 policy_definition
[policy_definition]
p = sub, obj, act
p2 = sub, act
定义的每一行称为 policy rule, p, p2 是 policy rule 的名字. p2 定义的是 sub 所有的资源都能执行 act
2.2.3 policy_effect
对policy生效范围的定义, 原语定义了当多个policy rule同时匹配访问请求request时,该如何对多个决策结果进行集成以实现统一决策。
[policy_effect]
e = some(where (p.eft == allow))
allowallowp.eftallowdenyallowp.eftallow
2.2.4 matchers
定义了策略匹配者。匹配者是一组表达式。它定义了如何根据请求来匹配策略规则。
[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act
2.2.5 role_definition
[role_definition]
g = _, _
g2 = _, _
RBAC角色继承关系的定义。 Casbin 支持 RBAC 系统的多个实例, 例如, 用户可以具有角色及其继承关系, 资源也可以具有角色及其继承关系。 这两个 RBAC 系统不会互相干扰
gg2_, _g
2.3 Go 常用API 基于RBAC
2.3.1添加规则:
mgoEnforcer.AddPolicy("角色1","权限1", "访问规则")
mgoEnforcer.AddPermissionsForUser("角色1","权限1", "访问规则") // 访问规则可为可选
2.3.2 为用户添加角色
mgoEnforcer.AddRoleForUser("用户1", "角色1")
2.3.3 删除用户
mgoEnforcer.DeleteUser("用户1")
2.3.4 删除权限
mgoEnforcer.DeletePermission("权限1")
2.3.4 获取用户角色
res, err := mgoEnforcer.GetRolesForUser("用户1")
2.3.5 获取用户权限
per := mgoEnforcer.GetPermissionsForUser("用户1")
2.3.6 获取拥有该角色的用户
res, err:=mgoEnforcer.GetRolesForUser("角色1")
2.4 多副本实例一致性问题:
关于集群或多实例一致性问题,官方在主库并未集成,采用应用watcher程序来实现观察者模式。目前官方支持golang watcher程序驱动如下:
下附Redis Watch使用代码:
import (
"github.com/casbin/casbin"
"github.com/casbin/casbin/util"
"github.com/billcobbler/casbin-redis-watcher"
)
func updateCallback(msg string) {
util.LogPrint(msg)
}
func main() {
// Initialize the watcher.
// Use the Redis host as parameter.
w, _ := rediswatcher.NewWatcher("127.0.0.1:6379")
// Initialize the enforcer.
e := casbin.NewEnforcer("examples/rbac_model.conf", "examples/rbac_policy.csv")
// Set the watcher for the enforcer.
e.SetWatcher(w)
// Set callback to local example
w.SetUpdateCallback(updateCallback)
// Update the policy to test the effect.
// You should see "[casbin rules updated]" in the log.
e.SavePolicy()
}
附录
1、PERM模型
- Policy: 定义权限的规则
- Effect: 定义组合了多个 Policy 之后的结果, allow/deny
- Request: 访问请求, 也就是谁想操作什么
- Matcher: 判断 Request 是否满足 Policy
2、部分API列表
//获取当前策略中显示的主题列表
allSubjects := e.GetAllSubjects()
//获取当前命名策略中显示的主题列表
allNamedSubjects := e.GetAllNamedSubjects("p")
//获取当前策略中显示的对象列表
allObjects := e.GetAllObjects()
//获取当前命名策略中显示的对象列表
allNamedObjects := e.GetAllNamedObjects("p")
//获取当前策略中显示的操作列表
allActions := e.GetAllActions()
//获取当前命名策略中显示的操作列表
allNamedActions := e.GetAllNamedActions("p")
//获取当前策略中显示的角色列表
allRoles = e.GetAllRoles()
//获取当前命名策略中显示的角色列表
allNamedRoles := e.GetAllNamedRoles("g")
//获取策略中的所有授权规则
policy = e.GetPolicy()
//获取策略中的所有授权规则,可以指定字段筛选器
filteredPolicy := e.GetFilteredPolicy(0, "alice")
//获取命名策略中的所有授权规则
namedPolicy := e.GetNamedPolicy("p")
//获取命名策略中的所有授权规则,可以指定字段过滤器
filteredNamedPolicy = e.GetFilteredNamedPolicy("p", 0, "bob")
//获取策略中的所有角色继承规则
groupingPolicy := e.GetGroupingPolicy()
//获取策略中的所有角色继承规则,可以指定字段筛选器
filteredGroupingPolicy := e.GetFilteredGroupingPolicy(0, "alice")
//获取策略中的所有角色继承规则
namedGroupingPolicy := e.GetNamedGroupingPolicy("g")
//获取策略中的所有角色继承规则
namedGroupingPolicy := e.GetFilteredNamedGroupingPolicy("g", 0, "alice")
// 确定是否存在授权规则
hasPolicy := e.HasPolicy("data2_admin", "data2", "read")
//确定是否存在命名授权规则
hasNamedPolicy := e.HasNamedPolicy("p", "data2_admin", "data2", "read")
//向当前策略添加授权规则。 如果规则已经存在,函数返回false,并且不会添加规则。 否则,函数通过添加新规则并返回true
added := e.AddPolicy("eve", "data3", "read")
// 向当前命名策略添加授权规则。 如果规则已经存在,函数返回false,并且不会添加规则。 否则,函数通过添加新规则并返回true
added := e.AddNamedPolicy("p", "eve", "data3", "read")
// 从当前策略中删除授权规则
removed := e.RemovePolicy("alice", "data1", "read")
// 移除当前策略中的授权规则,可以指定字段筛选器。 RemovePolicy 从当前策略中删除授权规则
removed := e.RemoveFilteredPolicy(0, "alice", "data1", "read")
//从当前命名策略中删除授权规则
removed := e.RemoveNamedPolicy("p", "alice", "data1", "read")
//从当前命名策略中移除授权规则,可以指定字段筛选器
removed := e.RemoveFilteredNamedPolicy("p", 0, "alice", "data1", "read")
//确定是否存在角色继承规则
has := e.HasGroupingPolicy("alice", "data2_admin")
//确定是否存在命名角色继承规则
has := e.HasNamedGroupingPolicy("g", "alice", "data2_admin")
// 向当前策略添加角色继承规则。 如果规则已经存在,函数返回false,并且不会添加规则。 如果规则已经存在,函数返回false,并且不会添加规则
added := e.AddGroupingPolicy("group1", "data2_admin")
//将命名角色继承规则添加到当前策略。 如果规则已经存在,函数返回false,并且不会添加规则。 否则,函数通过添加新规则并返回true
added := e.AddNamedGroupingPolicy("g", "group1", "data2_admin")
// 从当前策略中删除角色继承规则
removed := e.RemoveGroupingPolicy("alice", "data2_admin")
//从当前策略中移除角色继承规则,可以指定字段筛选器
removed := e.RemoveFilteredGroupingPolicy(0, "alice")
//从当前命名策略中移除角色继承规则
removed := e.RemoveNamedGroupingPolicy("g", "alice")
//当前命名策略中移除角色继承规则,可以指定字段筛选器
removed := e.RemoveFilteredNamedGroupingPolicy("g", 0, "alice")