Springboot2.5から3.1に移行した時の簡易メモ

前作ったアプリがSpringBoot2.5で作っていて別アプリをSpringBoot3.1で作成しました。
Tomcat9に入れてで起動すると上手く起動しなくて何でだと調べてみるとどうやらtomcat10じゃないとSpringBoot3.1は起動しない模様。
逆にTomcat10でSpringBoot2.5を起動してもまぁ駄目でアップグレードするしか道はありませんでした。
たいして使用してもいないものなのでかなり迷いましたがやりました。その時のメモです。

環境

移行前

  • Java 11
  • SpringBoot 2.5.3
  • Tomcat 9.0.37

移行後

  • Java 17
  • SpringBoot 3.1.1
  • Tomcat 10.1.11

修正内容

import文

javax.servlet.http.HttpServletRequest から jakarta.servlet.http.HttpServletRequestに変更。
Controllerで以下のようにしていたのでimport文を修正

//import javax.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequest;
@GetMapping
public String login(HttpServletRequest req) {
}

Entity

アノテーションもimport文を修正

//import javax.persistence.Column;
//import javax.persistence.Entity;
//import javax.persistence.Id;
//import javax.persistence.Table;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;

PostConstruct

@PostConstructもimport文を修正

//import javax.annotation.PostConstruct;
import jakarta.annotation.PostConstruct;

ログイン認証(WebSecurityConfigurerAdapter)

Spring Securityのバージョンが変わり、WebSecurityConfigurerAdapterを継承してどうのこうのは出来なくなり@Beanで定義するように変更になりました。
以下は修正前のソースです。多少改変してますが、ほぼまんまです。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

import sinoalice.tools.cololog.service.UserDetailsAuthenticationProvider;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsAuthenticationProvider service;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/new", "/status/**", "/notification/**").permitAll()    // 認証不要なパスを指定
                .anyRequest().authenticated()            // antMatchersで指定したパス以外認証する
                .and()
                .cors().and().csrf().disable()
            .formLogin()
                .loginPage("/login")
                .permitAll()
                .and()
            .logout()
                .permitAll();
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        // Security Filter Chain から除外するパス等を設定
        web.ignoring().antMatchers("/**/css/**", "/**/js/**", "/**/img/**");
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(service);
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public AuthenticationProvider getAuthenticationProvider() {
      return service;
    }

以下はSpringBoot3.1での修正版です。

package sinoalice.tools;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.servlet.PathRequest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;

import sinoalice.tools.cololog.service.UserDetailsAuthenticationProvider;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig {

    @Autowired
    private UserDetailsAuthenticationProvider service;

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests(authz -> authz
                .requestMatchers("/new", "/status/*", "/notification/*")    // 認証不要なパスを指定
                .permitAll()
                .requestMatchers(PathRequest.toStaticResources().atCommonLocations()) // css,jsなどのリソースも認証不要
                .permitAll()
                .requestMatchers("/login")
                .permitAll()
                .anyRequest().authenticated())  // antMatchersで指定したパス以外認証する
        .formLogin(login -> login
                .loginProcessingUrl("/login")  // ログイン情報の送信先
                .loginPage("/login")           // ログイン画面
                .defaultSuccessUrl("/")        // ログイン成功時の遷移先
                .failureUrl("/login?error")    // ログイン失敗時の遷移先
                .permitAll())                  // 未ログインでもアクセス可能
        .logout(logout -> logout
                .logoutSuccessUrl("/login")    // ログアウト成功時の遷移先
                .permitAll())
        .cors(cors -> cors.disable())
        .csrf((csrf) -> csrf.disable());

        return http.build();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public UserDetailsAuthenticationProvider userDetailsService() {
        return new UserDetailsAuthenticationProvider();
    }

    @Bean
    public AuthenticationManager authManager(HttpSecurity http) throws Exception {
        AuthenticationManagerBuilder authenticationManagerBuilder =
            http.getSharedObject(AuthenticationManagerBuilder.class);
        authenticationManagerBuilder.authenticationProvider(service);
        return authenticationManagerBuilder.build();
    }
}

以上です。

コメント

タイトルとURLをコピーしました