menu
書いてる野郎
orebike@gmail.com
認証の全体的な設定をするクラスを作る
このように実装する。
@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override public void configure(WebSecurity web) throws Exception { // 認証しないページの設定。この例では画像やCSS等の静的なファイルのURLを指定している web.ignoring().antMatchers("/img/**", "/css/**"); } @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/login", "/hoge/piyo", "hoge/fuga").permitAll() // login 画面に続き認証不要の画面をズラズラ書く .anyRequest().authenticated(); // ↑以外は全て要認証 http .formLogin() .loginProcessingUrl("/doLogin") // 認証用の情報(id と password)をどこへ送信するのか .loginPage("/login") // ログインフォームのURL .failureHandler(new MyAuthenticationFailureHandler()) // 認証失敗時に呼ぶハンドラ指定 .defaultSuccessUrl("/top") // 認証成功時の遷移先 .usernameParameter("login_id") // ID のパラメータ名 .passwordParameter("login_password"); // パスワードのパラメータ名 http.logout() .logoutRequestMatcher(new AntPathRequestMatcher("/doLogout")) // ログアウトするためのURL .logoutSuccessUrl("/login"); // ログアウト後にどこに遷移するか。この例はログイン画面。 // サンプルをわかりやすくするために自動挿入される CSRF のパラメータはキャンセルしておく http.csrf().disable(); } // 認証情報をどこから取ってくるか設定 @Configuration protected static class AuthenticationConfiguration extends GlobalAuthenticationConfigurerAdapter { // 認証情報取得の専用 Service を DI @Autowired UserDetailsService userDetailsService; @Override public void init(AuthenticationManagerBuilder auth) throws Exception { // 認証情報取得の専用 Service をセット // パスワードのハッシュアルゴリズムを指定する。 // 今回はサンプルを簡単にするために何があっても成功するようにする。 auth.userDetailsService(userDetailsService).passwordEncoder(new PasswordEncoder() { // こいつが true になると認証成功と判定される。 // rawPassword には画面からのモノがもろ入ってくる // encodedPassword には DB等に入っているハッシュ化されたパスワードがそのまま入る。 @Override public boolean matches(CharSequence rawPassword, String encodedPassword) { return true; } // 一応実装はするが、挙動を見てもなんのためにあるのかよくわからない // matches の前に呼び出されるのではあるが、その結果が matches で使われるわけでもなく // そもそも rawPassword に入力した値も入ってこない @Override public String encode(CharSequence rawPassword) { return null; } }); // Spring 的にはこれが推奨なので本番ではこのような定番のもうある実装を使う // auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder()); } } }
メソッドのチェーンを使って設定を書くことができるのだが、なんでもかんでもメチャクチャにできるわけでなく、 ある程度設定できるパラメータの順番が決まっているようなので、順番には注意したほうがよい。
ここで DI している UserDetailsService はこのように実装する → Spring Boot/認証/Spring Security/認証情報用取得用Service
↑で指定した認証失敗時のエラーハンドリング用クラスも実装する。
public class MyAuthenticationFailureHandler implements AuthenticationFailureHandler { @Override public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException { // ログイン画面にリダイレクトする response.sendRedirect(request.getContextPath() + "/login"); } }
この AuthenticationException に失敗の理由が詰まって送られてくるので、こいつを見て、response の内容を操作したりする。こいつは失敗時の話なので成功時のことは考えなくてヨイ。