Skip to content

Commit 63e0a56

Browse files
committed
Add setBasePath
Originally, it was thought that this feature would be rather uncommon; however, given some feedback from the Boot team, it makes sense to make this easier to configure. Of specific note is migrating from an earlier version were the servlet path did not need to be specified in authorizeHttpRequests. Since it does in 7, this will be a significant migration for those who have a servlet path configured. This setter simplifies that a great deal, including simplifying Boot's support of it. Closes gh-17579
1 parent 15fc898 commit 63e0a56

File tree

2 files changed

+37
-2
lines changed

2 files changed

+37
-2
lines changed

config/src/main/java/org/springframework/security/config/web/PathPatternRequestMatcherBuilderFactoryBean.java

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ public final class PathPatternRequestMatcherBuilderFactoryBean implements
4646

4747
private final PathPatternParser parser;
4848

49+
private String basePath;
50+
4951
private ApplicationContext context;
5052

5153
private String beanName;
@@ -78,23 +80,43 @@ public PathPatternRequestMatcherBuilderFactoryBean(PathPatternParser parser) {
7880
public PathPatternRequestMatcher.Builder getObject() throws Exception {
7981
if (!this.context.containsBean(MVC_PATTERN_PARSER_BEAN_NAME)) {
8082
PathPatternParser parser = (this.parser != null) ? this.parser : PathPatternParser.defaultInstance;
81-
return PathPatternRequestMatcher.withPathPatternParser(parser);
83+
return withPathPatternParser(parser);
8284
}
8385
PathPatternParser mvc = this.context.getBean(MVC_PATTERN_PARSER_BEAN_NAME, PathPatternParser.class);
8486
PathPatternParser parser = (this.parser != null) ? this.parser : mvc;
8587
if (mvc.equals(parser)) {
86-
return PathPatternRequestMatcher.withPathPatternParser(parser);
88+
return withPathPatternParser(parser);
8789
}
8890
throw new IllegalArgumentException("Spring Security and Spring MVC must use the same path pattern parser. "
8991
+ "To have Spring Security use Spring MVC's [" + describe(mvc, MVC_PATTERN_PARSER_BEAN_NAME)
9092
+ "] simply publish this bean [" + describe(this, this.beanName) + "] using its default constructor");
9193
}
9294

95+
private PathPatternRequestMatcher.Builder withPathPatternParser(PathPatternParser parser) {
96+
if (this.basePath == null) {
97+
return PathPatternRequestMatcher.withPathPatternParser(parser);
98+
}
99+
else {
100+
return PathPatternRequestMatcher.withPathPatternParser(parser).basePath(this.basePath);
101+
}
102+
}
103+
93104
@Override
94105
public Class<?> getObjectType() {
95106
return PathPatternRequestMatcher.Builder.class;
96107
}
97108

109+
/**
110+
* Use this as the base path for patterns built by the resulting
111+
* {@link PathPatternRequestMatcher.Builder} instance
112+
* @param basePath the base path to use
113+
* @since 7.0
114+
* @see PathPatternRequestMatcher.Builder#basePath(String)
115+
*/
116+
public void setBasePath(String basePath) {
117+
this.basePath = basePath;
118+
}
119+
98120
@Override
99121
public void setApplicationContext(ApplicationContext context) throws BeansException {
100122
this.context = context;

config/src/test/java/org/springframework/security/config/web/PathPatternRequestMatcherBuilderFactoryBeanTests.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,11 @@
2222
import org.mockito.junit.jupiter.MockitoExtension;
2323

2424
import org.springframework.context.support.GenericApplicationContext;
25+
import org.springframework.security.web.servlet.TestMockHttpServletRequests;
2526
import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher;
2627
import org.springframework.web.util.pattern.PathPatternParser;
2728

29+
import static org.assertj.core.api.Assertions.assertThat;
2830
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
2931
import static org.mockito.Mockito.mock;
3032
import static org.mockito.Mockito.verify;
@@ -75,6 +77,17 @@ void getObjectWhenMvcAndPathPatternParserAgreeThenUses() throws Exception {
7577
verify(mvc).parse("/path/**");
7678
}
7779

80+
@Test
81+
void getObjectWhenBasePathThenUses() throws Exception {
82+
PathPatternRequestMatcherBuilderFactoryBean factoryBean = new PathPatternRequestMatcherBuilderFactoryBean();
83+
factoryBean.setApplicationContext(this.context);
84+
factoryBean.setBasePath("/mvc");
85+
PathPatternRequestMatcher.Builder builder = factoryBean.getObject();
86+
PathPatternRequestMatcher matcher = builder.matcher("/path/**");
87+
assertThat(matcher.matches(TestMockHttpServletRequests.get("/mvc/path/123").build())).isTrue();
88+
assertThat(matcher.matches(TestMockHttpServletRequests.get("/path/123").build())).isFalse();
89+
}
90+
7891
PathPatternRequestMatcherBuilderFactoryBean factoryBean() {
7992
PathPatternRequestMatcherBuilderFactoryBean factoryBean = new PathPatternRequestMatcherBuilderFactoryBean();
8093
factoryBean.setApplicationContext(this.context);

0 commit comments

Comments
 (0)