Spring Security, JWT 사용 환경에서 예외처리 하는 방법을 알아보겠습니다!
Spring에서는 API 예외 처리 문제를 해결하기 위해 @ExceptionHandler라는 편리한 예외 처리 기능을 제공합니다.
실무에서 API 예외 처리는 이 기능을 대부분 사용합니다.
예를 들자면,
다음과 같이 추상 클래스 ResponseEntityExceptionHandler를 상속받고 각각의 메서드 레벨에 @ExceptionHandler 메서드를 붙여 사용합니다. Exception예외든 제가 직접 정의한 NotFoundUserException이든 하나의 클래스에서 예외를 관리할 수 있고 이를 클라이언트에게 JSON형식으로 내려줄 수 있습니다.
위의 그림과 같이 예외를 클라이언트에게 전달해줄 수 있게 됩니다!
여기서 NotFoundUserException과 같은 자식 클래스에서 최상위 부모 클래스는 Exception.class이지만, 둘 중 더 자세한 것이 우선권을 가지므로 자식예외처리가 호출되게 됩니다.
그렇다면,, 클래스 레벨에서 붙여준 @RestControllerAdvice는 무엇일까요?
@RestControllerAdvice를 들어가보면 다음과 같은 내용을 확인할 수 있습니다.
@ControllerAdvice와 @ResponseBody가 같이 사용되고 있는 모습을 확인할 수 있습니다.
@ControllerAdvice는 컨트롤러를 보조하는 클래스인데, Controller에서 발생하는 예외처리를 잡아서 처리해줍니다.
Controller에서 Service를 호출한 경우, Service에서 Exception이 발생해도 Controller에서 문제가 발생했음을 감지하고 Handler가 작동하게 됩니다.
@ResponseBody는 자바 객체를 HTTP 요청의 body 내용으로 매핑하는 역할을 합니다!
정리하자면 @RestControllerAdvice와 @ControllerAdvice의 차이는
@RestController와 @Controller의 차이인, View를 리턴하는지 JSON/XML같은 HTTP 응답을 리턴하는지에 대한 차이입니다.
---------------------------그렇다면.. 이런 @RestControllerAdvice, @ExceptionHandler를 사용해 Security , JWT환경에서 예외처리를 진행할 수 있을까요?
그럴 수 없습니다!
Spring Security는 Spring이전에 Filter 처리가 되므로 DispatcherServlet까지 가지 않기 때문입니다.
따라서, @RestControllerAdvice, @ExceptionHandler를 사용해 메서드를 정의한다고 한들, 예외가 그대로 로그에 남는걸 확인할 수 있습니다
이를 해결하기 위해선 Spring Security에서 제공하는
AuthenticationEntryPoint
인터페이스 구현 클래스에서 예외동작을 처리해줘야 합니다.
순서대로 알아보겠습니다.
예를 들어, 사용자가 AccessToken이 유효시간 30분을 초과한 토큰을 보낸다고 가정하겠습니다.
먼저, OncePerRequestFilter 추상 클래스를 상속받은 JwtFilter에서 doFilterInternal을 재정의하고 이 과정에서 빨간 동그라미가 쳐져있는 tokenProvider객체의 validateToken메서드가 작동합니다.
validateToken 메서드는 다음과 같습니다.
만료된 토큰이므로 ExpiredJwtException 예외가 발생하고 예외를 발생시킵니다.
이 메서드를 호출한 상위 메서드 doFilterInternal는 try catch문이므로, request.setAttribute메서드가 실행됩니다.
이후 AuthenticationEntryPoint를 구현한 클래스의 commence 메서드에서 이후로직을 처리하고 데이터를 반환합니다.
추가적으로, 시큐리티 설정 클래스에서
다음과 같이 설정해줘야 합니다.
그렇다면, 제가 정의한 코드를 HTTP 응답 메세지의 바디로 클라이언트에게 전달되는 모습을 확인할 수 있습니다!
단순히 반복적으로 @ExceptionHandler, @RestControllerAdvice를 사용하였던 제게, Filter에서 발생한 예외처리 문제는 예외처리 문제들이 어떤 동작들로 반복하는지 살펴볼 수 있게 해준 좋은 기회였습니다!
이 예외처리를 활용한다면 토큰 재발급 등과 같은 기능에도 활용할 수 있습니다.
만료된 토큰이라면, 클라이언트는 HTTP 메세지 바디의 데이터를 이용해 예외를 인지하고, 백엔드에서 설계한 토큰 재발급 API를 이용해 클라이언트가 다시 요청을 보내서 토큰을 재발급 받을 수 있습니다!
'Dev > Spring' 카테고리의 다른 글
[Spring Batch] 공공데이터 OPEN API 활용시, Spring Batch와 Quartz사용해 반복적으로 DB에 저장 자동화하기 - (2) (0) | 2022.04.29 |
---|---|
[Spring Batch] 공공데이터 OPEN API 활용시, Spring Batch와 Quartz사용해 반복적으로 DB에 저장 자동화하기 - (1) (0) | 2022.04.07 |