ruoyi-vue版本(四)@PreAuthorize 注解在若依里面的作用,springsecurity 框架相关的配置

文章详细介绍了SpringSecurity框架中的@PreAuthorize注解的用途,以及如何通过启用GlobalMethodSecurity进行方法级安全配置。此外,还讨论了AuthenticationEntryPointImpl认证失败处理类和LogoutSuccessHandlerImpl自定义退出处理类的实现。文章最后提及了Filter可能会因内部转发而多次执行的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 需求

我们打开若依项目,发现一些接口上面是有@PreAuthorize 注解,那么这个注解的作用是什么?

2 实现

2.1 背景

我们点进去@PreAuthorize 注解 里面的源码,发现他是第三方的jar包里面的,在这里插入图片描述
我们都知道,若依项目是集成了 springsecurity 框架,所以这个注解直接使用的是这个 springsecurity 框架里面的,我们拿上这个注解使用就可以,那么他咋使用,底层逻辑是什么?

2.2 实现

既然若依项目是集成了 springsecurity 框架,那么肯定需要写springsecurity 的配置类,我们找一下

在这里插入图片描述
若依项目集成了很多的第三方的jar包,所以配置类是比较多,在这个ruoyi-framework 模块下,是有一个config文件夹,下面就是放的各种各样jar包的配置文件,我们找到和 springsecurity 框架相关的配置文件。

在这里插入图片描述

2.3 springsecurity 框架相关的配置

2.3.1 @EnableGlobalMethodSecurity详解

当我们想要开启spring方法级安全时,只需要在任何 @Configuration实例上使用 @EnableGlobalMethodSecurity 注解就能达到此目的。同时这个注解为我们提供了prePostEnabled 、securedEnabled 和 jsr250Enabled 三种不同的机制来实现同一种功能。

A. prePostEnabled = true:
会开启 @PreAuthorize@PostAuthorize 两个注解。

@PreAuthorize注解会在方法执行前进行验证,
支持Spring EL表达式;
@PostAuthorize 注解会在方法执行后进行验证,
不经常使用, 适用于验证带有返回值的权限。

Spring EL提供了returnObject,
用于能够在表达式语言中获取返回的对象信息;

B. securedEnabled = true:
会开启@Secured 注解,用来定义业务方法的安全配置,
在调用的接口或方法上使用该注解。

在需要安全控制(一般使用角色或者权限进行控制)的方法上指定
@Secured,达到只有具备那些角色/权限的用户才可以访问该方法。

指定角色时必须以ROLE_开头,不可省略;不支持Spring EL表达式;
如果想要使用@Secured注解指定"AND"条件,
即调用deleteAll方法需同时拥有ADMINDBA角色的用户时,
@Secured便不能实现,

只能使用@PreAuthorize/@PostAuthorize注解。

2.3.2 认证失败处理类AuthenticationEntryPointImpl

这个类是在spring security 配置类里面进行引用的,所以我们先看这个类里面干了什么事情

在这里插入图片描述
在这里插入图片描述
认证失败处理类AuthenticationEntryPointImpl 实现了AuthenticationEntryPoint接口,重写了这个接口的方法

在这里插入图片描述
它在用户请求处理过程中遇到认证异常时,被ExceptionTranslationFilter用于开启特定认证方案(authentication schema)的认证流程。

这里参数request是遇到了认证异常authException用户请求,response是将要返回给客户的相应,方法commence实现,也就是相应的认证方案逻辑会修改response并返回给用户引导用户进入认证流程。

也就是认证失败,就会自动的进方法commence方法里面,走里面的
逻辑;

修改response并返回给用户引导用户进入认证流程。这个是主要的
目的

2.3.3 自定义退出处理类LogoutSuccessHandlerImpl

这个类实现了LogoutSuccessHandler接口,重写了里面的onLogoutSuccess方法,并且这个类上面是@Configuration;
说明当前类是全局配置类;

LogoutSuccessHandler接口是Spring Security框架里面的

为什么要实现这个接口?

