4

I am facing the issue which is not obvious to resolve just by reading the documentation. While migrating to Spring Boot v2.7.4 / Spring Security v5.7.3 I have refactored the configuration not to extend WebSecurityConfigurerAdapter and to look like below:

@Configuration
@EnableWebSecurity
public class CustomSecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.
            csrf().disable().
            logout().disable().
            authorizeRequests().anyRequest().permitAll();

        return http.build();
    }
}

The above method is called, however has no effect as SecurityFilterChain instance created by OAuth2SecurityFilterChainConfiguration is used instead (I see that from debug by inspecting the list of filter in the stack that has e.g. LogoutFilter which should be disabled by above configuration). Debug log:

2022-10-20 15:49:48.790 [main] o.s.b.a.s.DefaultWebSecurityCondition    : Condition DefaultWebSecurityCondition on org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerJwtConfiguration$OAuth2SecurityFilterChainConfiguration matched due to AllNestedConditions 2 matched 0 did not; NestedCondition on DefaultWebSecurityCondition.Beans @ConditionalOnMissingBean (types: org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter,org.springframework.security.web.SecurityFilterChain; SearchStrategy: all) did not find any beans; NestedCondition on DefaultWebSecurityCondition.Classes @ConditionalOnClass found required classes 'org.springframework.security.web.SecurityFilterChain', 'org.springframework.security.config.annotation.web.builders.HttpSecurity'
2022-10-20 15:49:48.791 [main] a.ConfigurationClassBeanDefinitionReader : Registered bean definition for imported class 'org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerJwtConfiguration$OAuth2SecurityFilterChainConfiguration'
2022-10-20 15:49:48.792 [main] o.s.b.a.condition.OnBeanCondition        : Condition OnBeanCondition on org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerJwtConfiguration$OAuth2SecurityFilterChainConfiguration#jwtSecurityFilterChain matched due to @ConditionalOnBean (types: org.springframework.security.oauth2.jwt.JwtDecoder; SearchStrategy: all) found bean 'jwtDecoderByJwkKeySetUri'
...
2022-10-20 15:49:49.082 [main] a.ConfigurationClassBeanDefinitionReader : Registering bean definition for @Bean method com.mycompany.CustomSecurityConfig.filterChain()
...
2022-10-20 15:49:52.276 [main] edFilterInvocationSecurityMetadataSource : Adding web access control expression [authenticated] for any request
2022-10-20 15:50:13.348 [main] o.s.s.web.DefaultSecurityFilterChain     : Will secure any request with [org.springframework.security.web.session.DisableEncodeUrlFilter@33502cfe, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@729d1428, org.springframework.security.web.context.SecurityContextPersistenceFilter@7d0312a, org.springframework.security.web.header.HeaderWriterFilter@6ca97ddf, org.springframework.security.web.csrf.CsrfFilter@38f569d, org.springframework.security.web.authentication.logout.LogoutFilter@1104ad6a, org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationFilter@74ab8610, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@7833407, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@66acaa54, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@115924ba, org.springframework.security.web.session.SessionManagementFilter@6a905513, org.springframework.security.web.access.ExceptionTranslationFilter@5749e633, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@49741e80]
...
2022-10-20 15:50:13.384 [main] edFilterInvocationSecurityMetadataSource : Adding web access control expression [permitAll] for any request
2022-10-20 15:50:17.641 [main] o.s.s.web.DefaultSecurityFilterChain     : Will secure any request with [org.springframework.security.web.session.DisableEncodeUrlFilter@4a0f4282, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@19d3f4fb, org.springframework.security.web.context.SecurityContextPersistenceFilter@99f75e4, org.springframework.security.web.header.HeaderWriterFilter@118c1faa, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@2b6ff016, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@5aefdb9e, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@43cf97a8, org.springframework.security.web.session.SessionManagementFilter@da5b46f, org.springframework.security.web.access.ExceptionTranslationFilter@11267e87, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@7827cdfc]

Is it expected that the bean CustomSecurityConfig.filterChain participates in DefaultWebSecurityCondition evaluation and OAuth2SecurityFilterChainConfiguration.jwtSecurityFilterChain is not created. Or the issue with DefaultWebSecurityCondition is that the instance of WebSecurityConfigurerAdapter is not in the context anymore (as to issue #10822 it is deprecated)?

The suggestion to add @Order() annotation didn't work:

@Configuration
@EnableWebSecurity
public class CustomSecurityConfig {

    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { ...

as well as further attempts to exclude the autoconfiguration class like this:

@SpringBootApplication(excludeName = "org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerJwtConfiguration.OAuth2SecurityFilterChainConfiguration")
public class Application extends SpringBootServletInitializer { ...

failed probably due to issue #5427 with the following error

java.lang.IllegalStateException: The following classes could not be excluded because they are not auto-configuration classes:
    - org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerJwtConfiguration.OAuth2SecurityFilterChainConfiguration
    at org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.handleInvalidExcludes(AutoConfigurationImportSelector.java:222) ~[spring-boot-autoconfigure-2.7.4.jar!/:2.7.4]

This way also does not work:

@ComponentScan(excludeFilters = {@ComponentScan.Filter(type = FilterType.REGEX, pattern = ".*OAuth2ResourceServerJwtConfiguration.*")})
public class Application extends SpringBootServletInitializer { ...

The documentation I read before posting:

Update

I have created a small Maven project that demonstrates the issue. After project is started, request the controller like this:

$ wget -nv -O - 'http://localhost:8080/spring/test'
Username/Password Authentication Failed.

As one can see, the custom configured SecurityFilterChain is not active because otherwise the access would be granted (as to antMatchers( "/**/test").permitAll()). ContextRefreshedEvent listener dumps two SecurityFilterChain instances (jwtSecurityFilterChain and filterChain), the priority of them is not possible to configure reliably.

dma_k
  • 10,431
  • 16
  • 76
  • 128
  • I think your CustomSecurityConfig should extend WebSecurityConfigurerAdapter – reza ramezani matin Oct 26 '22 at 11:45
  • I think you've missed the whole story: `WebSecurityConfigurerAdapter` is now marked as deprecated, take a look at documentation links from the post. – dma_k Oct 26 '22 at 22:12
  • Can you provide a minimal, reproducible sample? – Marcus Hert da Coregio Oct 27 '22 at 13:45
  • @MarcusHertdaCoregio I have created a [small project](https://www.dropbox.com/s/4mg7up88d5m0eba/spring-test.7z?dl=1) that reproduces the issue. See updated post. – dma_k Nov 09 '22 at 19:38
  • 2
    With that small project, I think you should open an issue in Spring Boot https://github.com/spring-projects/spring-boot/issues – Marcus Hert da Coregio Nov 10 '22 at 11:30
  • 1
    As follows from [issue #33103](https://github.com/spring-projects/spring-boot/issues/33103#issuecomment-1310815121), the beans imported from XML via `@ImportResource` do not participate in Spring Boot autoconfiguration, hence beans scanning should be performed using annotation i.e. `@SpringBootApplication(scanBasePackages = "some.package")` – this basically solves the issue. – dma_k Nov 17 '22 at 09:21

0 Answers0