Failed to protected my REST API with Spring Security

I fellowed this link, and created a Spring Boot (2.6.8) application which integrated with Keycloak 16.1.1, Flowable Engine 6.7.2, Flowable UI and Spring Security 5.6.5. Here are the dependencis:

		<!--flowable -->
		<dependency>
			<groupId>org.flowable</groupId>
			<artifactId>flowable-spring-boot-starter</artifactId>
			<version>${flowable.version}</version>
		</dependency>

		<!-- flowable-ui -->
		<dependency>
			<groupId>org.flowable</groupId>
			<artifactId>flowable-spring-boot-starter-ui-modeler</artifactId>
			<version>${flowable.version}</version>
		</dependency>

		<dependency>
			<groupId>org.flowable</groupId>
			<artifactId>flowable-spring-boot-starter-ui-admin</artifactId>
			<version>${flowable.version}</version>
		</dependency>
		
		<dependency>
			<groupId>org.flowable</groupId>
			<artifactId>flowable-spring-boot-starter-ui-idm</artifactId>
			<version>${flowable.version}</version>
		</dependency>
		
		<dependency>
			<groupId>org.flowable</groupId>
			<artifactId>flowable-spring-boot-starter-ui-task</artifactId>
			<version>${flowable.version}</version>
		</dependency>

Everything works well except one:

All the REST APIs defined in my Controllers can’t be protected by Spring Security.

Of course, I have created a WebSecurityConfigurerAdapter for this:

@EnableWebSecurity(debug = true)
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http.antMatcher("/oa/**").authorizeRequests()
			.antMatchers("/oa/**").authenticated();

		// http.oauth2Client();
	}
}

Here are some logs:

