szerhusenBC/jwt-spring-security-demo

How to ExceptionHandler of type ExpiredJwtException from JwtAuthenticationTokenFilter?

josevlad opened this issue ยท 5 comments

Hi, I want to give an answer to report that the token was expired, try to do this, but it does not work:
in:
JwtAuthenticationTokenFilter => doFilterInternal()

  ...
  ... 
  if (requestHeader != null && requestHeader.startsWith("Bearer ")) {
      authToken = requestHeader.substring(7);
      try {
        username = jwtTokenUtil.getUsernameFromToken(authToken);
      } catch (IllegalArgumentException e) {
        logger.error("an error occured during getting username from token", e);
      } catch (ExpiredJwtException e) {
        logger.warn("the token is expired and not valid anymore", e);
        throw new ServletException("token_expired");
      }
    }
  ...
  ...

in
RestResponseExceptionHandler => servletException()

@RestControllerAdvice
public class RestResponseExceptionHandler {
...
...

  @ExceptionHandler(value = { ServletException.class })
  public ResponseEntity servletException(ServletException e) {
    String message = e.getMessage();
    HttpStatus httpStatus = HttpStatus.INTERNAL_SERVER_ERROR;
    if (message.equals("token_expired")) {
      httpStatus = HttpStatus.UNAUTHORIZED;
      message = "the token is expired and not valid anymore";
    }
    RestErrorResponse restErrorResponse = new RestErrorResponse(httpStatus, message);
    return ResponseEntity.status(httpStatus).body(restErrorResponse);
  }

...
...

but the output is always

{
    "timestamp": 1510672145534,
    "status": 500,
    "error": "Internal Server Error",
    "exception": "javax.servlet.ServletException",
    "message": "token_expired",
    "path": "/api/bui/conceptos"
}

and I want it to be like that:

{
    "statusCode": 401,
    "status": "Unauthorized",
    "body": "the token is expired and not valid anymore"
}

It's because the filter comes before Servlet is invoked. ControllerAdvice only applies to the Controller classes.

I'm also trying to find the solution to same problem. Been reading some stackoverflow articles, this one seems promising: https://stackoverflow.com/questions/34595605/how-to-manage-exceptions-thrown-in-filters-in-spring @josevlad

@AshishHNP Thanks. It works.

@WuTaoyu How are you? I'm here with the same problem. Would you mind show me how you resolved the problem? I created a new Filter in spring (.addFilterBefore(jwtExpiredExceptionHandle, CorsFilter.class), but i can't catch and handle de execption ExpiredJwtException ...
Can you help-me?

I created handler filter that catch JwtException like below :

`public class ExceptionHandlerFilter extends OncePerRequestFilter {

	
	@Override
    public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        try {
            filterChain.doFilter(request, response);
        } catch (JwtException e) {

            
            FilterErrorResponse errorResponse = new FilterErrorResponse(e);

            response.setStatus(HttpStatus.BAD_REQUEST.value());
            response.getWriter().write(convertObjectToJson(errorResponse));
    }
}

    private String convertObjectToJson(Object object) throws JsonProcessingException {
        if (object == null) {
            return null;
        }
        ObjectMapper mapper = new ObjectMapper();
        return mapper.writeValueAsString(object);
    }

}`

then specified it on security config before Authentication token filter and it return error response excepted.

Closed, because I published a complete new version.