Spring Security from 5 to 7 migration, error 404 login submit

13 hours ago 1
ARTICLE AD BOX

I'm upgrading from Java 17 to 25, Spring Framework 5.3.39 to 7.0.3. Whenever I try to submit credentials via login page, I get error 404. Am I missing something to make this work?

WebSecurityConfig.java (Spring 5):

@EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { /** * クラス名です。トレースに使用します。 */ private String sClassName_ = null; /** * ORACLE用のハンドラの作成です。 */ private RdbHandler handler_ = null; /** * ユーザーのデフォルト権限です。 */ private List<GrantedAuthority> authorities_ = null; /** * ログインページです。 */ private String sLoginPage_ = null; /** * ログアウトの遷移先URLです。 */ private String sLogoutUrl_ = null; /** * ログイン成功時の遷移先URLです。 */ private String sLoginSuccessUrl_ = null; /** * ログインしていないユーザー用のページです。 */ private String[] aAnonymousPage_ = null; /** * ログイン必要なページです。 */ private String[] aAuthenticatedPage_ = null; public WebSecurityConfig() { sClassName_ = getClass().getName(); handler_ = new RdbHandler(RdbHandler.MODE_WEB); authorities_ = new ArrayList<GrantedAuthority>(); authorities_.add(new SimpleGrantedAuthority("LINIC3")); sLoginPage_ = Linic3Property.getWebSecurity(Linic3Property.LOGINPAGE); sLogoutUrl_ = Linic3Property.getWebSecurity(Linic3Property.LOGOUTURL); sLoginSuccessUrl_ = Linic3Property.getWebSecurity(Linic3Property.LOGINSUCCESSURL); // ----------------------------------------- // ログインしていないユーザー用のページ // ----------------------------------------- String sAnonymousPage = Linic3Property.getWebSecurity(Linic3Property.ANONYMOUSPAGE); List<String> aAnonymousPage = splitToken(sAnonymousPage); aAnonymousPage_ = aAnonymousPage.toArray(String[]::new); // ----------------------------------------- // ログイン必要なページ // ----------------------------------------- String sAuthenticatedPage = Linic3Property.getWebSecurity(Linic3Property.AUTHENTICATEDPAGE); List<String> aAuthenticatedPage = splitToken(sAuthenticatedPage); aAuthenticatedPage_ = aAuthenticatedPage.toArray(String[]::new); } @Autowired public void configure(AuthenticationManagerBuilder auth) throws Exception { String sTraceMark = sClassName_ + ".configure():"; Trace.debug(sTraceMark + "Start!"); auth.userDetailsService(username -> { UserMasterBean bean = new UserMasterBean(); try { handler_.connect(); bean.setUSERID(username); // --------------------------------- // ユーザーマスタを取得します // --------------------------------- handler_.select(SQLProperty.getSelectSql("LPF300C", "LPF300C_SEL03"), bean); if (handler_.next()) { handler_.fetch(bean); } else { handler_.closeStatement(); throw new UsernameNotFoundException(username); } handler_.closeStatement(); if (bean.getUSERPASSWORD() == null) { throw new UsernameNotFoundException(username); } // 当月ログイン回数カウントアップ handler_.update(SQLProperty.getUpdateSql("LPF300C", "LPF300C_UPD03"), bean); handler_.commit(); return new User(username, passwordEncoder().encode(bean.getUSERPASSWORD()), authorities_); } catch (Exception e) { Trace.printStackTrace(e); } finally { handler_.disconnect(); Trace.debug(sTraceMark + "End!"); } throw new UsernameNotFoundException(username); }); } @Override protected void configure(final HttpSecurity http) throws Exception { http.httpBasic().disable().csrf().disable().cors().and() .authorizeRequests() .antMatchers(aAnonymousPage_).anonymous() .antMatchers(aAuthenticatedPage_).authenticated() .antMatchers("**").permitAll() .anyRequest().authenticated() .and() .formLogin() .loginPage(sLoginPage_) .loginProcessingUrl(sLoginPage_) .successHandler(authenticationSuccessHandler(sLoginSuccessUrl_)) .failureHandler(authenticationFailureHandler(sLoginPage_)) .and() .logout() .logoutUrl(sLogoutUrl_) .logoutSuccessHandler(logoutSuccessHandler(sLoginPage_)) .deleteCookies("JSESSIONID"); } @Bean public AuthenticationSuccessHandler authenticationSuccessHandler(String sForwardTarget) { return new jp.co.nisz.linic3.config.websecurity.AuthenticationSuccessHandler(sForwardTarget); } @Bean public AuthenticationFailureHandler authenticationFailureHandler(String sForwardTarget) { return new jp.co.nisz.linic3.config.websecurity.AuthenticationFailureHandler(sForwardTarget); } @Bean public LogoutSuccessHandler logoutSuccessHandler(String sForwardTarget) { return new jp.co.nisz.linic3.config.websecurity.LogoutSuccessHandler(sForwardTarget); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } /** * カンマ区切りの文字列をカンマで分割し、Listへ詰めて返します。 * * @param カンマ区切りの文字列 * @return カンマで分割された文字列を持つList */ private List<String> splitToken(String sTarget) { List<String> aRetVal = new ArrayList<String>(); // 文字列がnull or 空白でない場合 if (NullChecker.check(sTarget) == false) { StringTokenizer tokens = new StringTokenizer(sTarget, ", ", false); while (tokens.hasMoreTokens()) { aRetVal.add(tokens.nextToken()); } } return aRetVal; } }

WebSecurityConfig.java (Spring 7):

@Configuration @EnableWebSecurity public class WebSecurityConfig {

/** * クラス名です。トレースに使用します。 */ private String sClassName_ = null; /** * ORACLE用のハンドラの作成です。 */ private RdbHandler handler_ = null; /** * ユーザーのデフォルト権限です。 */ private List<GrantedAuthority> authorities_ = null; /** * ログインページです。 */ private String sLoginPage_ = null; /** * ログアウトの遷移先URLです。 */ private String sLogoutUrl_ = null; /** * ログイン成功時の遷移先URLです。 */ private String sLoginSuccessUrl_ = null; /** * ログインしていないユーザー用のページです。 */ private String[] aAnonymousPage_ = null; /** * ログイン必要なページです。 */ private String[] aAuthenticatedPage_ = null; public WebSecurityConfig() { sClassName_ = getClass().getName(); handler_ = new RdbHandler(RdbHandler.MODE_WEB); authorities_ = new ArrayList<GrantedAuthority>(); authorities_.add(new SimpleGrantedAuthority("LINIC3")); sLoginPage_ = Linic3Property.getWebSecurity(Linic3Property.LOGINPAGE); sLogoutUrl_ = Linic3Property.getWebSecurity(Linic3Property.LOGOUTURL); sLoginSuccessUrl_ = Linic3Property.getWebSecurity(Linic3Property.LOGINSUCCESSURL); // ----------------------------------------- // ログインしていないユーザー用のページ // ----------------------------------------- String sAnonymousPage = Linic3Property.getWebSecurity(Linic3Property.ANONYMOUSPAGE); List<String> aAnonymousPage = splitToken(sAnonymousPage); aAnonymousPage_ = aAnonymousPage.toArray(String[]::new); // ----------------------------------------- // ログイン必要なページ // ----------------------------------------- String sAuthenticatedPage = Linic3Property.getWebSecurity(Linic3Property.AUTHENTICATEDPAGE); List<String> aAuthenticatedPage = splitToken(sAuthenticatedPage); aAuthenticatedPage_ = aAuthenticatedPage.toArray(String[]::new); } @Bean public UserDetailsService userDetailsService(PasswordEncoder passwordEncoder) { return username -> { String sTraceMark = sClassName_ + ".userDetailsService():"; Trace.debug(sTraceMark + "Start!"); UserMasterBean bean = new UserMasterBean(); try { handler_.connect(); bean.setUSERID(username); // --------------------------------- // ユーザーマスタを取得します // --------------------------------- handler_.select(SQLProperty.getSelectSql("LPF300C", "LPF300C_SEL03"), bean); if (handler_.next()) { handler_.fetch(bean); } else { handler_.closeStatement(); throw new UsernameNotFoundException(username); } handler_.closeStatement(); if (bean.getUSERPASSWORD() == null) { throw new UsernameNotFoundException(username); } // 当月ログイン回数カウントアップ handler_.update(SQLProperty.getUpdateSql("LPF300C", "LPF300C_UPD03"), bean); handler_.commit(); return new User(username, passwordEncoder.encode(bean.getUSERPASSWORD()), authorities_); } catch (Exception e) { Trace.printStackTrace(e); } finally { handler_.disconnect(); Trace.debug(sTraceMark + "End!"); } throw new UsernameNotFoundException(username); }; } @Bean protected SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http.httpBasic(httpBasic -> httpBasic.disable()) .csrf(csrf -> csrf.disable()) .cors(cors -> cors.disable()) .authorizeHttpRequests(auth -> auth .requestMatchers(aAnonymousPage_).anonymous() .requestMatchers(aAuthenticatedPage_).authenticated() .requestMatchers("/**").permitAll() .anyRequest().authenticated()) .formLogin(form -> form .loginPage(sLoginPage_) .loginProcessingUrl(sLoginPage_) .successHandler(authenticationSuccessHandler(sLoginSuccessUrl_)) .failureHandler(authenticationFailureHandler(sLoginPage_))) .logout(logout -> logout .logoutUrl(sLogoutUrl_) .logoutSuccessHandler(logoutSuccessHandler(sLoginPage_)) .deleteCookies("JSESSIONID")); return http.build(); } @Bean public AuthenticationManager authenticationManager(HttpSecurity http) throws Exception { AuthenticationManagerBuilder authenticationManagerBuilder = http.getSharedObject(AuthenticationManagerBuilder.class); return authenticationManagerBuilder.build(); } @Bean public AuthenticationSuccessHandler authenticationSuccessHandler(String sForwardTarget) { return new jp.co.nisz.linic3.config.websecurity.AuthenticationSuccessHandler(sForwardTarget); } @Bean public AuthenticationFailureHandler authenticationFailureHandler(String sForwardTarget) { return new jp.co.nisz.linic3.config.websecurity.AuthenticationFailureHandler(sForwardTarget); } @Bean public LogoutSuccessHandler logoutSuccessHandler(String sForwardTarget) { return new jp.co.nisz.linic3.config.websecurity.LogoutSuccessHandler(sForwardTarget); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } /** * カンマ区切りの文字列をカンマで分割し、Listへ詰めて返します。 * * @param カンマ区切りの文字列 * @return カンマで分割された文字列を持つList */ private List<String> splitToken(String sTarget) { List<String> aRetVal = new ArrayList<String>(); // 文字列がnull or 空白でない場合 if (NullChecker.check(sTarget) == false) { StringTokenizer tokens = new StringTokenizer(sTarget, ", ", false); while (tokens.hasMoreTokens()) { aRetVal.add(tokens.nextToken()); } } return aRetVal; } }

login.html:

<form method="POST" th:action="@{/login}"> <center class="login"> <table cellspacing="5" cellpadding="5"> <tr> <td nowrap width="70">ユーザーID</td> <td nowrap width="160"> <input type="text" name="username" maxlength="10" size="25" tabindex="1"> </td> </tr> <tr> <td nowrap width="70">パスワード</td> <td nowrap width="160"> <input type="password" name="password" maxlength="20" size="25" tabindex="2"> </td> </tr> <tr> <td nowrap colspan="2" align="right"> <input type="submit" name="doLogin" class="button01" value="ログイン" tabindex="3" /> </td> </tr> </table> </center> </form>
Read Entire Article