ruoyi接口权限校验

此文章属于ruoyi项目实战系列

ruoyi系统在前端主要通过权限字符包含与否来动态显示目录和按钮。为了防止通过http请求绕过权限限制,后端接口也需要进行相关权限设计。

@PreAuthorize使用

由于对 @PreAuthorize原理还不够深入了解,所以此处只粗浅讲解在ruoyi项目是如何应用的。
在请求调用接口前,被 @preAuthorize注解的接口需要首先通过验证。通过注解参数 value()返回值 truefalse来判断是否有权限。

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 permissions, String permission)
{
    return permissions.contains(ALL_PERMISSION) ||
     permissions.contains(StringUtils.trim(permission)); //判断是否持有"所有权限"字符,或者持有该权限
}

接口权限校验流程

粗略用两个例子来讲解前端请求如何经过后端接口权限校验。

Login匿名请求

ruoyi接口权限校验
  1. Login请求路径是 /login,在过滤器链中被 AnnoymousAuthenticationFilter添加匿名 authentication到Spring上下文里。由于 /login请求在 SecurityConfig.java里设置成匿名请求,所以可以成功到达 SysLoginController
  2. 调用 SysLoginService.login方法,关键的一行命令:
Authentication authentication = authenticationManager
.authenticate(new UsernamePasswordAuthenticationToken(username, password));

authenticationManager.authenticate()是钩子方法,在 AbstractUserDetailsAuthenticationProvider中实现,会根据传入的token类型来自动选择,此处 UsernamePasswordAuthenticationToken将由 DaoAuthenticationProvider来处理(不清楚的话可以前后打两个断点看调用栈)。
3. 在 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());
}
  1. 生成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 filterChains = filterChainProxy.getFilterChains();
        for(SecurityFilterChain sfc:filterChains){
            for(Filter filter:sfc.getFilters()){
                System.out.println(filter.getClass().getName());
            }
        }
    }
}

Original: https://www.cnblogs.com/allworldg/p/ruoyi-learn-1.html
Author: allworldg
Title: ruoyi接口权限校验

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/583390/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 302跳转

    题目如下 打开环境显示如下 点击Give me Flag发生跳转,并且多了index.html 题目提示为HTTP临时重定向,302代表临时转移,通过F12的网络功能找到了302 …

    Linux 2023年6月7日
    089
  • 网络协议及tcp协议详解

    说说TCP三次握手的过程? 第一次握手:Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Ser…

    Linux 2023年6月13日
    099
  • OpenSSL测试-SM3

    任务详情 在openEuler(推荐)或Ubuntu或Windows(不推荐)中完成下面任务 使用OpenSSL的命令计算你的8位学号的摘要值(SM3),提交截图(5’…

    Linux 2023年6月8日
    0110
  • .Net FW项目跑不起来且无Error信息

    阅文时长 | 0.17分钟字数统计 | 280.8字符主要内容 | 1、引言&背景 2、分析步骤 3、解决方案 4、声明与参考资料『.Net FW项目跑不起来且无Error…

    Linux 2023年6月13日
    098
  • shell脚本调试方法

    set -x bash -x test.sh 作者:习惯沉淀 如果文中有误或对本文有不同的见解,欢迎在评论区留言。 如果觉得文章对你有帮助,请点击文章右下角【推荐】一下。您的鼓励是…

    Linux 2023年5月28日
    095
  • Linux搭建SVN服务器详细教程

    前言 本文讲解Linux系统下如何搭建SVN服务器,详细说明各配置项的功能,最终实现可管控多个项目的复杂配置。 SVN是subversion的缩写,是一个开放源代码的版本控制系统,…

    Linux 2023年6月7日
    096
  • 百钱买百鸡问题

    百钱买百鸡问题 题目:公元前5世纪末,中国古代数学家张丘建在他的《算经》中提出了著名的 “百钱买百鸡问题”:鸡翁一,值钱五,鸡母一,值钱三,鸡雏三,值钱一,…

    Linux 2023年6月7日
    0106
  • USB转多串口产品设计

    在部分应用场合下需要为计算机或其他主机扩展多个串口,常见的扩展方式有USB转多串、PCI/PCIe转多串、蓝牙和以太网等网络转多串口。现在大多数台式计算机和笔记本电脑出于轻型化需要…

    Linux 2023年6月7日
    092
  • .NET Core 3.0, 发布将于今晚开始!

    期待已久的.NET Core 3.0即将发布! .NET Core 3.0在.NET Conf上发布。大约还有9个多小时后,.NET Conf开始启动。 第1天-9月23日 9:0…

    Linux 2023年6月7日
    085
  • Redis无法向磁盘写入RBD数据

    由于客户为了安全规范,规定Redis不能再root权限下运行,所以要进行降权切成普通用户等操作,刚刚做完切权操作。客户监控发出来项目服务的报错邮件,经过查看发现是Redis问题. …

    Linux 2023年6月8日
    0114
  • Log4j 2 日志框架

    Apache Log4j 2 是对 Log4j 的升级,它比其前身 Log4j 1.x 提供了显着改进,并提供了 Logback 中可用的许多改进,同时修复了 Logback 架构…

    Linux 2023年6月8日
    091
  • 根据温度、气压计算海拔高度

    基本概念 标准大气压:表示气压的单位,习惯上常用水银柱高度。例如,一个标准大气压等于760毫米高的水银柱的重量,它相当于一平方厘米面积上承受1.0336公斤重的大气压力。由于各国所…

    Linux 2023年6月8日
    0101
  • Python——装饰器(Decorator)

    1.什么是装饰器? 装饰器放在一个函数开始定义的地方,它就像一顶帽子一样戴在这个函数的头上。和这个函数绑定在一起。在我们调用这个函数的时候,第一件事并不是执行这个函数,而是将这个函…

    Linux 2023年6月8日
    0144
  • 个人学习-STL深入学习01-vectory源码研习 // 需要补充

    STL,即标准模板库(Standard Template Library,STL),内部封装了常见的容器和算法。由六部分组成:1.容器(Containers)2.分配器(Alloc…

    Linux 2023年6月6日
    088
  • UWP Add transport control button to taskbar preview

    I want to add transport control button to taskbar preview, like Netease Music. This is rea…

    Linux 2023年6月13日
    0113
  • Docker安装使用及私有仓库搭建

    1 概念 1.1 基本概念 Docker daemon​ 守护进程,运行在宿主机上,用户通过DockerClient客户端Docker命令与Docker daemon交互。Dock…

    Linux 2023年5月27日
    097
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球