SpringSecirityはバージョンごとに設定の書き方が大幅に変更されている。
ここでは、バージョンごとに記載方法が大きく変更となっているJavaConfig の記載方法についてまとめる。
バージョンによらない部分の実装については、下記の記事参照。
@EnableWebSecurityアノテーションを付ける
このクラスに記載の設定を適用したSpringSecurityによるフォーム認証を有効化するために、「@EnableWebSecurity
」アノテーションをクラスに付与する。
@EnableWebSecurity
は合成アノテーションであり、内部に「@Configuration
」アノテーションも持っているため、
このクラスはJavaConfigクラスではあるものの「@Configuration
」アノテーションの付与を省略することができる。
@EnableWebSecurity public class FormSecurityConfiguration { }
パスワードのエンコーダクラスをDIコンテナに登録する
作成したJavaConfigクラス内でパスワードのエンコーダクラスをDIコンテナに登録するメソッドを実装する。
使用するエンコーダはプロジェクトの仕様により適切なものを選定する。
/** * パスワードのエンコーダーをDIコンテナに登録する。<br> */ @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); }
認証の設定を行うメソッドを実装する。
Spring Security ver5.7.0以降では、「org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter」が非推奨となり、「SecurityFilterChain
」を使用した設定が推奨されている。
このメソッドでは、以下の設定を実施している。
- 認証マネージャーの構築
- 認証の対象とする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を認証対象外となるように設定している。
@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() // 認証対象外のURL指定(静的ファイル、エラーページ遷移のURL) .mvcMatchers("/images/**", "/css/**", "/js/**", "/webjars/**", "/authorization/**", "/filter-error").permitAll() // ログイン画面のURLも認証対象外とする .antMatchers("/login").permitAll() // 上記のURL以外は認証が必要 .anyRequest().authenticated(); }
フォーム認証の設定
フォーム認証で使用するログイン画面へ遷移するURL、フォーム認証成功後に遷移するURLを指定する。
また、認証成功時にユーザオブジェクトを構築するハンドラーを追加する。
@Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http.formLogin() // フォーム認証のログイン画面のURL .loginPage("/login") // 認証成功時に遷移するURL .defaultSuccessUrl("/") // Form認証成功時にユーザオブジェクトを構築するハンドラーを追加する .successHandler(new LocalAuthenticationSuccessHandler()); }
ログアウトの設定
ログアウトURLやログアウト成功時の遷移先URLの設定を行う。
また、ログアウト時にCookieの値やセッションを無効化するよう設定を行う。
@Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http.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 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() // 認証対象外のURL指定(静的ファイル、エラーページ遷移のURL) .mvcMatchers("/images/**", "/css/**", "/js/**", "/webjars/**", "/authorization/**", "/filter-error").permitAll() // ログイン画面のURLも認証対象外とする .antMatchers("/login").permitAll() // 上記のURL以外は認証が必要 .anyRequest().authenticated(); // フォーム認証の設定 http.formLogin() // フォーム認証のログイン画面のURL .loginPage("/login") // 認証成功時に遷移するURL .defaultSuccessUrl("/") // Form認証成功時にユーザオブジェクトを構築するハンドラーを追加する .successHandler(new LocalAuthenticationSuccessHandler()); // ログアウト処理の設定 http.logout() // ログアウトのURL .logoutRequestMatcher(new AntPathRequestMatcher("/logout")) // ログアウト成功時のURL(ログイン画面に遷移) .logoutSuccessUrl("/login") // Cookieの値を削除する .deleteCookies("JSESSIONID") // セッションを無効化する .invalidateHttpSession(true).permitAll(); return http.build(); } }