javaspring-securityjwtspring-resource-server

Why isn't my CustomAuthenticationEntryPoint commence method getting called for invalid or expired JWT tokens in Java?


Why doesn't this commence method get called for when jwt token is invalid or expired? It gets called for when the token is empty. Weird thing is that while debugging I found out that the BearerTokenAuthenticationEntryPoint.commence() method is being called when token is invalid or expired. And this class is part of standard java library and is final so cannot be extended. But it implements the same interface that I implemment - AuthenticationEntryPoint, still my commence method doesn't get called. It only gets called when token is empty.

public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
  public CustomAuthenticationEntryPoint() {
  }

  @Override
  public void commence(HttpServletRequest httpServletRequest, HttpServletResponse response, AuthenticationException authenticationException) throws IOException {
    response.setContentType(MediaType.APPLICATION_JSON_VALUE);
    response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
    HttpStatus status = HttpStatus.UNAUTHORIZED;

    final Map<String, Object> body = new HashMap<>();
    body.put("status", status.name());
    body.put("statusCode", status.value());
    body.put("message", "You need to login first in order to perform this action");

    final ObjectMapper mapper = new ObjectMapper();
    mapper.writeValue(response.getOutputStream(), body);
  }
}

I'm using it like this:

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    http
            .authorizeHttpRequests((authorize) -> authorize
                .requestMatchers("/api/v1/auth/**").permitAll() 
                .requestMatchers("/api/v1/admin/**").hasAuthority(Authority.ADMIN.name())
                .anyRequest().authenticated()
            )
        .csrf().disable()
        .cors().disable()
        .httpBasic().disable()
        .oauth2ResourceServer((oauth2) ->
            oauth2.jwt((jwt) -> jwt.jwtAuthenticationConverter(jwtToUserConverter))
        )
        .sessionManagement((session) -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
        .exceptionHandling((exceptions) -> exceptions
            .authenticationEntryPoint(new CustomAuthenticationEntryPoint())
            .accessDeniedHandler(new CustomAccessDeniedHandler())
        );
    return http.build();
}

I tried implementing AuthenticationEntryPoint and expected that my commence() method would be called when the token is invalid or expired. But my commence() method isn't called, instead BearerTokenAuthenticationEntryPoint.commence() method is being called.

Here's my JwtToUserConverter:

@Component
public class JwtToUserConverter implements Converter<Jwt, UsernamePasswordAuthenticationToken> {
    @Override
    public UsernamePasswordAuthenticationToken convert(Jwt jwt) {
        // extract user information from the JWT
        String username = jwt.getSubject();
        List<LinkedTreeMap> authoritiesList = jwt.getClaim("authorities");

        // create a collection of SimpleGrantedAuthority objects
        Collection<SimpleGrantedAuthority> grantedAuthorities = authoritiesList.stream()
            .map(authority -> new SimpleGrantedAuthority((String) authority.get("role")))
            .collect(Collectors.toList());

        // create the UsernamePasswordAuthenticationToken
        return new UsernamePasswordAuthenticationToken(username, null, grantedAuthorities);
    }

}

Here's the full debug log for when I pass an invalid token:

"http-nio-4983-exec-2@10996" daemon prio=5 tid=0x1b nid=NA runnable
  java.lang.Thread.State: RUNNABLE
      at org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationEntryPoint.commence(BearerTokenAuthenticationEntryPoint.java:63)
      at org.springframework.security.oauth2.server.resource.web.authentication.BearerTokenAuthenticationFilter.lambda$new$0(BearerTokenAuthenticationFilter.java:77)
      at org.springframework.security.oauth2.server.resource.web.authentication.BearerTokenAuthenticationFilter$$Lambda$1321/0x00000008014cfaf8.commence(Unknown Source:-1)
      at org.springframework.security.web.authentication.AuthenticationEntryPointFailureHandler.onAuthenticationFailure(AuthenticationEntryPointFailureHandler.java:55)
      at org.springframework.security.oauth2.server.resource.web.authentication.BearerTokenAuthenticationFilter.doFilterInternal(BearerTokenAuthenticationFilter.java:150)
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
      at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:107)
      at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:93)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
      at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90)
      at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75)
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
      at org.springframework.security.web.context.SecurityContextHolderFilter.doFilter(SecurityContextHolderFilter.java:82)
      at org.springframework.security.web.context.SecurityContextHolderFilter.doFilter(SecurityContextHolderFilter.java:69)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
      at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:62)
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
      at org.springframework.security.web.session.DisableEncodeUrlFilter.doFilterInternal(DisableEncodeUrlFilter.java:42)
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
      at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:233)
      at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:191)
      at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:352)
      at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:268)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158)
      at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158)
      at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158)
      at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158)
      at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:177)
      at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
      at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
      at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:119)
      at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
      at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
      at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)
      at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:400)
      at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
      at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:859)
      at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1734)
      at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
      at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
      at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
      at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
      at java.lang.Thread.run(Thread.java:833)

