본문 바로가기

Language/Spring Security

예외 처리 - ExceptionHandling()

  • 예외 처리는 필터 체인 내에서 발생하는 예외를 의미
    • 크게 인증예외(AuthenticationException)인가예외(AccessDeniedException)로 나뉨
  • 예외를 처리하는 필터로서 ExceptionTranslationFilter가 사용 되며 사용자의 인증 및 인가 상태에 따라 [로그인 재시도 / 401 / 403] 코드 등으로 응답 가능

예외 처리 유형

  • AuthenticationException(인증 예외)
    • SecurityContext 에서 인증 정보 삭제
      • 기존의 Authentication더 이상 유효하지 않다고 판단하고 Authentication을 초기화
    • AuthenticationEntryPoint 호출
      • AuthenticationException이 감지되면 필터는 authenticationEntryPoint를 실행하고 이를 통해 인증 실패를 공통적으로 처리할 수 있으며 일반적으로 인증을 시도할 수 있는 화면으로 이동
    • 인증 프로세스의 요청 정보를 저장하고 검색
      • RequestCache & SavedRequest­ → 인증 프로세스 동안 전달되는 요청을 세션 혹은 쿠키에 저장
      • 사용자가 인증을 완료한 후 요청을 검색하여 재 사용 가능
        → 기본 구현 = HttpSessionRequestCache
  • AccessDeniedException(인가 예외)
    • AccessDeniedHandler 호출
      • AccessDeniedException이 감지되면 필터는 사용자가 익명 사용자인지 여부를 판단
        • 익명 사용자인 경우 인증 예외 처리가 실행 → 인증 예외처리 = AuthenticationException
        • 익명 사용자가 아닌 경우 필터는 AccessDeniedHandler에게 위임

ExceptionHandling() API

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {

	http.exceptionHandling(exception -> exception
	        .authenticationEntryPoint((request, response, authException) -> {
	            System.out.println(authException.getMessage());
	        })
	        .accessDeniedHandler((request, response, accessDeniedException) -> {
	            System.out.println(accessDeniedException.getMessage());
	        })
	);

  return http.build();
}
  • authenticationEntryPoint() → 인증
    • 커스텀하게 사용할 EntryPoint 설정
  • accessDeniedHanlder() → 인가
    • 커스텀하게 사용할 AccessDeniedHandler 설정
  • AuthenticationEntryPoint 는 인증 프로세스마다 기본적으로 제공되는 클래스들이 설정
    • UsernamePasswordAuthenticationFIlter - LoginUrlAuthenticationEntryPoint
    • BasicAuthenticationFilter - BasicAuthenticationEntryPoint
    • 아무런 인증 프로세스가 설정 되지 않으면 기본적으로 Http403ForbiddenEntryPoint가 사용
    • 사용자 정의 AuthenticationEntryPoint 구현이 가장 우선적으로 수행되며 이 때는 기본 로그인 페이지 생성 무시
  • AccessDeniedHandler는 기본적으로 AccessDeniedHandlerImpl 클래스가 사용