Skip to content

Commit 05c877d

Browse files
committed
Only apply path to default PathPatternRequestMatcher.Builder
Prior to this commit, if the user defined a custom PathPatternRequestMatcher.Builder, security auto-configuration would still set its base path to matcher the dispatcher servlet path. We need to give the user more control in this situation. If the user has defined a custom builder bean it should have a name other than pathPatternRequestMatcherBuilder. This different name is required to prevent a clash with the @fallback bean that's defined by Security's AuthorizationConfiguration. This commit changes the bean post-processor so that it will only apply to a bean named pathPatternRequestMatcherBuilder. By using a different name (which is necessary unless overriding is enabled) to use can take complete control of the path pattern request matcher builder. See gh-45492
1 parent 5bafe70 commit 05c877d

File tree

2 files changed

+23
-1
lines changed

2 files changed

+23
-1
lines changed

module/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/servlet/SpringBootWebSecurityConfiguration.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ static BeanPostProcessor pathPatternRequestMatcherBuilderBasePathCustomizer(
5959

6060
@Override
6161
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
62-
if (bean instanceof PathPatternRequestMatcher.Builder builder) {
62+
if ("pathPatternRequestMatcherBuilder".equals(beanName)
63+
&& bean instanceof PathPatternRequestMatcher.Builder builder) {
6364
String path = dispatcherServletPath.getObject().getPath();
6465
if (!path.equals("/")) {
6566
return builder.basePath(path);

module/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/servlet/SecurityAutoConfigurationTests.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
4343
import org.springframework.boot.testsupport.classpath.resources.WithResource;
4444
import org.springframework.boot.web.servlet.DelegatingFilterProxyRegistrationBean;
45+
import org.springframework.boot.webmvc.autoconfigure.DispatcherServletPath;
4546
import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration;
4647
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
4748
import org.springframework.context.annotation.Bean;
@@ -52,11 +53,13 @@
5253
import org.springframework.security.authentication.DefaultAuthenticationEventPublisher;
5354
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
5455
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
56+
import org.springframework.security.config.web.PathPatternRequestMatcherBuilderFactoryBean;
5557
import org.springframework.security.core.Authentication;
5658
import org.springframework.security.core.AuthenticationException;
5759
import org.springframework.security.data.repository.query.SecurityEvaluationContextExtension;
5860
import org.springframework.security.web.FilterChainProxy;
5961
import org.springframework.security.web.SecurityFilterChain;
62+
import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher;
6063

6164
import static org.assertj.core.api.Assertions.assertThat;
6265

@@ -216,6 +219,24 @@ void whenTheBeanFactoryHasAConversionServiceAndAConfigurationPropertyBindingConv
216219
.run((context) -> assertThat(context.getBean(JwtProperties.class).getPublicKey()).isNotNull());
217220
}
218221

222+
@Test
223+
void whenDispatcherServletPathIsSetPathPatternRequestMatcherBuilderHasCustomBasePath() {
224+
this.contextRunner.withBean(DispatcherServletPath.class, () -> () -> "/dispatcher-servlet").run((context) -> {
225+
PathPatternRequestMatcher.Builder builder = context.getBean(PathPatternRequestMatcher.Builder.class);
226+
assertThat(builder).extracting("basePath").isEqualTo("/dispatcher-servlet");
227+
});
228+
}
229+
230+
@Test
231+
void givenACustomPathPatternRequestMatcherBuilderwhenDispatcherServletPathIsSetBuilderBasePathIsNotCustomized() {
232+
this.contextRunner.withBean(PathPatternRequestMatcherBuilderFactoryBean.class)
233+
.withBean(DispatcherServletPath.class, () -> () -> "/dispatcher-servlet")
234+
.run((context) -> {
235+
PathPatternRequestMatcher.Builder builder = context.getBean(PathPatternRequestMatcher.Builder.class);
236+
assertThat(builder).extracting("basePath").isEqualTo("");
237+
});
238+
}
239+
219240
@Configuration(proxyBeanMethods = false)
220241
@TestAutoConfigurationPackage(City.class)
221242
static class EntityConfiguration {

0 commit comments

Comments
 (0)