"http-nio-4983-exec-1@10995" daemon prio=5 tid=0x1a nid=NA waiting
  java.lang.Thread.State: WAITING
      at jdk.internal.misc.Unsafe.park(Unsafe.java:-1)
      at java.util.concurrent.locks.LockSupport.park(LockSupport.java:341)
      at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(AbstractQueuedSynchronizer.java:506)
      at java.util.concurrent.ForkJoinPool.unmanagedBlock(ForkJoinPool.java:3463)
      at java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3434)
      at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1623)
      at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:435)
      at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:117)
      at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33)
      at org.apache.tomcat.util.threads.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1114)
      at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1176)
      at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
      at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
      at java.lang.Thread.run(Thread.java:833)

"http-nio-4983-exec-3@10997" daemon prio=5 tid=0x1c nid=NA waiting
  java.lang.Thread.State: WAITING
      at jdk.internal.misc.Unsafe.park(Unsafe.java:-1)
      at java.util.concurrent.locks.LockSupport.park(LockSupport.java:341)
      at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(AbstractQueuedSynchronizer.java:506)
      at java.util.concurrent.ForkJoinPool.unmanagedBlock(ForkJoinPool.java:3463)
      at java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3434)
      at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1623)
      at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:435)
      at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:117)
      at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33)
      at org.apache.tomcat.util.threads.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1114)
      at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1176)
      at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
      at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
      at java.lang.Thread.run(Thread.java:833)

"http-nio-4983-exec-4@10998" daemon prio=5 tid=0x1d nid=NA waiting
  java.lang.Thread.State: WAITING
      at jdk.internal.misc.Unsafe.park(Unsafe.java:-1)
      at java.util.concurrent.locks.LockSupport.park(LockSupport.java:341)
      at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(AbstractQueuedSynchronizer.java:506)
      at java.util.concurrent.ForkJoinPool.unmanagedBlock(ForkJoinPool.java:3463)
      at java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3434)
      at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1623)
      at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:435)
      at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:117)
      at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33)
      at org.apache.tomcat.util.threads.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1114)
      at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1176)
      at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
      at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
      at java.lang.Thread.run(Thread.java:833)

"http-nio-4983-exec-5@10999" daemon prio=5 tid=0x1e nid=NA waiting
  java.lang.Thread.State: WAITING
      at jdk.internal.misc.Unsafe.park(Unsafe.java:-1)
      at java.util.concurrent.locks.LockSupport.park(LockSupport.java:341)
      at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(AbstractQueuedSynchronizer.java:506)
      at java.util.concurrent.ForkJoinPool.unmanagedBlock(ForkJoinPool.java:3463)
      at java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3434)
      at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1623)
      at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:435)
      at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:117)
      at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33)
      at org.apache.tomcat.util.threads.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1114)
      at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1176)
      at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
      at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
      at java.lang.Thread.run(Thread.java:833)

"http-nio-4983-exec-6@11000" daemon prio=5 tid=0x1f nid=NA waiting
  java.lang.Thread.State: WAITING
      at jdk.internal.misc.Unsafe.park(Unsafe.java:-1)
      at java.util.concurrent.locks.LockSupport.park(LockSupport.java:341)
      at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(AbstractQueuedSynchronizer.java:506)
      at java.util.concurrent.ForkJoinPool.unmanagedBlock(ForkJoinPool.java:3463)
      at java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3434)
      at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1623)
      at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:435)
      at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:117)
      at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33)
      at org.apache.tomcat.util.threads.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1114)
      at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1176)
      at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
      at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
      at java.lang.Thread.run(Thread.java:833)

"http-nio-4983-exec-7@11001" daemon prio=5 tid=0x20 nid=NA waiting
  java.lang.Thread.State: WAITING
      at jdk.internal.misc.Unsafe.park(Unsafe.java:-1)
      at java.util.concurrent.locks.LockSupport.park(LockSupport.java:341)
      at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(AbstractQueuedSynchronizer.java:506)
      at java.util.concurrent.ForkJoinPool.unmanagedBlock(ForkJoinPool.java:3463)
      at java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3434)
      at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1623)
      at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:435)
      at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:117)
      at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33)
      at org.apache.tomcat.util.threads.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1114)
      at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1176)
      at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
      at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
      at java.lang.Thread.run(Thread.java:833)

