Search code examples
javaspring-bootspring-securityjwtspring-security-oauth2

Spring Boot - Spring Security - InvalidBearerTokenException Error Handling


Similar to this question but it got no answers: Spring Security: Handle InvalidBearerTokenException in @ExceptionHandler

I have similar code and I'm trying to catch org.springframework.security.oauth2.server.resource.InvalidBearerTokenException when a user has supplied invalid/expired/bad JWT format.

    @Component
    public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
    
        @Autowired
        @Qualifier("handlerExceptionResolver")
        private HandlerExceptionResolver resolver;
    
        @Override
        public void commence(HttpServletRequest request, HttpServletResponse response,
                             AuthenticationException e) throws IOException, ServletException {
    
            resolver.resolveException(request, response, null, e);
        }
    }

    public class SecurityConfig extends WebSecurityConfigurerAdapter
    {
        @Autowired
        private CustomAuthenticationEntryPoint authenticationEntryPoint;
        @Autowired
        private CustomAccessDeniedHandler accessDeniedHandler;
    
        @Override
        protected void configure(HttpSecurity http) throws Exception
        {
            // other config here
            http.authorizeRequests()
                .anyRequest()
                .authenticated()
                .and()
                .oauth2ResourceServer().jwt();
    
            http.exceptionHandling()
                    .authenticationEntryPoint(authenticationEntryPoint)
                    .accessDeniedHandler(accessDeniedHandler);
        }
    }

I've also implemented the @ExceptionHandler of AuthenticationException for custom response.


        @ExceptionHandler({AuthenticationException.class})
        protected ResponseEntity<Object> handleAuthException(AuthenticationException ex, WebRequest req)
        {
            CustomResponse response = ...
            return new ResponseEntity<>(response, ...);
        }

InvalidBearerTokenException is a subclass of AuthenticationException. Any idea why this AuthenticationEntryPoint code is not catching it? I've also tried adding logging inside the commence method but it's not being called when InvalidBearerTokenException is thrown, but other AuthenticationException does.


Solution

  • You have to specify this AuthenticationEntryPoint inside the OAuth2ResourceServerConfigurer, like so:

            @Override
            protected void configure(HttpSecurity http) throws Exception
            {
                // other config here
                http.authorizeRequests()
                    .anyRequest()
                    .authenticated()
                    .and()
                    .oauth2ResourceServer().jwt().and()
                        .authenticationEntryPoint(authenticationEntryPoint)
                        .accessDeniedHandler(accessDeniedHandler);
            }
    

    When you set it, the Configurer will change the AuthenticationEntryPoint that is used inside the BearerTokenAuthenticationFilter, see here.