- Published on
AuthenticationEntryPoint 와 AccessDeniedHandler
- Authors
- Name
- ywj9811
AuthenticationEntryPoint
AuthenticationEntryPoint란 Authorization헤더를 보내지 않거나 혹은 인증에 실패하여 401 응답코드가 발생하게 되었을 때 처리하는 인터페이스로, 내부의 commence()
가 실행되게 된다.
@Component
@RequiredArgsConstructor
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
private final ObjectMapper objectMapper;
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
SecurityException.WrongTokenException e = new SecurityException.WrongTokenException(
JwtConstants.JwtExcpetionMessage.WRONG_TOKEN.getMessage(),
JwtConstants.JwtExcpetionCode.WRONG_TOKEN.getCode(),
HttpStatus.FORBIDDEN);
response.setStatus(e.getHttpStatus().value());
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
response.setCharacterEncoding("UTF-8");
String errorResponseJson = objectMapper.writeValueAsString(new ErrorResponse(e.getErrorCode(), e.getMessage()));
response.getOutputStream().write(errorResponseJson.getBytes("UTF-8"));
}
}
위의 코드는 AuthenticationEntryPoint를 구현한 커스텀 클래스로, 해당 코드를 살펴보면 어떻게 처리할 것인지에 대해서 정의하고 있는데, 커스텀 하여 만든 예외를 생성하고, response
에 적절한 정보를 담아서 응답하고 있다.
(WrongTokenException, ErrorResponse는 커스텀하여 정의한 클래스)
AccessDeniedHandler
그렇다면 AccessDeniedHandler 는 무엇일까
AccessDeniedHandler 란 인증은 되었지만 권한이 부족한 경우 즉, 엑세스 권한을 체크했을 때 엑세스 할 수 없는 요청을 했을 경우 동작하는 인터페이스로, 내부의 handler()
가 실행된다.
@Slf4j
@Component
@RequiredArgsConstructor
public class CustomAccessDeniedHandler implements AccessDeniedHandler {
private final ObjectMapper objectMapper;
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
log.error("권한이 없는 요청입니다.");
AuthorityException e = new AuthorityException(
JwtExcpetionMessage.NON_AUTHORITY.getMessage(),
JwtExcpetionCode.NON_AUTHORITY.getCode(),
HttpStatus.FORBIDDEN);
response.setStatus(e.getHttpStatus().value());
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
response.setCharacterEncoding("UTF-8");
String errorResponseJson = objectMapper.writeValueAsString(new ErrorResponse(e.getErrorCode(), e.getMessage()));
response.getOutputStream().write(errorResponseJson.getBytes("UTF-8"));
}
}
위의 코드는 AccessDeniedHandler 를 구현한 커스텀 클래스로, 코드를 살펴보면 이전에 살펴본 commence()
와 마찬가지로 동작하고 있다.
이렇게 경우에 따라서 실행될 수 있도록 클래스를 만들어주고,
@Override
protected void configure(HttpSecurity http) throws Exception {
http
...
.exceptionHandling()
.authenticationEntryPoint(customAuthenticationEntryPoint)
.accessDeniedHandler(customAccessDeniedHandler)
...
}
이렇게 설정에 추가하면 권한 검사를 진행할 경우 작동하여 처리되게 될 것이다.