環境
- SpringBoot 1.5.3
やりたかったこと
画面から入力されたIDとパスワードを用いたログイン処理です。
パスワードはハッシュ化してデータベースのユーザーテーブルに保存しているので、入力されたパスワードとデータベースに保存されたハッシュ値を比較する必要がありました。
ハマったこと
ユーザーテーブルに格納されているはずのアカウントでログインしようとして認証NGとなる。
ハッシュ化する処理を取り除いて平文でログインを行うと認証OKとなる。
原因
こんなソースを書いていました。
WebSecurityConfig.java(修正前)
@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
UserDetailsServiceImpl userDetailsService;
/** ~省略~ */
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
}
}
ググってSpringのログイン認証に関する記事を調べると、ほとんどのサイトでconfigureGlobal
メソッド内でパスワードエンコーディング方式を設定する的なことが書かれていました。
参考にしてるサイトに書いてある通りにしてるのになんでや!?と思っていたら、
どうやらconfigure
メソッドでの設定で上書きされていたようです。
- configureGlobalメソッドで設定
- configureメソッドで設定
という処理順だったようです。
あまり細かく理解できていないので、Springのライフサイクルをちゃんと知るべきだと思いました。
WebSecurityConfig.java(修正後)
@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
UserDetailsServiceImpl userDetailsService;
/** ~省略~ */
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
/** ~configureメソッドを削除~ */
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
}
}