SpringSecirityはバージョンごとに設定の書き方が大幅に変更されている。
ここでは、バージョンごとに記載方法が大きく変更となっているJavaConfig の記載方法についてまとめる。
バージョンによらない部分の実装については、下記の記事参照。
@EnableWebSecurityアノテーションを付ける
このクラスに記載の設定を適用したSpringSecurityによるフォーム認証を有効化するために、「@EnableWebSecurity
」アノテーションをクラスに付与する。
@EnableWebSecurity
は合成アノテーションであり、内部に「@Configuration
」アノテーションも持っているため、
このクラスはJavaConfigクラスではあるものの「@Configuration
」アノテーションの付与を省略することができる。
@EnableWebSecurity public class FormLoginConfiguration { }
「WebSecurityConfigurerAdapter」を実装する
org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
をextendsする。
@EnableWebSecurity public class FormLoginConfiguration extends WebSecurityConfigurerAdapter { }
パスワードのエンコーダクラスをDIコンテナに登録する
作成したJavaConfigクラス内でパスワードのエンコーダクラスをDIコンテナに登録するメソッドを実装する。
使用するエンコーダはプロジェクトの仕様により適切なものを選定する。
/** * パスワードのエンコーダーをDIコンテナに登録する。<br> */ @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); }
ユーザ情報を構築するサービスをDIコンテナに登録する
作成したJavaConfigクラス内でユーザ情報を構築するサービスをDIコンテナに登録するメソッドを実装する。
WebSecurityConfigurerAdapterクラスにUserDetailsServiceを設定するためのメソッドが存在しているため、
そのメソッドをオーバーライドする。
/** * ユーザー情報を構築するサービスをDIコンテナに登録する。<br> */ @Bean @Override public UserDetailsService userDetailsService() { return new LocalUserDetailService(); }
引数が「AuthenticationManagerBuilder」なconfigureメソッドをオーバーライドする
オーバーライドしたメソッドの中で、DIコンテナに登録したパスワードエンコーダーと、ユーザ情報を構築するサービスを設定する処理を追加する。
/** * {@inheritDoc} */ @Override public void configure(AuthenticationManagerBuilder auth) throws Exception { auth .userDetailsService(userDetailsService()) .passwordEncoder(passwordEncoder()); }
引数が「HttpSecurity」なconfigureメソッドをオーバーライドする
このメソッドの中では、以下の設定を実施する。 + 認証の対象とするURLの設定 + フォーム認証の設定 + ログアウトの設定
/** * {@inheritDoc} */ @Override protected void configure(HttpSecurity http) throws Exception { }
認証の対象とするURLの設定
フォーム認証の対象とするURL、対象外とするURLを設定する。
静的ファイルのパスやログイン画面のURLを認証対象外となるように設定している。
/** * {@inheritDoc} */ @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() // 認証対象外のURL指定 .mvcMatchers("/images/**", "/css/**", "/js/**", "/webjars/**", "/authorization/**").permitAll() // ログイン画面のURLも認証対象外とする .antMatchers("/login").permitAll() // 上記のURL以外は認証が必要 .anyRequest().authenticated(); }
フォーム認証の設定
フォーム認証で使用するログイン画面へ遷移するURL、フォーム認証成功後に遷移するURLを指定する。
また、認証成功時にユーザオブジェクトを構築するハンドラーを追加する。
/** * {@inheritDoc} */ @Override protected void configure(HttpSecurity http) throws Exception { http.formLogin() // フォーム認証のログイン画面のURL .loginPage("/login") // 認証成功時に遷移するURL .defaultSuccessUrl("/") // Form認証成功時にユーザオブジェクトを構築するハンドラーを追加する .successHandler(new LocalAuthenticationSuccessHandler()); }
ログアウトの設定
ログアウトURLやログアウト成功時の遷移先URLの設定を行う。
また、ログアウト時にCookieの値やセッションを無効化するよう設定を行う。
/** * {@inheritDoc} */ @Override protected void configure(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.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.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; 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 FormLoginConfiguration extends WebSecurityConfigurerAdapter { /** * パスワードのエンコーダーをDIコンテナに登録する。<br> */ @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } /** * ユーザー情報を構築するサービスをDIコンテナに登録する。<br> */ @Bean @Override public UserDetailsService userDetailsService() { return new LocalUserDetailService(); } /** * {@inheritDoc} */ @Override protected void configure(HttpSecurity http) throws Exception { // 認証処理の設定 http.authorizeRequests() // 認証対象外のURL指定 .mvcMatchers("/images/**", "/css/**", "/js/**", "/webjars/**", "/authorization/**").permitAll() // ログイン画面のURLも認証対象外とする .antMatchers("/login").permitAll() // 上記のURL以外は認証が必要 .anyRequest().authenticated(); // Form認証の設定 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(); } /** * {@inheritDoc} */ @Override public void configure(AuthenticationManagerBuilder auth) throws Exception { auth .userDetailsService(userDetailsService()) .passwordEncoder(passwordEncoder()); } }