"http-nio-4983-exec-8@11002" daemon prio=5 tid=0x21 nid=NA waiting
  java.lang.Thread.State: WAITING
      at jdk.internal.misc.Unsafe.park(Unsafe.java:-1)
      at java.util.concurrent.locks.LockSupport.park(LockSupport.java:341)
      at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(AbstractQueuedSynchronizer.java:506)
      at java.util.concurrent.ForkJoinPool.unmanagedBlock(ForkJoinPool.java:3463)
      at java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3434)
      at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1623)
      at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:435)
      at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:117)
      at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33)
      at org.apache.tomcat.util.threads.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1114)
      at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1176)
      at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
      at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
      at java.lang.Thread.run(Thread.java:833)

"http-nio-4983-exec-9@11003" daemon prio=5 tid=0x22 nid=NA waiting
  java.lang.Thread.State: WAITING
      at jdk.internal.misc.Unsafe.park(Unsafe.java:-1)
      at java.util.concurrent.locks.LockSupport.park(LockSupport.java:341)
      at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(AbstractQueuedSynchronizer.java:506)
      at java.util.concurrent.ForkJoinPool.unmanagedBlock(ForkJoinPool.java:3463)
      at java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3434)
      at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1623)
      at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:435)
      at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:117)
      at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33)
      at org.apache.tomcat.util.threads.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1114)
      at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1176)
      at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
      at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
      at java.lang.Thread.run(Thread.java:833)

"http-nio-4983-exec-10@11004" daemon prio=5 tid=0x23 nid=NA waiting
  java.lang.Thread.State: WAITING
      at jdk.internal.misc.Unsafe.park(Unsafe.java:-1)
      at java.util.concurrent.locks.LockSupport.park(LockSupport.java:341)
      at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(AbstractQueuedSynchronizer.java:506)
      at java.util.concurrent.ForkJoinPool.unmanagedBlock(ForkJoinPool.java:3463)
      at java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3434)
      at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1623)
      at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:435)
      at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:117)
      at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33)
      at org.apache.tomcat.util.threads.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1114)
      at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1176)
      at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
      at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
      at java.lang.Thread.run(Thread.java:833)

"Catalina-utility-1@5848" prio=1 tid=0x15 nid=NA waiting
  java.lang.Thread.State: WAITING
      at jdk.internal.misc.Unsafe.park(Unsafe.java:-1)
      at java.util.concurrent.locks.LockSupport.park(LockSupport.java:341)
      at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(AbstractQueuedSynchronizer.java:506)
      at java.util.concurrent.ForkJoinPool.unmanagedBlock(ForkJoinPool.java:3463)
      at java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3434)
      at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1623)
      at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1177)
      at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:899)
      at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1062)
      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1122)
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
      at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
      at java.lang.Thread.run(Thread.java:833)

"Catalina-utility-2@5847" prio=1 tid=0x16 nid=NA runnable
  java.lang.Thread.State: RUNNABLE
      at jdk.internal.misc.Unsafe.park(Unsafe.java:-1)
      at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:252)
      at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:1672)
      at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1182)
      at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:899)
      at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1062)
      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1122)
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
      at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
      at java.lang.Thread.run(Thread.java:833)

"HikariPool-1 housekeeper@7166" daemon prio=5 tid=0x18 nid=NA runnable
  java.lang.Thread.State: RUNNABLE
      at jdk.internal.misc.Unsafe.park(Unsafe.java:-1)
      at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:252)
      at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:1672)
      at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1182)
      at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:899)
      at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1062)
      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1122)
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
      at java.lang.Thread.run(Thread.java:833)

"http-nio-4983-Poller@11046" daemon prio=5 tid=0x24 nid=NA runnable
  java.lang.Thread.State: RUNNABLE
      at sun.nio.ch.WEPoll.wait(WEPoll.java:-1)
      at sun.nio.ch.WEPollSelectorImpl.doSelect(WEPollSelectorImpl.java:111)
      at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:129)
      - locked <0x2c5f> (a sun.nio.ch.WEPollSelectorImpl)
      - locked <0x2c60> (a sun.nio.ch.Util$2)
      at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:141)
      at org.apache.tomcat.util.net.NioEndpoint$Poller.run(NioEndpoint.java:751)
      at java.lang.Thread.run(Thread.java:833)

