Spring Boot/Security
AuthenticationEntryPoint & AccessDeniedHandler
최-코드
2024. 10. 6. 14:21
배경지식 :
- ExceptionHandlingConfigurer라는 클래스가 EntryPoint와 DeninedHandler 대한 구현체를 받아 defaultEntryPointMappings와, defulatDeniedHandlerMappings라는 Map객체에 저장한다.
- 기본적으로 FormLogin과 HttpBasic인증 방식에 대한 defulat한 예외 설정이 존재하며, 커스텀한 것이 존재하면 이것이 우선적으로 실행된다.
- SecurityFilterChain에는 ExceptionTranslationFilter가 존재하는데, 이는 Filter Chain 내부에서 발생하는 AccessDeniedException과 AuthenticationException의 처리를 담당한다.
- 만약 ExceptionTranslationFilter가 AuthenticationException을 감지했다면 authenticationEntryPoint를 실행한다. 이것을 통해서 AbstractSecurityInterceptor의 서브클래스에서 발생하는 인증 실패를 공동으로 처리할 수 있다.
- 만약 ExceptionTranslationFilter가 AccessDeniedException을 감지했다면 해당 사용자가 익명 사용자 인지의 여부를 판별하고 만약 익명 사용자일 경우 동일하게 authenticationEntryPoint을 실행한다. 만약 익명 사용자가 아닐 경우엔 AccessDeniedHandler을 위임한다.
- 즉, ExceptionTranslationFilter는 ExceptionHandlingConfigurer를 참고해서 감지한 것에 대한 예외를 처리한다.
AuthenticationException : 인증 과정에서 에러가 생겼을 경우 발생하는 예외
AccessDeniedException : 인가 과정에서 에러가 생겼을 경우 발생하는 예외(-> role값이 맞지 않을 때)
간단 예제
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
response.setStatus(HttpStatus.UNAUTHORIZED.value());
response.getWriter().write(authException.getMessage());
}
}
public class CustomAccessDeniedHandler implements AccessDeniedHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
response.setStatus(HttpStatus.FORBIDDEN.value());
response.getWriter().write(accessDeniedException.getMessage());
}
}