Casbin configuration
rbac_model.conf
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act
[role_definition]
g = _, _
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act
r = sub, obj, actp = sub, obj, actadmin, data, writeAll admins can write data.e = some(where (p.eft == allow))g = _, _Alice, adminm = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act
Policies
Casbin策略文件可以存储在csv文件或者是数据库中,csv格式如下:
p, user, resource, read
p, username, resource, read
p, admin, resource, read
p, admin, resource, write
g, alice, admin
g, bob, user
存储数据库表结构如下:
CREATE TABLE casbin_rule (
p_type VARCHAR(100),
v0 VARCHAR(100),
v1 VARCHAR(100),
v2 VARCHAR(100)
);
INSERT INTO casbin_rule VALUES('p', 'user', 'resource', 'read');
INSERT INTO casbin_rule VALUES('p', 'username', 'resource', 'read');
INSERT INTO casbin_rule VALUES('p', 'admin', 'resource', 'read');
INSERT INTO casbin_rule VALUES('p', 'admin', 'resource', 'write');
INSERT INTO casbin_rule(p_type, v0, v1) VALUES('g', 'alice', 'admin');
INSERT INTO casbin_rule(p_type, v0, v1) VALUES('g', 'bob', 'user');
golang权限控制
github.com/casbin/gorm-adapter/v3
gorm.io/gorm
github.com/casbin/casbin/v2
// 验证每一个角色
func CheckCasbinAuth() gin.HandlerFunc {
return func(c *gin.Context) {
requstUrl := c.Request.URL.Path
method := c.Request.Method
// 用户角色id需要存储在缓存,加快接口验证的效率(2021-03-11 后续实现)
orgIds := [1]int{} // 模拟用户角色
var roleId int
var isPass bool
var err error
enforcer := casbin.NewEnforcer("config/rbac_model.conf", adapter)
// 循环用户角色判断
for i := 0; i < len(orgIds); i++ {
roleId = orgIds[i]
isPass, err = enforcer.Enforce(strconv.Itoa(roleId), requstUrl, method)
if isPass == true {
break
}
}
if err != nil {
response.ErrorCasbinAuthFail(c, err.Error())
return
} else if !isPass {
response.ErrorCasbinAuthFail(c, "")
} else {
c.Next()
}
}
}
// 验证用户,casbin将会去策略数据里自动查找用户的角色(g, alice, admin),在根据角色验证访问权限
func CheckCasbinAuth() gin.HandlerFunc {
return func(c *gin.Context) {
requstUrl := c.Request.URL.Path
method := c.Request.Method
userId := "" // 从登录用户中获取用户ID
var isPass bool
var err error
// 会根据用户ID(或者用户名)查找角色去验证权限
enforcer := casbin.NewEnforcer("config/rbac_model.conf", adapter)
isPass, err = enforcer.Enforce(userId, requstUrl, method)
if err != nil {
response.ErrorCasbinAuthFail(c, err.Error())
return
} else if !isPass {
response.ErrorCasbinAuthFail(c, "")
} else {
c.Next()
}
}
}