I am trying to implement Token Authentication on our REST Api, and currently I am referring to this article. On the article it discusses that on creating the token JWT was used, but my current problem is that every time an invalid token was being passed on to my application an exception is being created which is the JwtException.class and I want to catch that exception using my global exception handler class. I tried also to wrapped the JwtException on my application's exception class but to no avail the exception was not caught.
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(value={JwtException.class})
public ResponseEntity<?> handleTokenException(JwtException e){
return new ResponseEntity<Object>(HttpStatus.UNAUTHORIZED);
}
@ExceptionHandler(value={InvalidAuthTokenException.class})
public ResponseEntity<?> handleTokenException(InvalidAuthTokenException e){
return new ResponseEntity<Object>(HttpStatus.UNAUTHORIZED);
}
}
Your GlobalExceptionHandler isn't truly global, it will only catch exceptions that occur in your controller (hence ControllerAdvice), the exceptions you are running into are occurring in servlet filters, which is where Spring Security does pretty much all of its work. This little chart may help explain what I am talking about:
PreFilters <- Executed before entering your controller, decryption of JWT is happening here
Controller <- ControllerAdvice will catch all exceptions thrown here
PostFilters <- Executed after exiting your controller
Luckily Spring Security already has mechanisms in place for handling exceptions that occur when doing things like decrypting a JWT in a filter. You will want to update your SpringSecurityConfig like so. Note its important that the ExceptionTranslationFilter is after your StatelessAuthenticationFilter (or whatever you named the filter where the JWT decryption is occurring).
@Configuration
@EnableWebSecurity
@Order(2)
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
ExceptionTranslationFilter = new ExceptionTranslationFilter(new AuthenticationExceptionHandler());
http.addFilterAfter(new StatelessAuthenticationFilter(tokenAuthenticationService),
ExceptionTranslationFilter.class);
}
}
public class AuthenticationExceptionHandler implements AuthenticationEntryPoint {
public void commence(HttpServletRequest request, HttpServletResponse, AuthenticationException e) throws IOException, ServletException {
//Logic on how to handle JWT exception goes here
}
}
public class StatelessAuthenticationFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
try {
//DECRYPT YOUR JWT
} catch (Exception e) {
throw new AuthenticationException();//If you get an exception wrap it in a AuthenticationException (or a class that extends it)
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With