"http-nio-4983-Acceptor@11048" daemon prio=5 tid=0x25 nid=NA runnable
  java.lang.Thread.State: RUNNABLE
      at sun.nio.ch.Net.accept(Net.java:-1)
      at sun.nio.ch.ServerSocketChannelImpl.implAccept(ServerSocketChannelImpl.java:425)
      at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:391)
      at org.apache.tomcat.util.net.NioEndpoint.serverSocketAccept(NioEndpoint.java:520)
      at org.apache.tomcat.util.net.NioEndpoint.serverSocketAccept(NioEndpoint.java:79)
      at org.apache.tomcat.util.net.Acceptor.run(Acceptor.java:128)
      at java.lang.Thread.run(Thread.java:833)

"Common-Cleaner@11356" daemon prio=8 tid=0xc nid=NA waiting
  java.lang.Thread.State: WAITING
      at java.lang.Object.wait(Object.java:-1)
      at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:155)
      at jdk.internal.ref.CleanerImpl.run(CleanerImpl.java:140)
      at java.lang.Thread.run(Thread.java:833)
      at jdk.internal.misc.InnocuousThread.run(InnocuousThread.java:162)

"container-0@5846" prio=5 tid=0x17 nid=NA runnable
  java.lang.Thread.State: RUNNABLE
      at java.lang.Thread.sleep(Thread.java:-1)
      at org.apache.catalina.core.StandardServer.await(StandardServer.java:562)
      at org.springframework.boot.web.embedded.tomcat.TomcatWebServer$1.run(TomcatWebServer.java:197)

"Reference Handler@11352" daemon prio=10 tid=0x2 nid=NA runnable
  java.lang.Thread.State: RUNNABLE
      at java.lang.ref.Reference.waitForReferencePendingList(Reference.java:-1)
      at java.lang.ref.Reference.processPendingReferences(Reference.java:253)
      at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:215)

"Finalizer@11353" daemon prio=8 tid=0x3 nid=NA waiting
  java.lang.Thread.State: WAITING
      at java.lang.Object.wait(Object.java:-1)
      at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:155)
      at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:176)
      at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:172)

"Signal Dispatcher@11354" daemon prio=9 tid=0x4 nid=NA runnable
  java.lang.Thread.State: RUNNABLE

"Attach Listener@11355" daemon prio=5 tid=0x5 nid=NA runnable
  java.lang.Thread.State: RUNNABLE

"Notification Thread@727" daemon prio=9 tid=0x10 nid=NA runnable
  java.lang.Thread.State: RUNNABLE

"DestroyJavaVM@11045" prio=5 tid=0x26 nid=NA runnable
  java.lang.Thread.State: RUNNABLE

And here's partial debug log for when I pass an empty token:

"http-nio-4983-exec-3@10997" daemon prio=5 tid=0x1c nid=NA runnable
  java.lang.Thread.State: RUNNABLE
      at com.onlineshop.main.config.security.exceptions.CustomAuthenticationEntryPoint.commence(CustomAuthenticationEntryPoint.java:21)
      at org.springframework.security.web.access.ExceptionTranslationFilter.sendStartAuthentication(ExceptionTranslationFilter.java:219)
      at org.springframework.security.web.access.ExceptionTranslationFilter.handleAccessDeniedException(ExceptionTranslationFilter.java:197)
      at org.springframework.security.web.access.ExceptionTranslationFilter.handleSpringSecurityException(ExceptionTranslationFilter.java:178)
      at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:147)
      at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:120)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:100)

Solution

  • Based on your logs, the BearerAuthenticationEntryPoint is being called from the line 77:

    at org.springframework.security.oauth2.server.resource.web.authentication.BearerTokenAuthenticationFilter.lambda$new$0(BearerTokenAuthenticationFilter.java:77)
    

    This is the authenticationFailureHandler field, which then invokes the AuthenticationEntryPoint. If I'm not mistaken, the oauth2ResourceServer DSL does not uses the same AuthenticationEntryPoint from exceptionHandling(), therefore you have to explicitly configure it, like so:

    http
        // ...
        .oauth2ResourceServer((oauth2) -> oauth2
            .jwt((jwt) -> jwt.jwtAuthenticationConverter(jwtToUserConverter))
            .authenticationEntryPoint(new CustomAuthenticationEntryPoint())
        );