SpringSecirityはバージョンごとに設定の書き方が大幅に変更されている。
ここでは、バージョンごとに記載方法が大きく変更となっているJavaConfig の記載方法についてまとめる。
バージョンによらない部分の実装については、下記の記事参照。
@EnableWebSecurityアノテーションを付ける
このクラスに記載の設定を適用したSpringSecurityによるフォーム認証を有効化するために、「@EnableWebSecurity
」アノテーションをクラスに付与する。
Spring Security ver6.0.0以降では、「@EnableWebSecurity
」から@Configuration
アノテーションが削除されているので、自分で@Configuration
アノテーションを付与する必要がある。
@EnableWebSecurity @Configuration public class FormSecurityConfiguration { }
パスワードのエンコーダクラスをDIコンテナに登録する
作成したJavaConfigクラス内でパスワードのエンコーダクラスをDIコンテナに登録するメソッドを実装する。
使用するエンコーダはプロジェクトの仕様により適切なものを選定する。
/** * パスワードのエンコーダーをDIコンテナに登録する。<br> */ @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); }
認証の設定を行うメソッドを実装する。
このメソッドでは、以下の設定を実施している。
- 認証マネージャーの構築
- 認証の対象とするURLの設定
- フォーム認証の設定
- ログアウトの設定
/** * {@link SecurityFilterChain}をDIコンテナに登録する。<br> * * @param http * {@link HttpSecurity} * @return {@link SecurityFilterChain} * @throws Exception * セキュリティ設定時に例外が発生した場合 */ @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { }
認証マネージャーの構築
Spring Security ver5.7.0より前では、引数が「AuthenticationManagerBuilder」なconfigureメソッドで設定していた内容である。
パスワードエンコーダーとユーザ情報を構築するサービスを設定した認証マネージャーを構築する。
@Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { AuthenticationManagerBuilder builder = http.getSharedObject(AuthenticationManagerBuilder.class); builder.userDetailsService(new LocalUserDetailService(passwordEncoder())); AuthenticationManager manager = builder.build(); }
認証の対象とするURLの設定
フォーム認証の対象とするURL、対象外とするURLを設定する。
静的ファイルのパスやログイン画面のURLを認証対象外となるように設定している。
SpringSecurity6.0以降では、引数なしの「authorizeHttpRequests()
」メソッドが非推奨となったので
引数に「org.springframework.security.config.Customizer
」を取るメソッドで実装する。
また、URLを指定するのに使用していた「mvcMatchers
」メソッドや「antMatchers
」メソッドも使用できなくなったため、全て「requestMatchers
」メソッドに置き換える。
@Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { AuthenticationManagerBuilder builder = http.getSharedObject(AuthenticationManagerBuilder.class); builder.userDetailsService(new LocalUserDetailService(passwordEncoder())); AuthenticationManager manager = builder.build(); http.authenticationManager(manager) .authorizeHttpRequests((auth) -> auth // 認証対象外のURL指定(静的ファイル、エラーページ遷移のURL) .requestMatchers("/images/**", "/css/**", "/js/**", "/webjars/**", "/authorization/**", "/filter-error").permitAll() // ログイン画面のURLも認証対象外とする .requestMatchers("/login").permitAll() // 上記以外は認証が必要 .anyRequest().authenticated()); }
フォーム認証の設定
フォーム認証で使用するログイン画面へ遷移するURL、フォーム認証成功後に遷移するURLを指定する。
また、認証成功時にユーザオブジェクトを構築するハンドラーを追加する。
SpringSecurity6.0以降では、引数なしの「formLogin()
」メソッドが非推奨となったので
引数に「org.springframework.security.config.Customizer
」を取るメソッドで実装する。
@Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http.formLogin((formLogin) -> formLogin // フォーム認証のログイン画面のURL .loginPage("/login") // 認証成功時に遷移するURL .defaultSuccessUrl("/") // Form認証成功時にユーザオブジェクトを構築するハンドラーを追加する .successHandler(new LocalAuthenticationSuccessHandler())); }
ログアウトの設定
ログアウトURLやログアウト成功時の遷移先URLの設定を行う。
また、ログアウト時にCookieの値やセッションを無効化するよう設定を行う。
SpringSecurity6.0以降では、引数なしの「logout()
」メソッドが非推奨となったので
引数に「org.springframework.security.config.Customizer
」を取るメソッドで実装する。
@Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http.logout((logout) -> logout // ログアウトのURL .logoutRequestMatcher(new AntPathRequestMatcher("/logout")) // ログアウト成功時のURL(ログイン画面に遷移) .logoutSuccessUrl("/login") // Cookieの値を削除する .deleteCookies("JSESSIONID") // セッションを無効化する .invalidateHttpSession(true).permitAll()); }
最終的に作成されるJavaConfigクラス
import org.springframework.context.annotation.Bean; 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 org.springframework.security.web.util.matcher.AntPathRequestMatcher; import jp.co.sample.web.authentication.handler.LocalAuthenticationSuccessHandler; import jp.co.sample.web.authentication.user.LocalUserDetailService; /** * フォーム認証する際に使用するSpring Securityの定義クラス。<br> */ @EnableWebSecurity @Configuration public class FormSecurityConfiguration { /** * パスワードのエンコーダーをDIコンテナに登録する。<br> * * @return {@link PasswordEncoder} */ @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } /** * {@link SecurityFilterChain}をDIコンテナに登録する。<br> * * @param http * {@link HttpSecurity} * @return {@link SecurityFilterChain} * @throws Exception * セキュリティ設定時に例外が発生した場合 */ @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { AuthenticationManagerBuilder builder = http.getSharedObject(AuthenticationManagerBuilder.class); builder.userDetailsService(new LocalUserDetailService(passwordEncoder())); AuthenticationManager manager = builder.build(); http.authenticationManager(manager) .authorizeHttpRequests((auth) -> auth // 認証対象外のURL指定(静的ファイル、エラーページ遷移のURL) .requestMatchers("/images/**", "/css/**", "/js/**", "/webjars/**", "/authorization/**", "/filter-error").permitAll() // ログイン画面のURLも認証対象外とする .requestMatchers("/login").permitAll() // 上記以外は認証が必要 .anyRequest().authenticated()); // フォーム認証の設定 http.formLogin((formLogin) -> formLogin // フォーム認証のログイン画面のURL .loginPage("/login") // 認証成功時に遷移するURL .defaultSuccessUrl("/") // Form認証成功時にユーザオブジェクトを構築するハンドラーを追加する .successHandler(new LocalAuthenticationSuccessHandler())); // ログアウト処理の設定 http.logout((logout) -> logout // ログアウトのURL .logoutRequestMatcher(new AntPathRequestMatcher("/logout")) // ログアウト成功時のURL(ログイン画面に遷移) .logoutSuccessUrl("/login") // Cookieの値を削除する .deleteCookies("JSESSIONID") // セッションを無効化する .invalidateHttpSession(true).permitAll()); return http.build(); } }