云原生|Go-Micro实践中如何进行权限设置?
本期摘要
Go Micro是一个插件化的基础微服务框架,它是一部分微服务工具的集合。基于该框架可以构建出微服务应用程序。
本文就作者的亲身实践,为各位分享Go Micro项目中的权限设置。
作者
王凯 | 后端开发工程师
争取当一名努力学习,默默踩坑的工程师
01
权限设计模型
本次权限设计使用的模型为RBAC 模型,基于角色的访问控制(Role-Based Access Control)迄今为止最为普及的权限设计模型。
角色连接用户和权限的关系,每个角色可以关联多个权限,一个用户关联多个角色,那么用户就可以拥有多个角色的多个权限。这样做的好处就是引入了“角色”概念后,管理员只需要把角色赋予给用户,那么用户拥有了角色的所有权限,这样设计可以提升了效率,也提高了扩展性。
权限是可访问资源,这个资源包括页面访问的资源,对某一项操作的权限,数据是否可访问权限等。
//权限设计架构图
02
权限控制
权限控制分为两个部分:
一、使用Casbin 做基础的权限验证
Casbin 是一个支持 ACL,RBAC,ABAC 等访问模型,可用于多种语言(如 Golang,Java,C/C++ 等)的授权库。它拥有灵活的策略存储方式,已支持 Mysql,Postgres,Oracle 等数十种数据库。
Casbin 可以:
-
支持自定义请求的格式,默认的请求格式为{subject, object, action}。
-
具有访问控制模型model和策略policy两个核心概念。
-
支持RBAC中的多层角色继承,不止主体可以有角色,资源也可以具有角色。
-
支持内置的超级用户 例如:root 或 administrator。超级用户可以执行任何操作而无需显式的权限声明。
-
支持多种内置的操作符,如 keyMatch,方便对路径式的资源进行管理,如 /foo/bar 可以映射到 /foo*
Casbin 不能:
-
身份认证 authentication(即验证用户的用户名和密码),Casbin 只负责访问控制。应该有其他专门的组件负责身份认证,然后由 Casbin 进行访问控制,二者是相互配合的关系。
-
管理用户列表或角色列表。Casbin 认为由项目自身来管理用户、角色列表更为合适, 用户通常有他们的密码,但是 Casbin 的设计思想并不是把它作为一个存储密码的容器。而是存储RBAC方案中用户和角色之间的映射关系。
基于Casbin权限验证编写成一个API接口,用于验证用户是否有权限访问:
基于Gorm实现Casbin的验证可参考: https://github.com/casbin/gorm-adapter
伪代码可参考:
package main import ( "github.com/casbin/casbin/v2" gormadapter "github.com/casbin/gorm-adapter/v3" _ "github.com/go-sql-driver/mysql" ) // 网关中间件中调用Casbin认证 func gateway(){
ValidationAuthority("alice", "data1", "read")
} // 使用Gorm验证访问权限 func ValidationAuthority(sub string, obj string, act string) {
a, _ := gormadapter.NewAdapter("mysql", "mysql_username:mysql_password@tcp(127.0.0.1:3306)/") // Your driver and data source. e, _ := casbin.NewEnforcer("examples/rbac_model.conf", a)
e.LoadPolicy()
e.Enforce(sub, obj, act)
e.SavePolicy()
}
rbac_model.conf 可参考 https://github.com/casbin/casbin
在 Casbin 中, 访问控制模型被抽象为基于 PERM (Policy, Effect, Request, Matcher) 的一个配置文件。因此,切换或升级项目的授权机制与修改配置一样简单。您可以通过组合可用的模型来定制您自己的访问控制模型。例如,您可以在一个model中结合RBAC角色和ABAC属性,并共享一组策略规则。
[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
上述文件是Casbin 抽象 RBAC的一个配置文件,Casbin集成了多种角色权限配置,官方提供不同的访问模型策略: https://casbin.org/zh/docs/supported-models
二、使用配置文件控制权限的颗粒度
自定义一个 rule_config.yaml 文件定义需要操控的接口,get_app 可以是前端UI组件的别名,也可以是定义的某个组件显示的参数条件,通过key,value 模式来操作UI组件的显示
rule: get_app: /api/v1/home/app get_defaultApp: /api/v1/home/defaultApp get_log: /api/v1/home/log
流程图:
返回结构:
1.判断是否是系统管理员(定义部分页面只有系统管理员才能访问,比如角色管理,组管理等)
2.动态菜单,通过可访问权限控制菜单列表的显示
3.权限列表,通过权限列表控制页面中颗粒度较细的UI组件
{ "is_system_admin": false, "menus":[ "id": 1, "name": "index", "path": "/index" ] "rule": [ "get_app", "get_log" ]
}
通过配置文件来控制UI界面的组件,这种方式是为了方便后续修改及定义。