两种RBAC权限控制模型详解
序言
由于最近一直卡在权限控制这个坎上,原来设计的比较简单的权限控制思路已经无法满足比较复杂一些的场景,因此一直在探索一种在大部分场景下比较通用的权限模型。
首先,这里说明一下两种RBAC权限模型分别是“基于角色的权限控制(Role-Based-Access-Control)”和“基于资源的权限控制(Resource-Based-Access-Control)”两种模型,这两种模型是Java最常见的权限控制的模型。它们之间的数据库结构区别并没有太大,甚至也可以一样。都是以最基础的五张表(用户表、角色表、用户-角色关系表、权限表、角色-权限关系表)组成,往后再复杂的业务再在这个基础上进行拓展,例如加入用户组、组织、模块等等概念,可以参考一下一这篇文章:
https://blog.csdn.net/qiaqia609/article/details/38102091
下面就以Spring Boot + Shiro为载体来具体记录一下。
1.准备数据库

这里还是贴一下Shiro的配置文件:ShiroConfig.java
-
/**
-
* @author phw
-
* @date Created in 04-08-2018
-
* @description 基于RESTFul风格的Shiro配置
-
*/
-
@Slf4j
-
@Configuration
-
public class ShiroConfig {
-
-
@Bean
-
public DefaultWebSecurityManager securityManager(MyShiroRealm myShiroRealm) {
-
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
-
securityManager.setRealm(myShiroRealm);
-
-
/**
-
* 关闭shiro自带的session管理
-
* http://shiro.apache.org/session-management.html#SessionManagement-StatelessApplications%28Sessionless%29
-
*/
-
DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
-
DefaultSessionStorageEvaluator evaluator = new DefaultSessionStorageEvaluator();
-
evaluator.setSessionStorageEnabled(false);
-
subjectDAO.setSessionStorageEvaluator(evaluator);
-
securityManager.setSubjectDAO(subjectDAO);
-
-
return securityManager;
-
}
-
-
@Bean
-
public ShiroFilterFactoryBean shiroFilter(DefaultWebSecurityManager securityManager) {
-
ShiroFilterFactoryBean filterFactoryBean = new ShiroFilterFactoryBean();
-
//filterFactoryBean.setLoginUrl("/sign-in");
-
//添加自己的过滤器并取名jwt
-
Map<String, Filter> filterMap = new HashMap<>();
-
filterMap.put("jwt", new JWTFilter());
-
filterFactoryBean.setFilters(filterMap);
-
filterFactoryBean.setSecurityManager(securityManager);
-
filterFactoryBean.setUnauthorizedUrl("/401");
-
-
//自定义url规则
-
Map<String, String> filterRuleMap = new LinkedHashMap<>();
-
// 访问401和404页面不通过我们的Filter
-
/*filterRuleMap.put("/401", "anon");
-
filterRuleMap.put("/403", "anon");
-
filterRuleMap.put("/404", "anon");
-
filterRuleMap.put("/sign-in", "anon");
-
filterRuleMap.put("/sign-up", "anon");
-
filterRuleMap.put("/sign-out", "logout");
-
// 所有请求通过自己的JWT Filter
-
filterRuleMap.put("/**", "jwt");*/
-
-
/*List<Permission> permissions = permissionMapper.selectAll();
-
for (Permission permission: permissions) {
-
filterRuleMap.put(permission.getUrl(), permission.getInit());
-
}
-
filterFactoryBean.setFilterChainDefinitionMap(filterRuleMap);
-
log.info("Shiro Filter Factory Bean inject successful...");*/
-
return filterFactoryBean;
-
}
-
-
@Bean
-
@DependsOn("lifecycleBeanPostProcessor")
-
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
-
DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
-
// 强制使用cglib,防止重复代理和可能引起代理出错的问题
-
// https://zhuanlan.zhihu.com/p/29161098
-
advisorAutoProxyCreator.setProxyTargetClass(true);
-
return advisorAutoProxyCreator;
-
}
-
-
@Bean
-
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
-
return new LifecycleBeanPostProcessor();
-
}
-
-
@Bean
-
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
-
AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
-
advisor.setSecurityManager(securityManager);
-
return advisor;
-
}
-
-
}
这里配置的是无状态(stateless)的shiro配置,因为要用到RESTful协议,所以需要使用jwt来保证api的安全。所以这里需要关闭掉Shiro自带的Session管理器,然后启用Shiro注解,自定义URL规则会在稍后说到。
2.Role Based Access Control
首先,来说一下比较常见的基于角色的权限控制。
我们所说的角色,其实就是一系列权限的集合,里面指定了哪种角色可以做什么事情,而用户也可以看作是一组角色的集合,所以我们在使用第一种rbac来进行权限控制的时候,一般是判断一个用户是否有某一个角色。我们用Shiro来讲就是像下面这样:
-
@RequiresRoles("admin")
-
//或者
-
if(SecurityUtils.getSubject().hasRole("admin")) {
-
//do some thing...
-
System.out.println("I'm admin.")
-
}
上面的代码是很多文章集成shiro后成功的样子,我当时也是这么做的,但是随着后来权限管理的业务越来越复杂,这种简单的或者说静态的权限管理模型已经不适用了,举个栗子:如果现在我要增加一个角色,名字叫teacher,让它也能打印一点东西。那么要做的就是首先在数据库添加角色名,然后修改权限代码,改成:
@RequiresRoles(value = {"admin", "teacher"}, logical = Logical.OR)
或者类似。也就是说,每一次变更需求,都需要变更代码,然后重新部署项目~~这显然是不怎么符合我们预期要求的。
因此这种模型只适合对权限需求变动不大的场景了。
当然,优点就是非常简单,开发起来使用起来非常方面,特别是配合上Shiro,一个注解就能搞定。
3.Resource Based Access Control
第二种基于资源的权限控制,是第一种的优化方案,我们还是来看看栗子:
-
@RequiresPermissions("user:add")
-
//或者
-
if(SecurityUtils.getSubject().hasPermission("user:add")) {
-
//do some thing...
-
System.out.println("user:add");
-
}
这种方式在一定程度上解决了上述第一种模型的问题,网上也有很多关于Resource Based Access Control的解释,但是这里我用我自己的话来解释一下,还是用上面的栗子,客户要求“admin”和“teacher”都有权限去打印一些东西。于是,第二种就不需要再修改代码了,我直接在前台给teacher授权“user:add”这个权限就可以了啊,因为这样已经很明确的指定了执行这个方法需要什么权限,就是“user:add”权限,我现在不管你是什么角色,什么组织,什么模块也好,只要你拥有这个“user:add”这个权限,那你就能执行这个方法。
但是,问题又来了。
如果现在需求变更,执行这个方法需要另外一个权限“user:edit”怎么办?是不是又得像上面那样,修改代码,重新部署项目。
所以,我们还需要一种能够完全动态控制权限的模型,不把任何权限或者角色写死,直接在数据库(前台)配置,每增加一个功能就注册一个功能然后指定它的需要的权限,就算需求变更,也不需要重新部署项目,只需要在前台稍微修改配置一下就能达到目的。
太晚了,今天就写到这里吧,预知后事如何,请听下回.......分解........
原文地址:https://blog.csdn.net/qq_33698579/article/details/80159823
两种RBAC权限控制模型详解的更多相关文章
- python RBAC权限控制模型扩展 基于JWT实现
jwt,全称 json web token,是使用一定的加密规则生成的token串来保证登录状态.验证用户身份.做权限认证等工作 以往保存用户登录状态多用session实现,但是当服务涉及多台服务器分 ...
- php_ThinkPHP的RBAC(基于角色权限控制)详解
一.什么是RBAC 基于角色的访问控制(Role-Based Access Control)作为传统访问控制(自主访问,强制访问)的有前景的代替受到广泛的关注. 在RBAC中,权限与角色相关联,用户通 ...
- ThinkPHP框架下基于RBAC的权限控制模式详解
这几天因为要做一个项目,需要可以对Web应用中通用功能进行封装,其中一个很重要的涉及到了对用户.角色和权限部分的灵活管理.所以基于TP框架自己封装了一个对操作权限和菜单权限进行灵活配置的可控制模式. ...
- IPVS和Nginx两种WRR负载均衡算法详解
动机 五一临近,四月也接近尾声,五一节乃小长假的最后一天.今天是最后一天工作日,竟然感冒了,半夜里翻来覆去无法安睡,加上窗外大飞机屋里小飞机(也就是蚊子)的骚扰,实在是必须起来做点有意义的事了! ...
- 两种CSS3圆环进度条详解
晚上睡觉之前,我抽了1个多小时,研究了一下圆环进度条,结合从网上查阅的资料,我终于掌握了两种圆环的生成方法. 这次的效果就是单纯的CSS3效果,也没有写具体的JS,等以后有时间在好好整理一下吧~. 第 ...
- 两种Redis持久化原理的详解
Redis为持久化提供了两种方式: RDB:在指定的时间间隔能对你的数据进行快照存储. AOF:记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据. 本文将通过下面内容的介 ...
- 图文详解基于角色的权限控制模型RBAC
我们开发一个系统,必然面临权限控制的问题,即不同的用户具有不同的访问.操作.数据权限.形成理论的权限控制模型有:自主访问控制(DAC: Discretionary Access Control).强制 ...
- Kubernetes-16:一文详解ServiceAccount及RBAC权限控制
一.ServiceAccount 1.ServiceAccount 介绍 首先Kubernetes中账户区分为:User Accounts(用户账户) 和 Service Accounts(服务账户) ...
- yii2搭建完美后台并实现rbac权限控制实例教程
1.安装yii2 未安装的请参考yii2史上最简单式安装教程,没有之一 或者参考yii2实战教程之详细安装步骤 已安装的请继续看下一步操作 2.配置数据库 2.1 配置数据库 修改common/con ...
随机推荐
- ArcGIS Data Interoperability 的使用(1)
今天在用OneMap的时候,发现OneMap中注册过后的WFS服务无法在skyline中加载,于是想知道OneMap注册后的WFS服务与server中的原生态WFS服务有啥区别.首先想到是否能在Arc ...
- 英语-汉语600句-会见:Making an Appointment/约会
ylbtech-英语-汉语600句-会见:Making an Appointment/约会 1.返回顶部 1. Making an Appointment/约会1.喂,请问是哪位?Hello, who ...
- pycharm 安装与激活
---恢复内容开始--- 环境:Windows 专业版 1.下载安装 1.到官网下载专业版(专业版功能更全(但要激活码),社区版免费) 2.下载完后双击.exe 文件进行安装 NEXT 下一步 NEX ...
- SpringCloud是如何运行的?
SpringCloud是基于SpringBoot这一高度自动化的应用开发框架,将各类业界比较知名的.得到过实践反馈的开元服务治理相关的技术框架进行优化整合的框架,是一种开发方式的优化和组合,,是一组框 ...
- PHP实现定时任务(非linux-shell方式,与操作系统无关)
页面交互效果 下面是写好的示例前端交互页面,主要是列表页面,编辑页面. 主要交互有: 1 开启定时任务进程 2 关闭定时任务进程 3 新增一项定时任务 4 编辑已有的定时任务 5 删除定时任务 6 开 ...
- leetcode 850. Rectangle Area II
给定一些矩形2 求覆盖面积 矩形不超过200个 1 算法1 朴素思想 虽然朴素但是代码却有意思 利用容斥原理 复杂度高达 N*2^N class Solution: def intersect(rec ...
- leetcode 448 - 476
448. Find All Numbers Disappeared in an Array Input: [4,3,2,7,8,2,3,1] Output: [5,6] 思路:把数组的内容和index ...
- TZ_15Spring-Cloud_Eureka-Ribbon-Hystix-Feign-Zuul微服务整合
1.一个微服务框架的基本流程 2.Eureka --Feign-Zuul Eureka:就是服务注册中心(可以是一个集群),对外暴露 ...
- angular1.0 $http jsonp callback
$http.jsonp(sDUrl,{cache:false,jsonpCallbackParam:'callback'}); https://stackoverflow.com/questions/ ...
- 微信小程序中自定义swiper轮播图面板指示点的样式
重置样式: .swiper{ width: 100%; height: 240px; margin-bottom: 0.5rem; position:relative; } div.wx-swiper ...