大多数业务场景下,自定义登出成功页面也满足不了一些要求,
更别提默认的登出成功页面。这时候,就需要别的方案支持
,幸运的是,Spring Security 框架还真就非常贴心的提供了
这样一个接口 LogoutSuccessHandler, 专门用于处理用户
登出成功请求。当然了,对于 LogoutSuccessHandler 接口,
Spring Security 框架有一些默认的实现,也可以自行扩展。


同用户登录成功的业务场景,在用户登出成功后,我们也要通过邮件、
短信、微信,来通知用户,在什么时间,什么地点,退出了系统。
更甚至,可以通知用户本次登录都操作了那些功能,做了哪些操作
等等。同时,也要把这些信息记录在日志文件中。而这所有的需求,
都可以通过实现 LogoutSuccessHandler 接口来实现。


扩展 LogoutSuccessHandler 接口实现发送信息、日志记录。

@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
    super.onLogoutSuccess(request, response, authentication);this.logger.info(String.format("IP %s,用户 %s, 于 %s 退出系统。", request.getRemoteHost(), authentication.getName(), LocalDateTime.now()));try {
        // 发邮件
        this.emailService.send();// 发短信
        this.smsService.send();// 发微信
        this.weChatService.send();
    } catch (Exception ex) {
        this.logger.error(ex.getMessage(), ex);
    }
}

目前若依项目,当退出的时候,所做的事情是在redis里面清空token,之后异步记录一下日志;

package com.ruoyi.framework.security.handle;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.framework.manager.factory.AsyncFactory;
import com.ruoyi.framework.web.service.TokenService;

/**
 * 自定义退出处理类 返回成功
 * 也就是用户退出系统,在退出之前会默认做的事情
 * @author jing
 */
@Configuration
public class LogoutSuccessHandlerImpl implements LogoutSuccessHandler
{
//    将token的工具类 引入
    @Autowired
    private TokenService tokenService;

    /**
     * 退出处理
     * 
     * @return
     */
    @Override
    public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
            throws IOException, ServletException
    {
//        根据request  获取到用户的信息
        LoginUser loginUser = tokenService.getLoginUser(request);
        if (StringUtils.isNotNull(loginUser))
        {
            String userName = loginUser.getUsername();
            // 删除用户缓存记录    redis  里面进行删除
            tokenService.delLoginUser(loginUser.getToken());
            // 记录用户退出日志
            AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName, Constants.LOGOUT, "退出成功"));
        }

//        直接渲染信息到客户端
        ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.error(HttpStatus.SUCCESS, "退出成功")));
    }
}

2.3.4 filter 为啥会多次执行

在servlet2.3中,Filter会经过一切请求,包括服务器内部使用的forward转发请求和<%@ include file=”/login.jsp”%>的情况

servlet2.4中的Filter默认情况下只过滤外部提交的请求,forward和include这些内部转发都不会被过滤

 就是有可能一个接口里面,使用了forward和include这些内部转发;
 然后继续  执行过滤器

3 @PreAuthorize 注解

通过在PreAuthorize表达式的Bean名称开头添加@来引用注册为组件的Bean。

