Search code examples
spring-security

Spring Security - Custom JWT error messages


I am building a microservice using Spring Cloud Gateway and OAuth2 Resource Server. The app aims at redirecting to other microservices after doing the security part. I am trying to setup a filter before AnonymousAuthenticationFilter and handle my custom exception from there but however the custom exception filter is never being invoked. Following the security config I have in the app:

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable().cors().disable()
      .httpBasic().disable()
      .formLogin().disable()
      .addFilterBefore(customExceptionHandler, AnonymousAuthenticationFilter.class)
      .authorizeRequests( auth -> auth.antMatchers(AUTH_WHITELIST).permitAll()
        .antMatchers("/**").authenticated())
      .oauth2ResourceServer(oauth2ResourceServer -> oauth2ResourceServer.jwt())
      .sessionManagement(sessionManagement -> sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
  }

In my customExceptionHandler, I have the following code:

public class CustomExceptionHandler extends OncePerRequestFilter {

  @Autowired
  @Qualifier("handlerExceptionResolver")
  private HandlerExceptionResolver resolver;

  @Override
  protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
    throws ServletException, IOException {

    try {
      filterChain.doFilter(request, response);
    } catch (Exception e) {
      log.error("Spring Security Filter Chain Exception:", e);
      resolver.resolveException(request, response, null, e);
    }
  }
}

Also following is my build.gradle:

// Spring Boot
implementation 'org.springframework.boot:spring-boot-starter'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'

// Spring Cloud
implementation 'org.springframework.cloud:spring-cloud-starter-gateway'

I also have an @ExceptionAdvice class that handles all the exceptions. However, if I pass in an expired JWT or any other error scenario to the service, I always get handled by the following error message in my WWW-Authenticate header:

Bearer error="invalid_token", error_description="Jwt expired at 2022-06-16T19:58:09Z", error_uri="https://tools.ietf.org/html/rfc6750#section-3.1"

How do I throw a custom POJO instead of this message?


Solution

  • This error is coming from BearerTokenAuthenticationEntryPoint, so to override the behavior you can just easily provide a custom entryPoint

    .oauth2ResourceServer(oauth2ResourceServer -> oauth2ResourceServer.jwt().and().authenticationEntryPoint(myCustomEntryPoint))