比较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 框架的整体设计哲学。

相关推荐
吃喝不愁霸王餐APP开发者5 分钟前
基于Spring Cloud Gateway实现对外卖API请求的统一鉴权与流量染色
java·开发语言
a努力。7 分钟前
美团Java面试被问:Redis集群模式的工作原理
java·redis·后端·面试
一雨方知深秋16 分钟前
面向对象编程
java·封装·this·构造器·static关键字·成员变量·javabean实体类
资生算法程序员_畅想家_剑魔20 分钟前
Java常见技术分享-11-责任链模式
java·spring boot·责任链模式
计算机程序设计小李同学1 小时前
动漫之家系统设计与实现
java·spring boot·后端·web安全
程序员阿鹏1 小时前
责任链模式
java·spring·servlet·tomcat·maven·责任链模式
@淡 定1 小时前
Java内存模型(JMM)详解
java·开发语言
czhc11400756632 小时前
C# 1221
java·servlet·c#
黄俊懿2 小时前
【深入理解SpringCloud微服务】Seata(AT模式)源码解析——全局事务的回滚
java·后端·spring·spring cloud·微服务·架构·架构师
派大鑫wink2 小时前
【Day12】String 类详解:不可变性、常用方法与字符串拼接优化
java·开发语言