Here is a simple project that demonstrates the problem:
https://github.com/ralscha/ignoring
Spring Boot adds by default ignore rules for /css/, /js/ and /images/**.
Creating filter chain: Ant [pattern='/css/**'], []
Creating filter chain: Ant [pattern='/js/**'], []
Creating filter chain: Ant [pattern='/images/**'], []
When there is a custom WebSecurityConfigurerAdapter in the application these rules will not be applied which is what I want.
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebSecurity
class SecurityConfig extends WebSecurityConfigurerAdapter {
.....
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/img2.png");
}
.....
}
Creating filter chain: Ant [pattern='/img2.png'], []
Creating filter chain: Ant [pattern='/**'], .......
But as soon as you add the actuator as a dependency this behavior changes
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
The presence of a custom WebSecurityConfigurerAdapter no longer overwrites the default ignore rules and the code in the configure method will be ignored.
Creating filter chain: OrRequestMatcher [requestMatchers=[Ant [pattern='/css/**'], Ant [pattern='/js/**'], Ant [pattern='/images/**'], Ant [pattern='/**/favicon.ico'], Ant [pattern='/error']]], []
Creating filter chain: OrRequestMatcher [requestMatchers=[Ant [pattern='/**']]],......
To override the default rules you need to add a security.ignored property in the applicaiton.properties or application.yml file
security:
ignored:
- /img2.png
Creating filter chain: OrRequestMatcher [requestMatchers=[Ant [pattern='/img2.png'], Ant [pattern='/error']]], []
Creating filter chain: OrRequestMatcher [requestMatchers=[Ant [pattern='/**']]], .....
After further investigating this issue I figured out that my statement about ignoring the rule from the configure method is wrong. The framework always adds the ignore rule from the
public void configure(WebSecurity web) method
But there is a difference when the actuator is on the classpath or not.
Default. Without actuator on the classpath and without a custom WebSecurityConfigurerAdapter
Creating filter chain: Ant [pattern='/css/**'], []
Creating filter chain: Ant [pattern='/js/**'], []
Creating filter chain: Ant [pattern='/images/**'], []
Creating filter chain: Ant [pattern='/webjars/**'], []
Creating filter chain: Ant [pattern='/**/favicon.ico'], []
Creating filter chain: Ant [pattern='/error'], []
With a custom WebSecurityConfigurerAdapter and without actuator on the classpath
Creating filter chain: Ant [pattern='/img2.png'], []
With a custom WebSecurityConfigurerAdapter and with the actuator on the classpath
Creating filter chain: OrRequestMatcher [requestMatchers=[Ant [pattern='/css/**'], Ant [pattern='/js/**'], Ant [pattern='/images/**'], Ant [pattern='/webjars/**'], Ant [pattern='/**/favicon.ico'], Ant [pattern='/error']]], []
Creating filter chain: Ant [pattern='/img2.png'], []
The problem is that the org.springframework.boot.actuate.autoconfigure.ManagementWebSecurityAutoConfiguration
re-adds the default ignore rules.
A solution is to set security.ignored to none.
security:
ignored:
- none
Creating filter chain: OrRequestMatcher [requestMatchers=[Ant [pattern='/error']]], []
Creating filter chain: Ant [pattern='/img2.png'], []
Not exactly the same as without the actuator because it still adds the ignore rule for /error
I can see that there is some surprising behaviour here, but I'm not sure what the best way to converge is. Your "solution" looks like the desired end state whether or not the actuator is available, so probably we should add "/error" to the ignored path even if there is no actuator and the user is attempting to customize the ignores. It's not possible to detect when a user is attempting to do that, so we have to make an assumption, I guess, by using the presence of @EnableWebSecurity.
Removing the duplicate IgnoredPathsWebSecurityConfigurerAdapter in ManagementWebSecurityAutoConfiguration should take of this discrepancy when actuator is on the classpath. See #7106.
Looks good now. I tested it with the 1.5.0 snapshot and it does no longer make a difference if the actuator is on the classpath or not. Thanks for the change.
Defaults. Without actuator on the classpath
1.4.2.RELEASE
Creating filter chain: Ant [pattern='/css/**'], []
Creating filter chain: Ant [pattern='/js/**'], []
Creating filter chain: Ant [pattern='/images/**'], []
Creating filter chain: Ant [pattern='/webjars/**'], []
Creating filter chain: Ant [pattern='/**/favicon.ico'], []
Creating filter chain: Ant [pattern='/error'], []
1.5.0.BUILD-SNAPSHOT
Creating filter chain: OrRequestMatcher [requestMatchers=[Ant [pattern='/css/**'], Ant [pattern='/js/**'], Ant [pattern='/images/**'], Ant [pattern='/webjars/**'], Ant [pattern='/**/favicon.ico'], Ant [pattern='/error']]], []
Defaults. With actuator on the classpath
1.4.2.RELEASE
Creating filter chain: OrRequestMatcher [requestMatchers=[Ant [pattern='/css/**'], Ant [pattern='/js/**'], Ant [pattern='/images/**'], Ant [pattern='/webjars/**'], Ant [pattern='/**/favicon.ico'], Ant [pattern='/error']]], []
1.5.0.BUILD-SNAPSHOT
Creating filter chain: OrRequestMatcher [requestMatchers=[Ant [pattern='/css/**'], Ant [pattern='/js/**'], Ant [pattern='/images/**'], Ant [pattern='/webjars/**'], Ant [pattern='/**/favicon.ico'], Ant [pattern='/error']]], []
With security.ignored=none. Without actuator on the classpath
1.4.2.RELEASE
Creating filter chain: Ant [pattern='/error'], []
1.5.0.BUILD-SNAPSHOT
Creating filter chain: OrRequestMatcher [requestMatchers=[Ant [pattern='/error']]], []
With security.ignored=none. With actuator on the classpath
1.4.2.RELEASE
Creating filter chain: OrRequestMatcher [requestMatchers=[Ant [pattern='/error']]], []
1.5.0.BUILD-SNAPSHOT
Creating filter chain: OrRequestMatcher [requestMatchers=[Ant [pattern='/error']]], []
With custom WebSecurityConfigurerAdapter. Without actuator on the classpath
1.4.2.RELEASE
Creating filter chain: Ant [pattern='/img2.png'], []
1.5.0.BUILD-SNAPSHOT
Creating filter chain: Ant [pattern='/img2.png'], []
With custom WebSecurityConfigurerAdapter. With actuator on the classpath
1.4.2.RELEASE
Creating filter chain: OrRequestMatcher [requestMatchers=[Ant [pattern='/css/**'], Ant [pattern='/js/**'], Ant [pattern='/images/**'], Ant [pattern='/webjars/**'], Ant [pattern='/**/favicon.ico'], Ant [pattern='/error']]], []
Creating filter chain: Ant [pattern='/img2.png'], []
1.5.0.BUILD-SNAPSHOT
Creating filter chain: Ant [pattern='/img2.png'], []
With security.ignored=none and custom WebSecurityConfigurerAdapter. Without actuator on the classpath
1.4.2.RELEASE
Creating filter chain: Ant [pattern='/img2.png'], []
1.5.0.BUILD-SNAPSHOT
Creating filter chain: Ant [pattern='/img2.png'], []
With security.ignored=none and custom WebSecurityConfigurerAdapter. With actuator on the classpath
1.4.2.RELEASE
Creating filter chain: OrRequestMatcher [requestMatchers=[Ant [pattern='/error']]], []
Creating filter chain: Ant [pattern='/img2.png'], []
1.5.0.BUILD-SNAPSHOT
Creating filter chain: Ant [pattern='/img2.png'], []
Custom WebSecurityConfigurerAdapter used in this example
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/img2.png");
}
@ralscha Thanks for testing!
Most helpful comment
Looks good now. I tested it with the 1.5.0 snapshot and it does no longer make a difference if the actuator is on the classpath or not. Thanks for the change.
Defaults. Without actuator on the classpath
1.4.2.RELEASE
1.5.0.BUILD-SNAPSHOT
Defaults. With actuator on the classpath
1.4.2.RELEASE
1.5.0.BUILD-SNAPSHOT
With
security.ignored=none. Without actuator on the classpath1.4.2.RELEASE
1.5.0.BUILD-SNAPSHOT
With
security.ignored=none. With actuator on the classpath1.4.2.RELEASE
1.5.0.BUILD-SNAPSHOT
With custom WebSecurityConfigurerAdapter. Without actuator on the classpath
1.4.2.RELEASE
1.5.0.BUILD-SNAPSHOT
With custom WebSecurityConfigurerAdapter. With actuator on the classpath
1.4.2.RELEASE
1.5.0.BUILD-SNAPSHOT
With
security.ignored=noneand custom WebSecurityConfigurerAdapter. Without actuator on the classpath1.4.2.RELEASE
1.5.0.BUILD-SNAPSHOT
With
security.ignored=noneand custom WebSecurityConfigurerAdapter. With actuator on the classpath1.4.2.RELEASE
1.5.0.BUILD-SNAPSHOT
Custom WebSecurityConfigurerAdapter used in this example