<think>好的,我需要帮助用户将Ruoyi-Vue升级到Spring Boot 3。首先,我应该回顾一下Ruoyi-Vue的当前技术栈。Ruoyi-Vue是基于Spring Boot、MyBatis和Vue的前后端分离框架,所以升级Spring Boot 3可能会涉及多个组件的兼容性问题。 首先,用户需要确认当前使用的Spring Boot版本。假设他们使用的是Spring Boot 2.x,那么升级到3.0需要遵循官方迁移指南。Spring Boot 3.0需要Java 17及以上,所以第一步是检查项目中的Java版本是否至少是17,并升级JDK。 接下来,修改项目的pom.xml文件,将Spring Boot的版本号改为3.0.0或更高。同时,Spring Boot 3.0对应的Spring Framework版本是6.0,因此可能需要更新相关的依赖项。例如,Spring Security可能会有版本变化,需要对应升级到6.x版本。 另一个关键点是依赖库的兼容性检查。例如,MyBatis的Spring Boot Starter可能需要升级到3.0以上版本。此外,像Druid数据库连接池、PageHelper分页插件等第三方库也需要确认是否支持Spring Boot 3.0。如果有不兼容的情况,可能需要寻找替代库或等待更新。 Jakarta EE的包名变化也是一个重要问题。Spring Boot 3.0将javax替换为jakarta,所以所有涉及到javax.persistence、javax.servlet等的地方都需要替换为jakarta下的相应包。这可能需要批量替换导入语句,或者使用IDE的全局替换功能。 配置文件的调整可能包括安全配置和JPA配置的变化。例如,Spring Security 6.0中的一些配置类或方法可能已被弃用或修改,需要根据新的文档进行调整。同时,数据库驱动类名在Spring Boot 3中可能有变化,比如MySQL的驱动类名可能从com.mysql.cj.jdbc.Driver调整为新的格式,需要检查并更新application.yml中的配置。 代码层面的修改可能涉及废弃API的替换。例如,Hibernate 6.x中某些方法可能不再使用,需要查找并替换为新的方法。此外,单元测试中使用的JUnit版本可能需要升级到JUnit 5,并调整测试注解和断言方法。 升级过程中可能会遇到各种编译错误和运行时异常,需要逐步解决。例如,升级后启动项目时出现ClassNotFoundException或NoSuchMethodError,可能是由于依赖版本不匹配,需要检查并调整依赖版本。同时,注意日志中的错误信息,按照提示进行修复。 测试阶段需要全面覆盖,包括单元测试、集成测试和前端功能测试。确保所有接口正常响应,权限控制生效,数据库操作无误。前端部分如果使用了Vue,可能不需要太多改动,但要确保后端API的变更不会影响前端调用。 最后,参考官方文档和社区资源非常重要。Spring Boot 3的迁移指南、Ruoyi社区的讨论帖、以及GitHub上的Issues都可能提供有用的解决方案。如果遇到无法解决的问题,可以在这些地方寻求帮助。</think>将 Ruoyi-Vue 升级到 Spring Boot 3 需分步骤处理兼容性问题,以下是详细流程: --- ### **1. 环境准备** - **JDK 版本升级**:Spring Boot 3 要求 Java 17+,需安装 JDK 17 并配置环境变量。 - **IDE 支持**:确保 IntelliJ IDEA 或 Eclipse 支持 Java 17 语法。 --- ### **2. 修改依赖版本** 在 `ruoyi/pom.xml` 中更新 Spring Boot 版本: ```xml <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.0.0</version> <!-- 或最新版本 --> </parent> ``` 同时更新相关依赖: - Spring Security 升级到 6.0+ - MyBatis Spring Boot Starter 升级到 3.0+ - 其他依赖如 `druid-spring-boot-starter`、`pagehelper-spring-boot-starter` 需兼容 Spring Boot 3[^1]。 --- ### **3. Jakarta EE 包替换** 全局替换 `javax.*` 为 `jakarta.*`,例如: - `javax.servlet` → `jakarta.servlet` - `javax.persistence` → `jakarta.persistence` 可通过 IDE 的 **Replace in Path** 功能批量操作。 --- ### **4. 配置文件调整** - **数据库驱动类名**:在 `application.yml` 中修改: ```yaml spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/ry_vue?useSSL=false ``` - **安全配置**:Spring Security 6 默认启用 CSRF,若需禁用,需显式配置: ```java @Configuration public class SecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.csrf().disable(); return http.build(); } } ``` --- ### **5. 代码适配** - **JPA/Hibernate**:检查实体类注解是否兼容 Jakarta EE。 - **废弃 API**:例如 `SpringExtension` 在 JUnit 5 中需替换为 `@ExtendWith`。 - **Web 层**:若使用 `Servlet API`,需确保导入 `jakarta.servlet.http.HttpServletRequest`。 --- ### **6. 测试与调试** - **编译错误**:优先解决依赖冲突(使用 `mvn dependency:tree` 分析)。 - **权限问题**:Spring Security 6 的权限表达式语法可能变化,需检查 `@PreAuthorize` 注解- **前端联调**:确保接口路径和参数格式与 Vue 前端匹配。 --- ### **参考资源** - [Spring Boot 3 迁移指南](https://spring.io/projects/spring-boot#overview)[^2] - [Ruoyi 社区讨论帖](https://gitee.com/y_project/RuoYi-Vue/issues) ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一写代码就开心

你的打赏将是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值