Reputation: 1
My goal is to provide a starter (spring boot 3.4) that brings an out-of-the-box experience. In essence it is a collection of authentication providers and converters, configuration of the authentication manager and finally setting up the SecurityFilterChain. Preferably users wouldn't need to add @EnableWebSecurity
in their applications as that would be impled by depending on the starter.
My setup works so far as I can put all configuration in the starter, except the SecurityFilterChain
. Either it conflicts with the defaultSecurityFilterChain or it conflicts with managementSecurityFilterChain from Actuator. Looking at ManagementWebSecurityAutoConfiguration I can see it annotated with @ConditionalOnDefaultWebSecurity
and similarly I believe that defaultSecurityFilterChain is dependent on the same condition. I tried tweaking the autoconfiguration order of my configuration but can't seem to nail it:
@Configuration
@ConditionalOnClass(EnableWebSecurity.class)
@AutoConfigureBefore(SecurityAutoConfiguration.class)
public class MySecurityConfiguration {
...
@Bean
public SecurityFilterChain securityFilterChain(...) {
...
}
}
with an error being thrown:
A filter chain that matches any request [DefaultSecurityFilterChain defined as 'managementSecurityFilterChain' in ... has already been configured, which means that this filter chain [DefaultSecurityFilterChain defined as 'securityFilterChain' in ... will never get invoked. Please use HttpSecurity#securityMatcher to ensure that there is only one filter chain configured for 'any request' and that the 'any request' filter chain is published last.
Upvotes: 0
Views: 68
Reputation: 1
This eventually turned out to be an auto configuration ordering issue when spring-boot-starter-actuator is present. In order for ManagementWebSecurityAutoConfiguration
not to apply on the @ConditionalOnDefaultWebSecurity
, the ordering needs to be set up as such:
@Configuration
@ConditionalOnDefaultWebSecurity
@AutoConfigureBefore({SecurityAutoConfiguration.class, ManagementWebSecurityAutoConfiguration.class})
public class MySecurityConfiguration {
...
@Bean
public SecurityFilterChain securityFilterChain(...) {
...
}
}
Also note the switch to @ConditionalOnDefaultWebSecurity
. If an SecurityFilterChain
bean is already present (as in explicit configuration), this condition will not apply. Depending on the circumstances this condition should, or should not, be used:
SecurityFilterChain
without a securitymatcher set up, and expressing an anyRequest()
is final. Users of the opinionated spring security starter that want to modify or add to the existing security configuration would have to supply their own, explicit, SecurityFilterChain
bean. In this case @ConditionalOnDefaultWebSecurity
is suitable as it only applies when a SecurityFilterChain
bean isn't present.SecurityFilterChain
that does not use an anyRequest()
but rather supplies patterns to be authorized could later be extended on with additional SecurityFilterChain
beans. In this case @ConditionalOnDefaultWebSecurity
must not be used and @Order
has a more important role as users may want to apply their extensions either before, or after, the opinionated SecurityFilterChain
.Upvotes: 0