Spring

[Spring security] AuthenticationEntryPoint 에러 해결 방법(with jwt)

archiveloper 2024. 6. 28. 19:00

 문제 상황


 사용자만 이용 가능한 서비스를 이용하기 전 회원인지 검증하는 부분에서 503 에러가 발생했다. api 사용 절차는 다음과 같았다.

  1.  상품 등록 api를 사용 시, 정상 데이터로 상품을 등록
  2. 일부 정보를 누락시켜서 고의적으로 에러를 발생시킴
  3. 다시 정상 데이터로 실행

 결과

  • 기대 결과: 정상 동작
  • 발생 결과: UnavailableException이 발생

 

 

 원인


 AuthenticationEnrtyPoint클래스를 상속받은 클래스에서 예외 던지는 방식을 잘못 던지고 있었다. 사실 전달받은 객체를 바로 던지는 방법으로도 기능은 원하는 대로 동작했지만, 이왕이면 에러 결과를 깔끔하게 전달하고 싶었다.

 

 기존 방식의 문제점

  • 서버에서 새로운 예외를 발생시켜서 던지기 때문에 기존에 전달받은 예외를 처리하지 못해서 서버에서 에러가 발생함.
@Override
public void commence(HttpServletRequest request,
                     HttpServletResponse response,
                     AuthenticationException authException) throws IOException, ServletException {
    log.error("인증되지 않은 요청입니다.", authException);

    throw new UnavailableException("인증되지 않은 요청입니다.");

}

 

 수정

  • 직접 HttpServletRespone 객체를 작성해서 결과를 전송함.
@Override
public void commence(HttpServletRequest request,
                     HttpServletResponse response,
                     AuthenticationException authException) throws IOException, ServletException {
    log.error("인증되지 않은 요청입니다.", authException);

    // 응답 헤더 설정
    response.setContentType("application/json;charset=utf-8");
    response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); // 401 Unauthorized

    // 응답 바디 작성
    Map<String, Object> responseBody = new HashMap<>();
    responseBody.put("message", "인증되지 않은 요청입니다.");
    responseBody.put("status", HttpServletResponse.SC_UNAUTHORIZED);
    responseBody.put("occurrenceTime", LocalDateTime.now());

    // 응답 바디를 JSON 형식으로 변환하여 응답
    String responseJson = objectMapper.writeValueAsString(responseBody);
    response.getWriter().write(responseJson);
}

 

 

 수정 후 결과


 원하는 대로 정상 동작함.

수행 결과

 


 뭔가 ExceptionHandler로도 시도를 해봤지만 원하는 대로 결과가 나오지 않았다. 일단 AccessDeniedHandler도 이런 방식으로 수정하고 좀 더 알아봐야겠다.

300x250