SecurityJwtFilter 에러 반환 방법

0

Kotlin

목록 보기
18/32

목표

  • 기존 액세스 토큰 만료일 경우에도 filterChain.doFilter(request, response) 로 필터링 거쳐서 403에러를 내보냈는데, 에러상태코드를 분리하기 위해서 액세스 토큰이 만료됐을 경우 400에러를 내보내려고 한다.
  • SecurityJwtFilter 클래스에서 (OncePerRequestFilter를 구현) jwt의 검증을 하게 되는데,
    이 때
    1) 인증된 jwt이지만 만료됐을 경우
    response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "AccessToken Expired") 를 보내주고 -> 400 에러.
    2) 인증도 됐고, jwt 만료까지의 시간도 남았다면 SecurityContextHolder.getContext().authenticationsecurityJwtProvider.getAuthentication(token)로 권한을 넣어서 controller의 API를 호출할 수 있게 해준다. -> 정상. 200


기존에 액세스토큰이 만료됐을 경우, 아닐 경우를 나눠서 if / else 구문으로 처리했고
1) 액세스 토큰이 만료되지 않았을 경우에 if문에서는 권한을 넣어주고,
2) 만료됐을 경우 sendError를 보내도록 했더니 아래와 같은 에러가 발생했다.

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Unable to handle the Spring Security Exception because the response is already committed.] with root cause
-> 이미 response를 내보냈기 때문에 Spring Security 에서 Exception이 발생했다는 것. 발생한 위치는 doFilter 였다.

doFilter의 위치가 잘못 됐음을 인지하고 위치를 바꿔줬음.

  • 인증이 잘 됐을 경우에는 doFilter를 통해서 filter 거쳐서 응답이 되도록 하고,
    인증이 안됐을 경우(액세스 토큰 만료)에는 filter를 거치지 않고 내가 정한 Error를 response하도록 변경
    -> 아래와 같이 잘 작동했다!

액세스 토큰이 아예 없을 경우에는 ?

  • swagger에 만료된 accessToken도 넣지않고 아예 뺀 채로 API 요청을 보냈다.
  • 위의 코드로 하면, 아무일도 일어나지 않는다.
    왜냐하면 request, response에 대해서 accessToken이 인증됐을 경우에만 filter.doFilter(request, response)response.sendError 를 해주기 때문에 액세스 토큰이 아예 인증(isVerify)도 되지 않았을 경우에는 아무 처리를 하지않는것.
    -> 액세스 토큰이 없으면 인증이 되지 않은 사용자라서 알아서 AuthenticationEntryPoint로 들어가지 않을까 했는데,
    jwtFilter에서 doFilter로 처리를 안해주면 AuthenticationEntryPoint에도 안들어가나 보다...

    따라서 doFilter를 두군데에다가 다 설정해줬음.
    1) 인증도 됐고, 만료도 안된 경우
    2) 인증조차 아예 안된 경우

    아래 사진과 같이 token도 아무것도 안들어오고, jwtFilter를 거쳐서 AuthenticationEntryPoint를 거치는 것을 확인할 수 있었다.

  • 원래 AccessDenied로 떠야하는데 아직 AuthenticationEntryPoint에 해당 API path를 설정하지 않아서 Not Found로 뜨는것.

    • 스프링 시큐리티 예외 처리과정이 아래와 같기 때문에 doFilter를 거친 후 Exception이 발생했을 때 startAuthentication()이 진행되는 과정에서 AuthenticationEntryPoint에 자격증명 요청을 위임하기 때문에 doFilter 를 거쳐야 AuthenticationEntryPoint에 접근하는것인가 보다!
  • 그리고, AuthenticationEntryPoint에서 발생하는 기본 에러는 403이라고 한다.!

profile
백엔드를 공부하고 있습니다.

0개의 댓글