본문 바로가기

Language/Spring Security

예외 필터 - ExceptionTranslationFilter()

예외 처리 흐름도

  1. 인증 받지 못한 사용자가 /user URL 요청
    → /user URL은 인증이 필요
  2. 가장 마지막의 인가 필터(AuthorizationFilter)가 받음
  3. AuthorizationManager를 통해 사용자의 접근 여부를 판단하고 최종 반환 받은 값으로 해당 유저는 접근할 수 없다고 판단 → 인가 예외(AccessDeniedException) 발생
  4. ExceptionTranslationFilter가 받음 → 해당 필터는 인증 예외, 인가 예외 두 가지를 처리할 수 있지만 지금 받은 것은 인가 예외
  5. AccessDeniedException에서 익명 사용자 또는 RememberMe(기억하기 인증) 사용자라면 인증 예외(AuthenticationException)으로 전달 → 아이디, 패스워드를 입력한 사용자일 경우 그 아래로 내려가서 AccessDeniedHandler 처리
  6. AuthenticationException가 실행될 경우
    • SecurityContext 초기화
    • HttpSessionRequestCache가 사용자가 요청했던 URL(/user)를 Session에 저장
    • AuthenticationEntryPoint를 통해 리다이렉트

추가 내용 정리

  • AuthorizationFilter에서 발생한 예외를 처리하는 필터
  • 순서가 ExceptionTranslationFilter → AuthorizationFilter 이여서 반대로 생각이 들 수 있지만 ExceptionTranslationFilter의 doFilter를 보면 다음 필터에서 발생한 예외를 ExceptionTranslationFilter에서 catch()문으로 처리

private void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
    try {
        chain.doFilter(request, response);
    } catch (IOException var7) {
        throw var7;
    } catch (Exception var8) {
        Throwable[] causeChain = this.throwableAnalyzer.determineCauseChain(var8);
        ...
    }
}
  • MVC에서 잡아내지 못한 예외는 ExceptionTranslationFilter까지 전달이 되어 ServletException을 처리할 수는 있으나, 원래는 AuthenticationException과 AccessDeniedException을 처리하기 위한 필터