认证鉴权框架SpringSecurity-6--6.x版本升级篇

1、Springboot和springSecurity版本关系

前面少介绍了一个概念,springSecurity是spring家族的一员,springboot同样也是spring家族的一员。我们在pom中引入使用springboot时,需要指定springboot的版本。在引入springSecurity时,则不需要指定版本,spring会默认添加最匹配的版本。

版本主要关系如下:

Springboot2.X版本--对应springSecurity5.X版本

Springboot3.X版本--对应springSecurity6.X版本

2、5.X版本和6.X版本的区别

Spring Security 6.x 引入了一些重要的变化和改进,与之前的版本(如 Spring Security 5)相比有一些区别。最主要的区别就是弃用了WebSecurityConfigurerAdapter 类,使用了更加组件式的配置。简单来说就是直接定义一个或多个 SecurityFilterChain通过 bean方式注入spring容器中就达到了配置安全规则的结果。

3、升级改造流程

(1)、引入springboot3.X版本依赖

java 复制代码
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>my-security-app</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.0.0</version>
        <relativePath/> <!-- lookup parent from repository -->
</parent>

    <dependencies>
        <!-- Spring Boot Starter Security -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

        <!-- Spring Boot Starter Web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
</project>

(2)、老版5.x版本的配置升级

1、老版本5.x配置类示例
java 复制代码
import com.demo.exception.CustomAuthenticationFailureHandler;
import com.demo.exception.Http401AuthenticationEntryPoint;
import com.demo.filter.JWTAuthenticationFilter;
import com.demo.filter.JWTLoginFilter;
import com.demo.service.CustomAuthenticationProvider;
import com.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

/**
 * SpringSecurity的配置
 * 通过SpringSecurity的配置,将JWTLoginFilter,JWTAuthenticationFilter组合在一起
 */
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, jsr250Enabled = true, prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    /**白名单*/
    private static final String[] AUTH_WHITELIST = {
            "/v2/api-docs",
            "/swagger-resources/**",
            "/test/**"
    };

    @Autowired
    private UserService userService;
    @Autowired
    private CustomAuthenticationFailureHandler customAuthenticationFailureHandler;

    // 设置 HTTP 验证规则
    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.cors().and().csrf().disable()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
                .authorizeRequests()
                .anyRequest().authenticated() 
                .and()
                .exceptionHandling()
                .authenticationEntryPoint(
                        new Http401AuthenticationEntryPoint())
                .and()
                .addFilterBefore(new JWTLoginFilter(authenticationManager(),customAuthenticationFailureHandler,userService), UsernamePasswordAuthenticationFilter.class)
                .addFilterBefore(new JWTAuthenticationFilter(authenticationManager(),userService), UsernamePasswordAuthenticationFilter.class);        httpSecurity.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER);
    }
    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 使用自定义认证提供者
        auth.authenticationProvider(new CustomAuthenticationProvider(userService));
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        // 白名单接口放行
        web.ignoring().antMatchers(AUTH_WHITELIST);
    }
}
2、新版本6.x配置类示例

注意看的地方

java 复制代码
import com.demo.exception.CustomAuthenticationFailureHandler;
import com.demo.exception.Http401AuthenticationEntryPoint;
import com.demo.filter.JWTAuthenticationFilter;
import com.demo.filter.JWTLoginFilter;
import com.demo.service.CustomAuthenticationProvider;
import com.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

/**
 * SpringSecurity的配置
 * 通过SpringSecurity的配置,将JWTLoginFilter,JWTAuthenticationFilter组合在一起
 */
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, jsr250Enabled = true, prePostEnabled = true)
public class WebSecurityConfig {

    /**白名单
     */
    private static final String[] AUTH_WHITELIST = {
            "/v2/api-docs",
            "/swagger-resources",
            "/test/**"
    };

    @Autowired
    private UserService userService;

    @Autowired
    private CustomAuthenticationFailureHandler customAuthenticationFailureHandler;

    @Bean    构建过滤器链返回
    protected SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.cors().and().csrf().disable()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
                .authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .exceptionHandling()
                .authenticationEntryPoint(
                        new Http401AuthenticationEntryPoint())
                .and()
                .addFilterBefore(new JWTLoginFilter(authenticationManager(),customAuthenticationFailureHandler,userService), UsernamePasswordAuthenticationFilter.class)
                .addFilterBefore(new JWTAuthenticationFilter(authenticationManager(),userService), UsernamePasswordAuthenticationFilter.class);
        httpSecurity.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER);
		
		httpSecurity.authenticationProvider(new CustomAuthenticationProvider(userService))   使用自定义认证提供者,直接封装到httpSecurity中	
		
		return http.build();     构建过滤链并返回
    }

   @Bean
    public WebSecurityCustomizer webSecurityCustomizer() {
         白名单接口放行
		return (web) -> web.ignoring().antMatchers(AUTH_WHITELIST);
    }
}

(3)、升级总结

1、6.X的配置类不在继承WebSecurityConfigurerAdapter抽象类

2、HttpSecurity配置后,需要调用.build方法生成过滤器链返回,注入到容器中。

3、自定义的UserDetailService不需要AuthenticationManagerBuilder指定,直接注入spring容器就行。

4、自定义AuthenticationProvider认证方式,通过HttpSecurity配置,添加到过滤器链中。

5、白名单返回WebSecurityCustomizer 对象。

相关推荐
你的人类朋友31 分钟前
“签名”这个概念是非对称加密独有的吗?
前端·后端·安全
南尘NCA866638 分钟前
企业微信防封防投诉拦截系统:从痛点解决到技术实现
java·网络·企业微信
怪兽20141 小时前
SQL优化手段有哪些
java·数据库·面试
ss2731 小时前
手写MyBatis第107弹:@MapperScan原理与SqlSessionTemplate线程安全机制
java·开发语言·后端·mybatis
携欢2 小时前
PortSwigger靶场之CSRF where token validation depends on request method通关秘籍
安全·web安全·csrf
周杰伦_Jay2 小时前
【计算机网络表格图表解析】网络体系结构、数据链路层、网络层、传输层、应用层、网络安全、故障排查
计算机网络·安全·web安全
Deschen2 小时前
设计模式-原型模式
java·设计模式·原型模式
麦麦鸡腿堡2 小时前
Java的动态绑定机制(重要)
java·开发语言·算法
それども2 小时前
SpringBootTest运行线程池被拒绝
java
介一安全3 小时前
【Frida Android】基础篇6:Java层Hook基础——创建类实例、方法重载、搜索运行时实例
android·java·网络安全·逆向·安全性测试·frida