キーワード†
- Spring Boot
- HandlerInterceptor
- アスペクト
- 共通処理
したいこと†
ログインユーザーのパスワードが有効期限切れのとき、パスワードリセットページにリダイレクトする。
ただし、UserDetails#isCredentialsNotExpired()は使わない。これを使うとログインした状態でパスワードリセットにリダイレクトさせることができない。ログインさせないためのフラグなので。
どうやって†
HandlerInterceptorでアスペクト処理する。
@Component
public class PasswordResetHandlerInterceptor extends HandlerInterceptorAdapter {
@Autowired
private LoggedInUserLoadService loggedInUserLoadService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Authentication authentication = (Authentication) request.getUserPrincipal();
boolean isPasswordExpired =
Optional.ofNullable(authentication)
.map(a -> a.getPrincipal())
.filter(p -> p instanceof UserDetails)
.map(p -> (LoggedInUser) p)
.map(u -> loggedInUserService.loadUserByUsername(u.getUsername())) // DBから取得しないといつまでもパスワード期限切れ
.map(u -> u.isPasswordExpired()) // isCredentialsNotExpired()は無条件にtrue
.orElse(false);
if (isPasswordExpired) // リダイレクト処理
return ! isPasswordExpired;
}
}
これを登録する。
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
@Autowired
PasswordResetHandlerInterceptor passwordResetInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(passwordResetInterceptor);
}
}
ノート†
次に手こずった。
- HttpServletRequestからログインユーザーを引っこ抜く
- HandlerInterceptorを登録する
- UserDetailsがどうも更新できない
- ので毎リクエストでDBからユーザーを取得するようにした
- 何かいい方法ないの??
- パスワードリセットしたらログアウトさせるっていうのがつくりとしてはシンプルなのだけど
- ので毎リクエストでDBからユーザーを取得するようにした