home wiki.fukuchiharuki.me
Menu

キーワード

  • Spring Boot
  • Spring Security
  • エラーメッセージ

現象

Spring Securityでログインページを作成するとき、エラーメッセージにシステムエラーが表示されてしまう。たとえば、JDBCアクセスできなかったという詳細なエラーメッセージが「ログインIDかパスワードが間違っています。」と表示したい箇所にモロ出しになる。

原因

ログインプロセス中に生じた例外をSpring Securityが拾ってしまうため。

対策

エラーページにリダイレクトする

ExceptionMappingAuthenticationFailureHandlerを作成して次の例外でエラーページにリダイレクトするように設定する。

  • org.springframework.security.authentication.InternalAuthenticationServiceException
public class SecurityConfigAuthenticationFailureHandler extends ExceptionMappingAuthenticationFailureHandler {

	public SecurityConfigAuthenticationFailureHandler() {
		this.setDefaultFailureUrl("/");
		this.setExceptionMappings(getFailureUrlMap());
	}
	
	private Map<String, String> getFailureUrlMap() {
		Map<String, String> map = new HashMap<>();
		map.put(InternalAuthenticationServiceException.class.getName(), "/error");
		return map;
	}

}

ログ出力する

エラーページにリダイレクトしても例外オブジェクトは届けられない。ExceptionMappingAuthenticationFailureHandlerは単純にリダイレクトをしているだけだから。なので、このハンドラ中でエラーログ出力してあげる必要がある。

	@Override
	public void onAuthenticationFailure(
			HttpServletRequest request,
			HttpServletResponse response, 
			AuthenticationException exception
	) throws IOException, ServletException {

		// TODO: ここで、exceptionを利用してエラーログ出力する

		super.onAuthenticationFailure(request, response, exception);
	}

備考

  • InternalAuthenticationServiceExceptionは名前どおり、内部的なエラーを包む。
  • InternalAuthenticationServiceExceptionに対するメッセージを定義するだけで足りたりする?(試してない)
    • それにしてもエラーログ出力はしたいから何か手を打つ必要はある
  • SimpleUrlAuthenticationFailureHandlerを継承するようにして、InternalAuthenticationServiceExceptionであればthrowする方がよいような気がしました
    • 例外のロギングをいろんなところに書きたくない
    • 例外はErrorControllerがもつ、がシンプルでいい

参考