返回

升级到 Java 21 + Spring boot 3.2 + Spring Security 6.2

软件小窝
2024-01-09 00:35:198.67k 字预计阅读时长 17 分钟

最近花了一些时间升级了下后端的 java  和 spring boot 版本

gradle 的配置

plugins {
    id 'java'
    id 'org.springframework.boot' version '3.2.0'
    id 'io.spring.dependency-management' version '1.1.4'
}

java {
    sourceCompatibility = JavaVersion.VERSION_21
    targetCompatibility = JavaVersion.VERSION_21
}

Spring Security 6.2 主要看文档 https://docs.spring.io/spring-security/reference/servlet/getting-started.html

遇到的变化

1、所有配置都完成后,启动的时候会遇到一些 循环依赖 问题,这个到好解决。

2、Tomcat的包名有了变化,这是 Tomcat 10  的变化,项目中很多需要替换,有 IDEA,也算是轻松。

3、几个依赖需要升级一下,gradle 升级到 8.5(我目前用的是最高)

// Lombok 支持
    implementation 'org.projectlombok:lombok:1.18.30'
    annotationProcessor 'org.projectlombok:lombok:1.18.30'

// Spring boot Mybatis
    implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:3.0.3'

4、重点是 Spring Security 升级后很多都变了,很多方法都废弃了,写法也有一些变化,

以前的配置

**
 * @author FB by Linux
 * @device Windows 11
 * @date 2022/4/22
 * @remarks: [ SecurityConfig 配置类 ]
 */

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private CustomLoginSuccessHandler customLoginSuccessHandler;

    @Autowired
    private CustomLoginFailureHandler customLoginFailureHandler;

    @Autowired
    private CustomLogoutHandler customLogoutHandler;

    @Autowired
    private CustomLogoutSuccessHandler customLogoutSuccessHandler;

    @Autowired
    private CustomAccessDeniedHandler customAccessDeniedHandler;

    @Autowired
    private CustomAuthenticationEntryPoint customAuthenticationEntryPoint;

    @Autowired
    private AuthenticationFilter authenticationFilter;

    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors()
                .and()
                .csrf().disable()
                .authorizeRequests()
                .antMatchers().permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginProcessingUrl("/login")
                .usernameParameter("email")
                .passwordParameter("password")
                .successHandler(customLoginSuccessHandler)
                .failureHandler(customLoginFailureHandler).permitAll()
                .and()
                .logout()
                .logoutUrl("/logout")
                .addLogoutHandler(customLogoutHandler)
                .logoutSuccessHandler(customLogoutSuccessHandler)
                .deleteCookies("JSESSIONID").permitAll()
                .and()
                .exceptionHandling()
                .authenticationEntryPoint(customAuthenticationEntryPoint)
                .accessDeniedHandler(customAccessDeniedHandler)
                .and()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .addFilterAt(jsonLogin(), UsernamePasswordAuthenticationFilter.class)
                .addFilterBefore(authenticationFilter, LogoutFilter.class);
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
    }
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Bean
    JsonLogin jsonLogin() throws Exception {
        JsonLogin jsonLogin = new JsonLogin();
        jsonLogin.setAuthenticationManager(authenticationManagerBean());
        jsonLogin.setAuthenticationSuccessHandler(customLoginSuccessHandler);
        jsonLogin.setAuthenticationFailureHandler(customLoginFailureHandler);

        return jsonLogin;
    }

    /**
     * 密码加密方式
     * @return PasswordEncoder
     */
    @Bean
    PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

现在的配置

/**
 * @author FB by Linux
 * @device Windows 11
 * @date 2022/4/22
 * @remarks: [ SecurityConfig 配置类 ]
 */

@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class SecurityConfig {

    @Autowired
    private CustomLoginSuccessHandler customLoginSuccessHandler;

    @Autowired
    private CustomLoginFailureHandler customLoginFailureHandler;

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http,
                                           CustomLogoutHandler customLogoutHandler,
                                           CustomLogoutSuccessHandler customLogoutSuccessHandler,
                                           CustomAccessDeniedHandler customAccessDeniedHandler,
                                           CustomAuthenticationEntryPoint customAuthenticationEntryPoint,
                                           AuthenticationFilter authenticationFilter,
                                           UserDetailsService userDetailsService) throws Exception {
        http.csrf(AbstractHttpConfigurer::disable)
                .headers(headers -> headers.xssProtection(
                        xss -> xss.headerValue(XXssProtectionHeaderWriter.HeaderValue.ENABLED_MODE_BLOCK)
                ))
                .authorizeHttpRequests(authorizeRequests -> authorizeRequests
                        .anyRequest().authenticated())
                .formLogin(httpSecurityFormLoginConfigurer -> httpSecurityFormLoginConfigurer
                        .loginProcessingUrl("/login")
                        .usernameParameter("email")
                        .passwordParameter("password")
                        .successHandler(customLoginSuccessHandler)
                        .failureHandler(customLoginFailureHandler).permitAll())
                .logout(httpSecurityLogoutConfigurer -> httpSecurityLogoutConfigurer
                        .logoutUrl("/logout")
                        .addLogoutHandler(customLogoutHandler)
                        .logoutSuccessHandler(customLogoutSuccessHandler)
                        .deleteCookies("JSESSIONID").permitAll())
                .exceptionHandling(httpSecurityExceptionHandlingConfigurer -> httpSecurityExceptionHandlingConfigurer
                        .authenticationEntryPoint(customAuthenticationEntryPoint)
                        .accessDeniedHandler(customAccessDeniedHandler))
                .sessionManagement(httpSecuritySessionManagementConfigurer -> httpSecuritySessionManagementConfigurer
                        .sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                .addFilterAt(jsonLogin(userDetailsService), UsernamePasswordAuthenticationFilter.class)
                .addFilterBefore(authenticationFilter, LogoutFilter.class);
        return http.build();
    }


    @Bean
    MethodSecurityExpressionHandler methodSecurityExpressionHandler(CustomPermissionVerification customPermissionVerification) {
        DefaultMethodSecurityExpressionHandler defaultWebSecurityExpressionHandler = new DefaultMethodSecurityExpressionHandler ();
        defaultWebSecurityExpressionHandler.setPermissionEvaluator(customPermissionVerification);
        return defaultWebSecurityExpressionHandler;
    }

    @Bean
    AuthenticationManager authenticationManagerBean(UserDetailsService userDetailsService) {
        DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
        daoAuthenticationProvider.setUserDetailsService(userDetailsService);
        daoAuthenticationProvider.setPasswordEncoder(passwordEncoder());
        return new ProviderManager(daoAuthenticationProvider);
    }

    @Bean
    JsonLogin jsonLogin(UserDetailsService userDetailsService){
        JsonLogin jsonLogin = new JsonLogin();
        jsonLogin.setAuthenticationManager(authenticationManagerBean(userDetailsService));
        jsonLogin.setAuthenticationSuccessHandler(customLoginSuccessHandler);
        jsonLogin.setAuthenticationFailureHandler(customLoginFailureHandler);

        return jsonLogin;
    }

    /**
     * 密码加密方式
     * @return PasswordEncoder
     */
    @Bean
    PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

 

 

本篇文章用到的软件

  • 21Java
    Java
    面向对象编程语言
    下载
  • 8.5Gradle
    Gradle
    更快地构建、自动化和交付更好的软件
    下载