ruoyi接口权限校验
此文章属于ruoyi项目实战系列
ruoyi系统在前端主要通过权限字符包含与否来动态显示目录和按钮。为了防止通过http请求绕过权限限制,后端接口也需要进行相关权限设计。
@PreAuthorize使用
由于对@PreAuthorize
原理还不够深入了解,所以此处只粗浅讲解在ruoyi项目是如何应用的。
在请求调用接口前,被@preAuthorize
注解的接口需要首先通过验证。通过注解参数value()
返回值true
和false
来判断是否有权限。
public @interface PreAuthorize {
String value();
}
Ruoyi并没有使用原生的Spel表达式,而是使用了自定义的PermissionService
类,通过其中自定义方法hasPermi(String Permission)
来进行权限判断。注解使用举例:@PreAuthorize("@ss.hasPermi('system:menu:list')")
public boolean hasPermi(String permission)
{
if (StringUtils.isEmpty(permission))//用注解就必须有permission值
{
return false;
}
LoginUser loginUser = SecurityUtils.getLoginUser();
if (StringUtils.isNull(loginUser) ||
CollectionUtils.isEmpty(loginUser.getPermissions()))
{
return false;
}
return hasPermissions(loginUser.getPermissions(), permission);
private boolean hasPermissions(Set<String> permissions, String permission)
{
return permissions.contains(ALL_PERMISSION) ||
permissions.contains(StringUtils.trim(permission)); //判断是否持有"所有权限”字符,或者持有该权限
}
接口权限校验流程
粗略用两个例子来讲解前端请求如何经过后端接口权限校验。
Login匿名请求
Login请求路径是
/login
,在过滤器链中被AnnoymousAuthenticationFilter
添加匿名authentication
到Spring上下文里。由于/login
请求在SecurityConfig.java
里设置成匿名请求,所以可以成功到达SysLoginController
。调用
SysLoginService.login
方法,关键的一行命令:Authentication authentication = authenticationManager
.authenticate(new UsernamePasswordAuthenticationToken(username, password));
authenticationManager.authenticate()
是钩子方法,在AbstractUserDetailsAuthenticationProvider
中实现,会根据传入的token类型来自动选择,此处UsernamePasswordAuthenticationToken
将由DaoAuthenticationProvider
来处理(不清楚的话可以前后打两个断点看调用栈)。在
DaoAuthenticationProvider
中可以看到关键的一行:UserDetails loadedUser = this.getUserDetailsService()
.loadUserByUsername(username);
这会调用我们自定义实现的
UserDetailsServiceImpl#loadUserByUsername
方法(如流程图所示),获得user信息。至于为什么会使用自定义方法,因为在SecurityConfig.java
中进行了配置@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception
{
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
}
生成token,然后返回。
已登录请求
已登录请求流程较简单,在流程图里的some filters里会通过自定义的JwtAuthenticationFilter
,其中会通过token获得user信息,然后装入Spring
的上下文,方便提取使用。
曾纠结踩坑的点
由于对SpringSecurity较陌生,虽然功能强大,但其复杂性也是大大提高,所以调试项目的同时翻看了很多入门博客文章,其中都不约而同的提到了UsernamePasswordAuthenticationFilter
,可是我在实战项目中反复调试都没有看到这个过滤器的调用。
原因:Security配置文件需要添加httpSecurity.formLogin()
启用表单登录才会使用该filter。查看项目使用的所有filter可以使用以下测试代码:
class RuoYiApplicationTest {
@Autowired
private FilterChainProxy filterChainProxy;
@Test
public void test() {
List<SecurityFilterChain> filterChains = filterChainProxy.getFilterChains();
for(SecurityFilterChain sfc:filterChains){
for(Filter filter:sfc.getFilters()){
System.out.println(filter.getClass().getName());
}
}
}
}
ruoyi接口权限校验的更多相关文章
- 使用AOP+自定义注解完成spring boot的接口权限校验
记使用AOP+自定义注解完成接口的权限校验,代码如下: pom文件添加所需依赖: 1 <dependency> 2 <groupId>org.aspectj</group ...
- SpringCloud(8)---zuul权限校验、接口限流
zuul权限校验.接口限流 一.权限校验搭建 正常项目开发时,权限校验可以考虑JWT和springSecurity结合进行权限校验,这个后期会总结,这里做个基于ZuulFilter过滤器进行一个简单的 ...
- Apache shiro之权限校验流程
从张开涛blog学习后整理:http://jinnianshilongnian.iteye.com/blog/2018398 图片原图比较大,建议将图片在新的选项卡打开后100%大小浏览 在权限校验中 ...
- 基于Spring Aop实现类似shiro的简单权限校验功能
在我们的web开发过程中,经常需要用到功能权限校验,验证用户是否有某个角色或者权限,目前有很多框架,如Shiro Shiro有基于自定义登录界面的版本,也有基于CAS登录的版本,目前我们的系统是基于C ...
- SpringBoot系列 - 集成JWT实现接口权限认证
会飞的污熊 2018-01-22 16173 阅读 spring jwt springboot RESTful API认证方式 一般来讲,对于RESTful API都会有认证(Authenticati ...
- 类Shiro权限校验框架的设计和实现(2)--对复杂权限表达式的支持
前言: 我看了下shiro好像默认不支持复杂表达式的权限校验, 它需要开发者自己去做些功能扩展的工作. 针对这个问题, 同时也会为了弥补上一篇文章提到的支持复杂表示需求, 特地尝试写一下解决方法. 本 ...
- 类Shiro权限校验框架的设计和实现
前言: 之前简单集成了springmvc和shiro用于后台管理平台的权限控制, 设计思路非常的优美, 而且编程确实非常的方便和简洁. 唯一的不足, 我觉得配置稍有些繁琐. 当时我有个小想法, 觉得可 ...
- 【JEECG技术文档】JEECG 接口权限开发及配置使用说明
1.功能介绍 通过接口配置实现,对接口的访问权限控制和数据权限控制,接口时REST接口,接口权限认证机制使用Json web token (JWT) 接口权限调用流程: (1)通过接口用户的用户名 ...
- fastDFS shiro权限校验 redis FreeMark页面静态化
FastDFS是一个轻量级分布式文件系统, 使用FastDFS很容易搭建一套高性能的文件服务器集群提供文件上传.下载等服务 FastDFS服务端有两个角色:跟踪器(tracker)和存储节点( ...
随机推荐
- springboot jar包方式部署
打好jar包后上传到 linux 执行命令 java -jar /root/vhr-web-0.0.1-SNAPSHOT.jar > /root/log.txt & 1.java -ja ...
- Unity中制作血条2.0
##1.血量显示 不必像之前那样添加Slider组件 直接创建Image 在添加Source Image之后,将Image Type 修改为Filled 通过修改Fill Mode就可以显示不同效果 ...
- vue3响应式模式设计原理
vue3响应式模式设计原理 为什么要关系vue3的设计原理?了解vue3构建原理,将有助于开发者更快速上手Vue3:同时可以提高Vue调试技能,可以快速定位错误 1.vue3对比vue2 vue2的原 ...
- DjangoRestFramework框架三种分页功能的实现 - 在DjangoStarter项目模板中封装
前言 继续Django后端开发系列文章.刚好遇到一个分页的需求,就记录一下. Django作为一个"全家桶"型的框架,本身啥都有,分页组件也是有的,但默认的分页组件没有对API开发 ...
- css 实现输入效果
<template> <h1>Pure CSS Typing animation.</h1> </template> <script> ...
- 2021.07.23 P2474 天平(差分约束)
2021.07.23 P2474 天平(差分约束) [P2474 SCOI2008]天平 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题意: 已知A,B和每两个点点权,求点权i, ...
- 接口测试实战| GET/POST 请求区别详解
1.请求行的 method 不同:2.POST 可以附加 body,可以支持 form.json.xml.binary等各种数据格式:3.从行业通用规范的角度来说,无状态变化的建议使用 GET 请求, ...
- apparmor 源码分析
这里不对apparmor做介绍,记录一下源码分析过程. 初始化 static int __init apparmor_init(void) -> security_add_hooks(appar ...
- JavaScript 数据结构与算法2(队列和双端队列)
学习数据结构的 git 代码地址: https://gitee.com/zhangning187/js-data-structure-study 1.队列和双端队列 队列和栈非常类似,但是使用了与 后 ...
- 如何形象简单地理解java中只有值传递,而没有引用传递?
首先,java中只有值传递,没有引用传递.可以说是"传递的引用(地址)",而不能说是"按引用传递". 按值传递意味着当将一个参数传递给一个函数时,函数接收的是原 ...