spring controlleradvice is not catching aexpirerJwtException

69 views Asked by At

@ExceptionHandler(DataIntegrityViolationException.class) public ResponseEntity handleRegisterUsernameDuplication(DataIntegrityViolationException e){ ErrorObject errorObject = new ErrorObject( HttpStatus.CONFLICT.value(), e.getMessage(), new Date() ); return new ResponseEntity<>(errorObject, HttpStatus.CONFLICT); }

    @ExceptionHandler(ExpiredJwtException.class)
    public ResponseEntity<ErrorObject> handleJwtExpiration(ExpiredJwtException e){
        ErrorObject errorObject = new ErrorObject(
                HttpStatus.UNAUTHORIZED.value(),
                e.getMessage(),
                new Date()
        );
        return new ResponseEntity<>(errorObject, HttpStatus.UNAUTHORIZED);
    }
}

But when the token expires, the 403 error(forbidden) is used instead of my defined 401 (Unauthorized), from server:

2023-12-06T17:01:13.459+01:00 ERROR 11489 --- [nio-8080-exec-5] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception

io.jsonwebtoken.ExpiredJwtException: JWT expired at 2023-12-06T16:01:12Z. Current time: 2023-12-06T16:01:13Z, a difference of 1457 milliseconds.  Allowed clock skew: 0 milliseconds.
    at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:427) ~[jjwt-impl-0.11.5.jar:0.11.5]

...

from client:

ERROR
Request failed with status code 403
AxiosError@http://localhost:3000/static/js/bundle.js:66657:18
settle@http://localhost:3000/static/js/bundle.js:67310:12
onloadend@http://localhost:3000/static/js/bundle.js:65992:6
1

There are 1 answers

4
Jeremy Twiggs On

I suspect its because Spring Security is handling the scenario first.

If you have a SecurityFilterChain bean, you should be able to access HttpSecurity and do something like this:

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    return http
        .oauth2ResourceServer()
        .authenticationEntryPoint(yourAuthenticationEntryPointGoesHere)
        .and()
        .build();
}

implement AuthenticationEntryPoint and customise the commence method.