比较Spring Security6.X 和 Spring Security 5.X的不同

项目使用了SpringBoot3 ,因此 SpringSecurity也相应进行了升级 版本由5.4.5升级到了6.1.5 写法上发生了很大的变化,最显著的变化之一就是对 WebSecurityConfigurerAdapter 类的使用方式的改变。这个类在 Spring Security 中被广泛用于自定义安全配置。以下是主要的差异和写法上的变化:

  1. 废弃 WebSecurityConfigurerAdapter

    • 在 Spring Security 5.x 版本中,WebSecurityConfigurerAdapter 是实现安全配置的常用方法。用户通过继承这个类,并覆盖其方法来自定义安全配置。
    • 到了 Spring Security 6.x,WebSecurityConfigurerAdapter 被标记为过时(deprecated),意味着它可能在未来的版本中被移除。这一变化是为了推动使用更现代的配置方法,即使用组件式配置。
  2. 使用组件式配置:

    • 在 Spring Security 6.x 中,推荐使用组件式配置。这意味着你可以创建一个配置类,该类不再需要继承 WebSecurityConfigurerAdapter
    • 你可以直接定义一个或多个 SecurityFilterChain bean 来配置安全规则。这种方式更加灵活,并且与 Spring Framework 的整体风格更加一致。

示例代码变化:

  • 在 Spring Security 5.x 使用 WebSecurityConfigurerAdapter 的配置框架:
复制代码
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            .anyRequest().authenticated()
            .and()
            .formLogin()
            .and()
            .httpBasic();
    }
}
  • 在 Spring Security 6.x 使用组件式配置变成了这个样子:
复制代码
@Configuration
public class SecurityConfiguration {
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            .anyRequest().authenticated()
            .and()
            .formLogin()
            .and()
            .httpBasic();
        return http.build();
    }
}

项目上具体的写法:

  • 在 Spring Security 5.4.5 使用 WebSecurityConfigurerAdapter 的配置:
复制代码
@Configuration
@Component
@EnableWebSecurity
@AllArgsConstructor
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Value("${auth.whitelist:/login}")
    private final String[] URL_WHITELIST;
    private final AuthenticationFailureHandler loginFailureHandler;

    private final UserLoginSuccessHandler loginSuccessHandler;
    private final UserLogoutSuccessHandler logoutSuccessHandler;
    private final UserDetailsService userDetailsService;
    private final AccessDeniedHandler authAccessDeniedHandler;
    private final AuthenticationEntryPoint loginAuthenticationEntryPoint;

    @Bean
    BCryptPasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public UserAuthenticationProvider myAuthenticationProvider() {
        UserAuthenticationProvider userAuthenticationProvider = new UserAuthenticationProvider(userDetailsService);
        return userAuthenticationProvider;
    }


    @Bean
    JwtAuthenticationFilter jwtAuthenticationFilter() throws Exception {
        JwtAuthenticationFilter jwtAuthenticationFilter2 = new JwtAuthenticationFilter(authenticationManager());
        return jwtAuthenticationFilter2;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http
                .cors()
                .and()
                .csrf().disable()
                .formLogin()
                .loginProcessingUrl("/login")
                .usernameParameter("userName")
                .passwordParameter("password")
                .successHandler(loginSuccessHandler)
                .failureHandler(loginFailureHandler)

                .and()
                .logout()
                .logoutSuccessHandler(logoutSuccessHandler)

                //禁用session
                .and()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)

                //配置拦截规则
                .and()
                .authorizeRequests()
                .antMatchers(URL_WHITELIST).permitAll()

                .anyRequest().authenticated()

                //异常处理器
                .and()
                .exceptionHandling()
                .authenticationEntryPoint(loginAuthenticationEntryPoint)
                .accessDeniedHandler(authAccessDeniedHandler)

                .and()
                .addFilterAfter(jwtAuthenticationFilter(), ExceptionTranslationFilter.class);

    }
}
  • 使用SpringSecurity6.1.5实现相同逻辑的配置变成了如下形式:
复制代码
@Configuration
@Component
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfiguration {

    @Value("${bxt.auth.whitelist:/login}")
    private final String[] URL_WHITELIST;

    private final CustomerUserDetailsService customUserDetailsService;
    private final CustomLoginSuccessHandler loginSuccessHandler;
    private final CustomLoginFailureHandler loginFailureHandler;
    private final AccessDeniedHandler authAccessDeniedHandler;
    private final AuthenticationEntryPoint loginAuthenticationEntryPoint;
    @Bean
    BCryptPasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public JwtAuthenticationFilter jwtAuthenticationFilter() {
        return new JwtAuthenticationFilter(); // 实例化您的 JWT 过滤器
    }


    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return new ProviderManager(new DaoAuthenticationProvider() {{
            setUserDetailsService(customUserDetailsService);
            setPasswordEncoder(bCryptPasswordEncoder());
        }});
    }


    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
                .csrf(csrf -> csrf.disable())
                .authorizeRequests(authz -> authz
                        .requestMatchers(URL_WHITELIST).permitAll() // 允许访问无需认证的路径
                        .anyRequest().authenticated()
                )
                .formLogin(form -> form.
                        loginProcessingUrl("/login")
                                .usernameParameter("username")
                                .passwordParameter("password")
                                .successHandler(loginSuccessHandler)
                                .failureHandler(loginFailureHandler)
                        )
                .logout(Customizer.withDefaults())
                .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                .userDetailsService(customUserDetailsService)
                .exceptionHandling(exceptionHandle -> exceptionHandle
                        .authenticationEntryPoint(loginAuthenticationEntryPoint)
                        .accessDeniedHandler(authAccessDeniedHandler)
                )
                .addFilterAfter(jwtAuthenticationFilter(), ExceptionTranslationFilter.class)
                .httpBasic(Customizer.withDefaults());

        return http.build();
    }
}

  总之,从 Spring Security 5.x 迁移到 6.x,主要的改变是从继承 WebSecurityConfigurerAdapter 转向定义 SecurityFilterChain bean 的方式来配置安全性。这种变化旨在使配置更加模块化和灵活,并更好地符合 Spring 框架的整体设计哲学。

相关推荐
SimonKing1 小时前
艹,维护AI写的代码,我心态崩了......
java·后端·程序员
用户298698530142 小时前
Java Word 文档样式进阶:段落与文本背景色设置完全指南
java·后端
小bo波17 小时前
从"任意文件复制"深挖Java I/O:字符流与字节流的本质抉择
java·nio·io流·后端开发·文件复制
nanxun8862 天前
记一次诡异的 Docker 容器"串包"故障排查
java
用户1563068103512 天前
Day01 | Java 基础(Java SE)
java
行者全栈架构师2 天前
Maven dependency:tree 的 8 个高级用法
java·后端
行者全栈架构师2 天前
IDEA 中 Maven 项目的 15 个红色报错快速解决方法
java·后端
令人头秃的代码0_02 天前
mac(m5)平台编译openjdk
java
唐青枫3 天前
Java JDBC 实战指南:从 Connection 到事务和连接池
java
一个做软件开发的牛马3 天前
MyBatis-Plus 从零实战:完整搭建可运行 Demo,BaseMapper 零 SQL、Wrapper 条件构造、分页插件与代码生成器详解
java·后端