2022-06-07 11:58:29.556 | DEBUG | o.s.s.w.FilterChainProxy | Securing GET /oa/expense/processes?userId=staff | FilterChainProxy.java:208
2022-06-07 11:58:29.557 | TRACE | o.s.s.w.FilterChainProxy | Invoking WebAsyncManagerIntegrationFilter (1/16) | FilterChainProxy.java:333
2022-06-07 11:58:29.559 | TRACE | o.s.s.w.FilterChainProxy | Invoking SecurityContextPersistenceFilter (2/16) | FilterChainProxy.java:333
2022-06-07 11:58:29.560 | TRACE | o.s.s.w.c.HttpSessionSecurityContextRepository | No HttpSession currently exists | HttpSessionSecurityContextRepository.java:156
2022-06-07 11:58:29.560 | TRACE | o.s.s.w.c.HttpSessionSecurityContextRepository | Created SecurityContextImpl [Null authentication] | HttpSessionSecurityContextRepository.java:123
2022-06-07 11:58:29.563 | DEBUG | o.s.s.w.c.SecurityContextPersistenceFilter | Set SecurityContextHolder to empty SecurityContext | SecurityContextPersistenceFilter.java:102
2022-06-07 11:58:29.564 | TRACE | o.s.s.w.FilterChainProxy | Invoking HeaderWriterFilter (3/16) | FilterChainProxy.java:333
2022-06-07 11:58:29.566 | TRACE | o.s.s.w.FilterChainProxy | Invoking LogoutFilter (4/16) | FilterChainProxy.java:333
2022-06-07 11:58:29.566 | TRACE | o.s.s.w.a.l.LogoutFilter | Did not match request to Or [Ant [pattern='/app/logout', GET], Ant [pattern='/app/logout', POST], Ant [pattern='/app/logout', PUT], Ant [pattern='/app/logout', DELETE]] | LogoutFilter.java:117
2022-06-07 11:58:29.567 | TRACE | o.s.s.w.FilterChainProxy | Invoking OAuth2AuthorizationRequestRedirectFilter (5/16) | FilterChainProxy.java:333
2022-06-07 11:58:29.567 | TRACE | o.s.s.w.FilterChainProxy | Invoking OAuth2AuthorizationRequestRedirectFilter (6/16) | FilterChainProxy.java:333
2022-06-07 11:58:29.568 | TRACE | o.s.s.w.FilterChainProxy | Invoking OAuth2LoginAuthenticationFilter (7/16) | FilterChainProxy.java:333
2022-06-07 11:58:29.568 | TRACE | o.s.s.o.c.w.OAuth2LoginAuthenticationFilter | Did not match request to Ant [pattern='/login/oauth2/code/*'] | AbstractAuthenticationProcessingFilter.java:262
2022-06-07 11:58:29.568 | TRACE | o.s.s.w.FilterChainProxy | Invoking DefaultLoginPageGeneratingFilter (8/16) | FilterChainProxy.java:333
2022-06-07 11:58:29.569 | TRACE | o.s.s.w.FilterChainProxy | Invoking DefaultLogoutPageGeneratingFilter (9/16) | FilterChainProxy.java:333
2022-06-07 11:58:29.569 | TRACE | o.s.s.w.a.u.DefaultLogoutPageGeneratingFilter | Did not render default logout page since request did not match [Ant [pattern='/logout', GET]] | DefaultLogoutPageGeneratingFilter.java:55
2022-06-07 11:58:29.570 | TRACE | o.s.s.w.FilterChainProxy | Invoking RequestCacheAwareFilter (10/16) | FilterChainProxy.java:333
2022-06-07 11:58:29.571 | TRACE | o.s.s.w.s.HttpSessionRequestCache | No saved request | HttpSessionRequestCache.java:102
2022-06-07 11:58:29.571 | TRACE | o.s.s.w.FilterChainProxy | Invoking SecurityContextHolderAwareRequestFilter (11/16) | FilterChainProxy.java:333
2022-06-07 11:58:29.573 | TRACE | o.s.s.w.FilterChainProxy | Invoking AnonymousAuthenticationFilter (12/16) | FilterChainProxy.java:333
2022-06-07 11:58:29.575 | TRACE | o.s.s.w.a.AnonymousAuthenticationFilter | Set SecurityContextHolder to AnonymousAuthenticationToken [Principal=anonymousUser, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=null], Granted Authorities=[ROLE_ANONYMOUS]] | AnonymousAuthenticationFilter.java:92
2022-06-07 11:58:29.575 | TRACE | o.s.s.w.FilterChainProxy | Invoking OAuth2AuthorizationCodeGrantFilter (13/16) | FilterChainProxy.java:333
2022-06-07 11:58:29.577 | TRACE | o.s.s.w.FilterChainProxy | Invoking SessionManagementFilter (14/16) | FilterChainProxy.java:333
2022-06-07 11:58:29.578 | TRACE | o.s.s.w.FilterChainProxy | Invoking ExceptionTranslationFilter (15/16) | FilterChainProxy.java:333
2022-06-07 11:58:29.578 | TRACE | o.s.s.w.FilterChainProxy | Invoking FilterSecurityInterceptor (16/16) | FilterChainProxy.java:333
2022-06-07 11:58:29.580 | TRACE | o.s.s.w.a.e.ExpressionBasedFilterInvocationSecurityMetadataSource | Did not match request to Ant [pattern='/app/rest/account'] - [authenticated] (1/14) | DefaultFilterInvocationSecurityMetadataSource.java:89
2022-06-07 11:58:29.581 | TRACE | o.s.s.w.a.e.ExpressionBasedFilterInvocationSecurityMetadataSource | Did not match request to Ant [pattern='/app/rest/runtime/app-definitions'] - [authenticated] (2/14) | DefaultFilterInvocationSecurityMetadataSource.java:89
2022-06-07 11:58:29.582 | TRACE | o.s.s.w.a.e.ExpressionBasedFilterInvocationSecurityMetadataSource | Did not match request to Ant [pattern='/idm-app/rest/authenticate'] - [authenticated] (3/14) | DefaultFilterInvocationSecurityMetadataSource.java:89
2022-06-07 11:58:29.582 | TRACE | o.s.s.w.a.e.ExpressionBasedFilterInvocationSecurityMetadataSource | Did not match request to Ant [pattern='/idm-app/rest/account'] - [authenticated] (4/14) | DefaultFilterInvocationSecurityMetadataSource.java:89
2022-06-07 11:58:29.583 | TRACE | o.s.s.w.a.e.ExpressionBasedFilterInvocationSecurityMetadataSource | Did not match request to Ant [pattern='/app/rest/**'] - [hasAuthority('access-task')] (5/14) | DefaultFilterInvocationSecurityMetadataSource.java:89
2022-06-07 11:58:29.583 | TRACE | o.s.s.w.a.e.ExpressionBasedFilterInvocationSecurityMetadataSource | Did not match request to Ant [pattern='/workflow/'] - [hasAuthority('access-task')] (6/14) | DefaultFilterInvocationSecurityMetadataSource.java:89
2022-06-07 11:58:29.584 | TRACE | o.s.s.w.a.e.ExpressionBasedFilterInvocationSecurityMetadataSource | Did not match request to Ant [pattern='/admin-app/**'] - [hasAuthority('access-admin')] (7/14) | DefaultFilterInvocationSecurityMetadataSource.java:89
2022-06-07 11:58:29.584 | TRACE | o.s.s.w.a.e.ExpressionBasedFilterInvocationSecurityMetadataSource | Did not match request to Ant [pattern='/admin/'] - [hasAuthority('access-admin')] (8/14) | DefaultFilterInvocationSecurityMetadataSource.java:89
2022-06-07 11:58:29.585 | TRACE | o.s.s.w.a.e.ExpressionBasedFilterInvocationSecurityMetadataSource | Did not match request to Ant [pattern='/idm-app/**'] - [hasAuthority('access-idm')] (9/14) | DefaultFilterInvocationSecurityMetadataSource.java:89
2022-06-07 11:58:29.585 | TRACE | o.s.s.w.a.e.ExpressionBasedFilterInvocationSecurityMetadataSource | Did not match request to Ant [pattern='/modeler-app/**'] - [hasAuthority('access-modeler')] (10/14) | DefaultFilterInvocationSecurityMetadataSource.java:89
2022-06-07 11:58:29.586 | TRACE | o.s.s.w.a.e.ExpressionBasedFilterInvocationSecurityMetadataSource | Did not match request to Ant [pattern='/modeler/'] - [hasAuthority('access-modeler')] (11/14) | DefaultFilterInvocationSecurityMetadataSource.java:89
2022-06-07 11:58:29.587 | TRACE | o.s.s.w.a.e.ExpressionBasedFilterInvocationSecurityMetadataSource | Did not match request to Ant [pattern='/'] - [authenticated] (12/14) | DefaultFilterInvocationSecurityMetadataSource.java:89
2022-06-07 11:58:29.587 | TRACE | o.s.s.w.a.e.ExpressionBasedFilterInvocationSecurityMetadataSource | Did not match request to Ant [pattern='/app/authentication'] - [permitAll] (13/14) | DefaultFilterInvocationSecurityMetadataSource.java:89
2022-06-07 11:58:29.588 | TRACE | o.s.s.w.a.e.ExpressionBasedFilterInvocationSecurityMetadataSource | Did not match request to Ant [pattern='/idm'] - [permitAll] (14/14) | DefaultFilterInvocationSecurityMetadataSource.java:89
2022-06-07 11:58:29.590 | DEBUG | o.s.s.w.a.i.FilterSecurityInterceptor | Authorized public object filter invocation [GET /oa/expense/processes?userId=staff] | AbstractSecurityInterceptor.java:194
2022-06-07 11:58:29.591 | TRACE | o.s.b.f.s.DefaultListableBeanFactory | Returning cached instance of singleton bean 'delegatingApplicationListener' | AbstractBeanFactory.java:264
2022-06-07 11:58:29.591 | TRACE | o.s.b.f.s.DefaultListableBeanFactory | Returning cached instance of singleton bean 'springApplicationAdminRegistrar' | AbstractBeanFactory.java:264
2022-06-07 11:58:29.591 | TRACE | o.s.b.f.s.DefaultListableBeanFactory | Returning cached instance of singleton bean 'liveReloadServerEventListener' | AbstractBeanFactory.java:264
2022-06-07 11:58:29.592 | DEBUG | o.s.s.w.FilterChainProxy | Secured GET /oa/expense/processes?userId=staff | FilterChainProxy.java:323
2022-06-07 11:58:29.598 | TRACE | o.s.w.s.DispatcherServlet | GET "/oa/expense/processes?userId=staff", parameters={masked}, headers={masked} in DispatcherServlet 'dispatcherServlet' | LogFormatUtils.java:116

It seems that no any filter has been generated for my url in FilterChainProxy.

So, how can I fix this problem? Any help is expected. Thanks.

It has been resolved by myself. The key point is the ORDER, see below

@EnableWebSecurity(debug = true)
@Order(SecurityConstants.FORM_LOGIN_SECURITY_ORDER - 1) 
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

@Override
	protected void configure(HttpSecurity http) throws Exception {
			http.cors().and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

		http.requestMatchers().antMatchers("/oa/**", "/demo/**"); 
		
		http.authorizeRequests()
			.antMatchers("/oa/**", "/demo/**").authenticated();
		
		//validate JWT Bearer token
		http.oauth2ResourceServer().jwt();
	}

}