基于RBAC的权限控制浅析(结合Spring Security)
嗯,昨天面试让讲我的项目,让我讲讲项目里权限控制那一块的,讲的很烂。所以整理一下。
按照面试官的提问流程来讲:
一、RBAC是个啥东西了?
RBAC(Role-Based Access Control ),即基于角色的访问控制模型,我的项目是基于RBAC0模型.由于之相对应的数据实体构成.由用户表,角色映射表,角色表,权限表,权限映射表构成.
图1 RBAC0模型图
二、你可以讲讲权限控制大概执行流程吗?
用户登录之后首先进行身份验证,成功之后获取当前用户的所有角色,之后根据角色加载对应的权限菜单,这里默认不加载没有权限的菜单,当存在直接输入URL路径的情况时,对于登录用户的每一个请求,都会通过鉴权处理,分析角色.最后通过权限的判断分析是否可以访问菜单资源.
在 spring Security,对用登录的请先通过FilterInvocationSecurityMetadataSource的实现类获取当前请求,分析需要的角色,该类的主要功能就是通过当前的请求地址,获取该地址需要的用户角色。
1、获取当前访问路径的URL路径
2、获取所有资源URL,即所有的菜单URL路径
3、当前的访问URL和返回的每个URL基于Ant风格比较,如果相等,获取当前访问URL的所有角色。如果没有相等的,定义资源为公告资源,并且给予一个公告资源的角色。
4、当为公共资源时,判断用户是否登录。登录放行。返回资源
5、当为角色资源时,登录用户的角色列表和该资源的角色列表进行比较,如果有相同角色,放行,返回资源
6、当即不是公共资源也没有相匹配的角色的时候。抛异常,没有权限
图2 系统访问控制流程图
代码:
鉴权:
@Component
public class CustomFilterInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {
@Autowired
MenuService menuService;
//路径比较工具
AntPathMatcher antPathMatcher = new AntPathMatcher();
Logger logger = Logger.getLogger("com.liruilong.hros.config.ustomFilterInvocationSecurityMetadataSource");
/**
* @return java.util.Collection<org.springframework.security.access.ConfigAttribute> * 返回值是 Collection<ConfigAttribute>,表示当前请求 URL 所需的角色。
* @Author Liruilong
* @Description 当前请求需要的角色,该方法的参数是一个 FilterInvocation, 开发者可以从 Filterlnvocation 中提取出当前请求的 URL,
* @Date 18:13 2019/12/24
* @Param [object]
**/
@Override
public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
//获取当前请求路径
String requestUrl = ((FilterInvocation) object).getRequestUrl();
logger.warning(requestUrl);
//获取所有的菜单url路径
List<Menu> menus = menuService.getAllMenusWithRole();
// AntPathMatcher,主要用来实现 ant 风格的 URL 匹配。
for (Menu menu : menus) {
if (antPathMatcher.match(menu.getUrl(), requestUrl)) {
//拥有当前菜单权限的角色
List<Role> roles = menu.getRoles();
String[] strings = new String[roles.size()];
for (int i = 0; i < roles.size(); i++) {
strings[i] = roles.get(i).getName();
}
return SecurityConfig.createList(strings);
}
}
// 没匹配上的资源都是登录,或者为公共资源
return SecurityConfig.createList("ROLE_LOGIN");
}
@Override
public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes)
throws AccessDeniedException, InsufficientAuthenticationException {
for (ConfigAttribute configAttribute : configAttributes) {
String needRole = configAttribute.getAttribute();
if ("ROLE_LOGIN".equals(needRole)) {
if (authentication instanceof AnonymousAuthenticationToken) {
throw new AccessDeniedException("尚未登录,请登录!");
} else {
return;
}
}
Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
for (GrantedAuthority authority : authorities) {
if (authority.getAuthority().equals(needRole)) {
return;
}
}
}
throw new AccessDeniedException("权限不足,请联系管理员!");
}
三、你可以把对应的SQL和表结构写一下吗?
加载所有的菜单资源;返回所有的菜单资源和对应的角色集合,Service端和访问的URL的比较,存在判断角色。(鉴权)
select m.*,r.`id` as rid,r.`name` as rname,r.`namezh` as rnamezh
from menu m,menu_role mr,role r
where m.`id`=mr.`mid` and mr.`rid`=r.`id` order by m.`id`
根据用户ID返回当前用户的全部菜单资源(授权)
select m1.`id`,m1.url,m1.`path`,m1.`component`,m1.`iconCls`,m1.`name`,m1.`requireAuth`,m1.keepAlive,m1.enabled,
m2.id as id2,m2.url as url2,m2.name as name2,m2.`component` as component2,m2.`iconCls` as iconCls2,m2.`keepAlive` as keepAlive2,m2.`path` as path2,m2.`requireAuth` as requireAuth2,m2.enabled as enabled2,m2.parentId as parentId2
from menu m1,menu m2
where m1.`id`=m2.`parentId` and m1.`id`!=1 and m2.`id`
in(select mr.`mid` from hr_role h_r,menu_role mr where h_r.`rid`=mr.`rid` and h_r.`hrid`=#{hrId})
and m2.`enabled`=true order by m1.`id`,m2.`id`
图2 ERBAC数据实体关系图
用户登录之后首先进行身份验证,成功之后获取当前用户的所有角色,之后根据角色加载对应的权限菜单,这里默认不加载没有权限的菜单,当存在直接输入URL路径的情况时,对于登录用户的每一个请求,都会通过鉴权处理,分析角色.最后通过权限的判断分析是否可以访问菜单资源.
用户表:
角色表:
用户角色映射表:
权资源表:
基于RBAC的权限控制浅析(结合Spring Security)的更多相关文章
- ThinkPHP框架下基于RBAC的权限控制模式详解
这几天因为要做一个项目,需要可以对Web应用中通用功能进行封装,其中一个很重要的涉及到了对用户.角色和权限部分的灵活管理.所以基于TP框架自己封装了一个对操作权限和菜单权限进行灵活配置的可控制模式. ...
- 图文详解基于角色的权限控制模型RBAC
我们开发一个系统,必然面临权限控制的问题,即不同的用户具有不同的访问.操作.数据权限.形成理论的权限控制模型有:自主访问控制(DAC: Discretionary Access Control).强制 ...
- Spring Security实现基于RBAC的权限表达式动态访问控制
昨天有个粉丝加了我,问我如何实现类似shiro的资源权限表达式的访问控制.我以前有一个小框架用的就是shiro,权限控制就用了资源权限表达式,所以这个东西对我不陌生,但是在Spring Securit ...
- Spring Security(17)——基于方法的权限控制
目录 1.1 intercept-methods定义方法权限控制 1.2 使用pointcut定义方法权限控制 1.3 使用注解定义方法权限控制 1.3.1 JSR-25 ...
- Spring Security教程之基于方法的权限控制(十二)
目录 1.1 intercept-methods定义方法权限控制 1.2 使用pointcut定义方法权限控制 1.3 使用注解定义方法权限控制 1.3.1 JSR-25 ...
- RBAC: K8s基于角色的权限控制
文章目录 RBAC: K8s基于角色的权限控制 ServiceAccount.Role.RoleBinding Step 1:创建一个ServiceAccount,指定namespace Step 2 ...
- 后端基于方法的权限控制--Spirng-Security
后端基于方法的权限控制--Spirng-Security 默认情况下, Spring Security 并不启用方法级的安全管控. 启用方法级的管控后, 可以针对不同的方法通过注解设置不同的访问条件: ...
- 在ASP.NET MVC中实现基于URL的权限控制
本示例演示了在ASP.NET MVC中进行基于URL的权限控制,由于是基于URL进行控制的,所以只能精确到页.这种权限控制的优点是可以在已有的项目上改动极少的代码来增加权限控制功能,和项目本身的耦合度 ...
- RBAC角色权限控制
RBAC角色权限控制 1. user (用户表) * 用户的基本信息(mid:用户信息id 如图) 2. node (节点表) * 页面(模块\控制器\方法) 3. role_node(角色.节点 ...
随机推荐
- 「从零单排HBase 09」Hbase的那些数据结构和算法
在之前学习MySQL的时候,我们知道存储引擎常用的索引结构有B+树索引和哈希索引. 而对HBase的学习,也离不开索引结构的学习,它使用了一种LSM树((Log-Structured Merge-Tr ...
- CC2530通用IO口的输入输出
一.引脚概述 CC2530有40 个引脚.其中,有21个数字I/O端口,其中P0和P1是8 位端口,P2仅有5位可以使用.P2端口的5个引脚中,有2个需要用作仿真,有2个需要用作晶振.所以可供我们使用 ...
- leetCode刷题 | 两数之和
两数之和: 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是,你不能重复利用这个数 ...
- Excel函数有门槛,是编程
Excel的公式体系,最简单的就是输入“=1+1”.“=2*3”.看起来没有门槛,但实质上是函数式编程,Range写Formula,Power Query写M语言,VBA里写Function.通过菜单 ...
- 如何将项目发布到npm仓库
有时候,我们希望将项目里的模块提升为公共模块,以便其他项目也能使用.在前端可以将模块发布到npm仓库,这样所有项目都可以通过 npm install youProject 使用模块了. 这个过程很简单 ...
- flink进阶篇
Flink 面试--进阶篇 1.Flink是如何支持批流一体的? 2.Flink是如何做到高效的数据交换的? 3.Flink是如何做容错的? 4.Flink 分布式快照的原理是什么? 5.Flink ...
- Mysql 常用函数(2)- if 函数
Mysql常用函数的汇总,可看下面系列文章 https://www.cnblogs.com/poloyy/category/1765164.html if 的作用 根据表达式的某个条件或值结果来执行一 ...
- 09JAVA基础-常用类
1.Scanner //获取键盘输入 Scanner sc = new Scanner(System.in); int num = sc.nextIn(); String str = sc.nextL ...
- android关机流程
关机过程的主要实现在ShutdownThread.java中在关机过程中,主要做了三件事:1.发送关机广播 有的模块可能需要监听手机关机事件,所以在关机时发送关机广播,通知相关模块处理.2.关闭一些主 ...
- fetch方法
在<深入浅出React和Redux>一书中,介绍react与服务器端交互时,用了fetch方法:https://github.com/github/fetch.该网址上有各种使用例子. 安 ...