权限模型
先回顾总结下之前做权限设计的经验。权限设计的核心在于怎么合理的给每个人分配权限,其中的核心我理解有三个:用户,资源,策略。用户的主体是人,资源可以是页面/按钮/api等,策略是指定用户应该按照何种规访问哪些资源。权限模型总的来说可以分为5类:
- ACL:Access Control List,访问控制列表。简单理解为将资源的访问权限记录下,资源能否访问先查表,window的文件系统就是这种模式的应用。
- DAC:Discretionary Access Control,自主访问控制(ACL的拓展)。简单理解为在 ACL 基础上,拥有权限的用户自主的给其他人赋予资源的访问权限。
- MAC: Mandatory Access Control,强制访问控制。简单理解为用户和资源都设置了权限限制,用户访问资源需要验证用户身份和资源的访问级别。
- RBAC:Role-Based Access Control,基于角色的权限访问控制。简单理解为给用户赋予特定的角色,角色上赋予资源的访问权限。RBAC目前是主流的权限控制模型,细分为RBAC0,RBAC1,RBAC2,RBAC3。
- ABAC:Attribute-Based Access Control,基于属性的访问控制。简单理解为通过策略(访问规则的描述)来限定资源的访问,策略可以用在用户上,也可以用在资源上。
// 阿里云 RAM 策略配置表
{"Version": "1","Statement":[{"Effect": "Allow","Action": ["oss:List*", "oss:Get*"], // 请求的描述"Resource": ["acs:oss:*:*:samplebucket", "acs:oss:*:*:samplebucket/*"], // 资源的描述"Condition": // 约束条件的描述 {"IpAddress": {"acs:SourceIp": "42.160.1.0"}}}]
}
RBAC 权限模型
RBAC 作为主流的权限控制模型有3个基础组成部分,分别是:用户、角色和权限:
- 用户:可以是单个用户,也可以是用户组
- 角色:可以定义为单个角色,也可以将同类型的角色做成角色集,上下级的角色定义为岗位
- 权限:可以分为两大类:功能权限和数据权限。功能权限是指菜单(页面),按钮(api)等这类权限。数据权限是指对数据访问范围的区分,如根据国家区分数据的访问范围。
RBAC 模型分类
RBAC0:最基础 RBAC 模型,。在这个模型中,我们把权限赋予角色,再把角色赋予用户。用户和角色,角色和权限都是多对多的关系。用户拥有的权限等于他所有的角色持有权限之和。
![](https://i-blog.csdnimg.cn/blog_migrate/615604fb93f9cf63186ef22b90782642.png)
RBAC1:RBAC1建立在RBAC0基础之上,在角色中引入了继承的概念。简单理解就是,给角色可以分成几个等级,每个等级权限不同,从而实现更细粒度的权限管理。角色集和岗位就是RBAC1的应用。
![](https://i-blog.csdnimg.cn/blog_migrate/7c8143c10f5e8c319fe6abaa572acce3.png)
RBAC2:RBAC2同样建立在RBAC0基础之上,对用户、角色和权限三者之间增加了一些限制。这些限制可以分成两类,即静态职责分离SSD(Static Separation of Duty)和动态职责分离DSD(Dynamic Separation of Duty)。
![](https://i-blog.csdnimg.cn/blog_migrate/c75cb68b29dd85af10309846d51ba28f.png)
RBAC3:RBAC3 = RBAC1 + RBAC2,所以RBAC3既有角色分层,也包括可以增加各种限制。
前端功能权限实现
对于前端来说,权限控制体现在页面和按钮是否显示。结合 vue-element-admin 看看页面的显示控制是怎么完成的。 在 vue-element-admin 中,页面的显示控制是获取到角色后,找到 route.meta.roles
符合的角色生成 asyncRoutes
通过 router.addRoutes
动态生成 routes
。侧边栏 SideBar
组件遍历路由生成该角色的菜单栏导航。 具体实现过程描述如下:
1.创建vue实例的时候将vue-router挂载,但这个时候vue-router挂载一些登录或者不用权限的公用的页面。
2.当用户登录后,获取用户role,将role和路由表每个页面的需要的权限作比较,生成最终用户可访问的路由表。
3.调用router.addRoutes(store.getters.addRouters)添加用户可访问的路由。
4.使用vuex管理路由表,根据vuex中可访问的路由渲染侧边栏组件。
页面功能权限
页面权限功能的总体逻辑在beforeEach,代码如下:
router.beforeEach(async(to, from, next) => {// start progress barNProgress.start()// set page titledocument.title = getPageTitle(to.meta.title)// determine whether the user has logged inconst hasToken = getToken()if (hasToken) {if (to.path === '/login')