mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-06-27 22:32:43 +00:00
AntPathRequestMatcher implements RequestVariableExtractor
Issue gh-3964
This commit is contained in:
parent
e4c13e3c0e
commit
9d50944cb2
@ -54,7 +54,6 @@ abstract class AbstractVariableEvaluationContextPostProcessor
|
|||||||
if (this.variables == null) {
|
if (this.variables == null) {
|
||||||
this.variables = extractVariables(request);
|
this.variables = extractVariables(request);
|
||||||
}
|
}
|
||||||
name = postProcessVariableName(name);
|
|
||||||
return this.variables.get(name);
|
return this.variables.get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,6 +62,4 @@ abstract class AbstractVariableEvaluationContextPostProcessor
|
|||||||
|
|
||||||
abstract Map<String, String> extractVariables(HttpServletRequest request);
|
abstract Map<String, String> extractVariables(HttpServletRequest request);
|
||||||
|
|
||||||
abstract String postProcessVariableName(String variableName);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -93,10 +93,6 @@ public final class ExpressionBasedFilterInvocationSecurityMetadataSource
|
|||||||
|
|
||||||
private static AbstractVariableEvaluationContextPostProcessor createPostProcessor(
|
private static AbstractVariableEvaluationContextPostProcessor createPostProcessor(
|
||||||
Object request) {
|
Object request) {
|
||||||
if (request instanceof AntPathRequestMatcher) {
|
|
||||||
return new AntPathMatcherEvaluationContextPostProcessor(
|
|
||||||
(AntPathRequestMatcher) request);
|
|
||||||
}
|
|
||||||
if (request instanceof RequestVariablesExtractor) {
|
if (request instanceof RequestVariablesExtractor) {
|
||||||
return new RequestVariablesExtractorEvaluationContextPostProcessor(
|
return new RequestVariablesExtractorEvaluationContextPostProcessor(
|
||||||
(RequestVariablesExtractor) request);
|
(RequestVariablesExtractor) request);
|
||||||
@ -117,11 +113,6 @@ public final class ExpressionBasedFilterInvocationSecurityMetadataSource
|
|||||||
Map<String, String> extractVariables(HttpServletRequest request) {
|
Map<String, String> extractVariables(HttpServletRequest request) {
|
||||||
return this.matcher.extractUriTemplateVariables(request);
|
return this.matcher.extractUriTemplateVariables(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
String postProcessVariableName(String variableName) {
|
|
||||||
return this.matcher.postProcessVariableName(variableName);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static class RequestVariablesExtractorEvaluationContextPostProcessor
|
static class RequestVariablesExtractorEvaluationContextPostProcessor
|
||||||
@ -137,11 +128,6 @@ public final class ExpressionBasedFilterInvocationSecurityMetadataSource
|
|||||||
Map<String, String> extractVariables(HttpServletRequest request) {
|
Map<String, String> extractVariables(HttpServletRequest request) {
|
||||||
return this.matcher.extractUriTemplateVariables(request);
|
return this.matcher.extractUriTemplateVariables(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
String postProcessVariableName(String variableName) {
|
|
||||||
return variableName;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,8 @@ import org.springframework.util.StringUtils;
|
|||||||
*
|
*
|
||||||
* @see org.springframework.util.AntPathMatcher
|
* @see org.springframework.util.AntPathMatcher
|
||||||
*/
|
*/
|
||||||
public final class AntPathRequestMatcher implements RequestMatcher {
|
public final class AntPathRequestMatcher
|
||||||
|
implements RequestMatcher, RequestVariablesExtractor {
|
||||||
private static final Log logger = LogFactory.getLog(AntPathRequestMatcher.class);
|
private static final Log logger = LogFactory.getLog(AntPathRequestMatcher.class);
|
||||||
private static final String MATCH_ALL = "/**";
|
private static final String MATCH_ALL = "/**";
|
||||||
|
|
||||||
@ -102,10 +103,6 @@ public final class AntPathRequestMatcher implements RequestMatcher {
|
|||||||
this.matcher = null;
|
this.matcher = null;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!caseSensitive) {
|
|
||||||
pattern = pattern.toLowerCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the pattern ends with {@code /**} and has no other wildcards or path
|
// If the pattern ends with {@code /**} and has no other wildcards or path
|
||||||
// variables, then optimize to a sub-path match
|
// variables, then optimize to a sub-path match
|
||||||
if (pattern.endsWith(MATCH_ALL)
|
if (pattern.endsWith(MATCH_ALL)
|
||||||
@ -113,10 +110,10 @@ public final class AntPathRequestMatcher implements RequestMatcher {
|
|||||||
&& pattern.indexOf('}') == -1)
|
&& pattern.indexOf('}') == -1)
|
||||||
&& pattern.indexOf("*") == pattern.length() - 2) {
|
&& pattern.indexOf("*") == pattern.length() - 2) {
|
||||||
this.matcher = new SubpathMatcher(
|
this.matcher = new SubpathMatcher(
|
||||||
pattern.substring(0, pattern.length() - 3));
|
pattern.substring(0, pattern.length() - 3), caseSensitive);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.matcher = new SpringAntMatcher(pattern);
|
this.matcher = new SpringAntMatcher(pattern, caseSensitive);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,6 +161,7 @@ public final class AntPathRequestMatcher implements RequestMatcher {
|
|||||||
return this.matcher.matches(url);
|
return this.matcher.matches(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Map<String, String> extractUriTemplateVariables(HttpServletRequest request) {
|
public Map<String, String> extractUriTemplateVariables(HttpServletRequest request) {
|
||||||
if (this.matcher == null || !matches(request)) {
|
if (this.matcher == null || !matches(request)) {
|
||||||
return Collections.emptyMap();
|
return Collections.emptyMap();
|
||||||
@ -172,10 +170,6 @@ public final class AntPathRequestMatcher implements RequestMatcher {
|
|||||||
return this.matcher.extractUriTemplateVariables(url);
|
return this.matcher.extractUriTemplateVariables(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String postProcessVariableName(String variableName) {
|
|
||||||
return this.caseSensitive ? variableName : variableName.toLowerCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getRequestPath(HttpServletRequest request) {
|
private String getRequestPath(HttpServletRequest request) {
|
||||||
String url = request.getServletPath();
|
String url = request.getServletPath();
|
||||||
|
|
||||||
@ -183,10 +177,6 @@ public final class AntPathRequestMatcher implements RequestMatcher {
|
|||||||
url += request.getPathInfo();
|
url += request.getPathInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.caseSensitive) {
|
|
||||||
url = url.toLowerCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,27 +243,29 @@ public final class AntPathRequestMatcher implements RequestMatcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static class SpringAntMatcher implements Matcher {
|
private static class SpringAntMatcher implements Matcher {
|
||||||
private static final AntPathMatcher antMatcher = createMatcher();
|
private final AntPathMatcher antMatcher;
|
||||||
|
|
||||||
private final String pattern;
|
private final String pattern;
|
||||||
|
|
||||||
private SpringAntMatcher(String pattern) {
|
private SpringAntMatcher(String pattern, boolean caseSensitive) {
|
||||||
this.pattern = pattern;
|
this.pattern = pattern;
|
||||||
|
this.antMatcher = createMatcher(caseSensitive);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean matches(String path) {
|
public boolean matches(String path) {
|
||||||
return antMatcher.match(this.pattern, path);
|
return this.antMatcher.match(this.pattern, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, String> extractUriTemplateVariables(String path) {
|
public Map<String, String> extractUriTemplateVariables(String path) {
|
||||||
return antMatcher.extractUriTemplateVariables(this.pattern, path);
|
return this.antMatcher.extractUriTemplateVariables(this.pattern, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static AntPathMatcher createMatcher() {
|
private static AntPathMatcher createMatcher(boolean caseSensitive) {
|
||||||
AntPathMatcher matcher = new AntPathMatcher();
|
AntPathMatcher matcher = new AntPathMatcher();
|
||||||
matcher.setTrimTokens(false);
|
matcher.setTrimTokens(false);
|
||||||
|
matcher.setCaseSensitive(caseSensitive);
|
||||||
return matcher;
|
return matcher;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -284,15 +276,20 @@ public final class AntPathRequestMatcher implements RequestMatcher {
|
|||||||
private static class SubpathMatcher implements Matcher {
|
private static class SubpathMatcher implements Matcher {
|
||||||
private final String subpath;
|
private final String subpath;
|
||||||
private final int length;
|
private final int length;
|
||||||
|
private final boolean caseSensitive;
|
||||||
|
|
||||||
private SubpathMatcher(String subpath) {
|
private SubpathMatcher(String subpath, boolean caseSensitive) {
|
||||||
assert!subpath.contains("*");
|
assert!subpath.contains("*");
|
||||||
this.subpath = subpath;
|
this.subpath = caseSensitive ? subpath : subpath.toLowerCase();
|
||||||
this.length = subpath.length();
|
this.length = subpath.length();
|
||||||
|
this.caseSensitive = caseSensitive;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean matches(String path) {
|
public boolean matches(String path) {
|
||||||
|
if (!this.caseSensitive) {
|
||||||
|
path = path.toLowerCase();
|
||||||
|
}
|
||||||
return path.startsWith(this.subpath)
|
return path.startsWith(this.subpath)
|
||||||
&& (path.length() == this.length || path.charAt(this.length) == '/');
|
&& (path.length() == this.length || path.charAt(this.length) == '/');
|
||||||
}
|
}
|
||||||
|
@ -65,13 +65,6 @@ public class AbstractVariableEvaluationContextPostProcessorTests {
|
|||||||
assertThat(this.context.lookupVariable(KEY)).isEqualTo(VALUE);
|
assertThat(this.context.lookupVariable(KEY)).isEqualTo(VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void postProcessVariableName() {
|
|
||||||
this.context = this.processor.postProcess(this.context, this.invocation);
|
|
||||||
|
|
||||||
assertThat(this.context.lookupVariable("nothing")).isEqualTo(VALUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void extractVariablesOnlyUsedOnce() {
|
public void extractVariablesOnlyUsedOnce() {
|
||||||
this.context = this.processor.postProcess(this.context, this.invocation);
|
this.context = this.processor.postProcess(this.context, this.invocation);
|
||||||
@ -89,10 +82,5 @@ public class AbstractVariableEvaluationContextPostProcessorTests {
|
|||||||
protected Map<String, String> extractVariables(HttpServletRequest request) {
|
protected Map<String, String> extractVariables(HttpServletRequest request) {
|
||||||
return this.results;
|
return this.results;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
String postProcessVariableName(String variableName) {
|
|
||||||
return KEY;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -210,21 +210,6 @@ public class AntPathRequestMatcherTests {
|
|||||||
assertThat(matcher.matches(request)).isFalse();
|
assertThat(matcher.matches(request)).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void postProcessVariableNameCaseInsensitive() {
|
|
||||||
AntPathRequestMatcher matcher = new AntPathRequestMatcher("/**", null, false);
|
|
||||||
String variableName = "userName";
|
|
||||||
assertThat(matcher.postProcessVariableName(variableName))
|
|
||||||
.isEqualTo(variableName.toLowerCase());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void postProcessVariableNameCaseSensitive() {
|
|
||||||
AntPathRequestMatcher matcher = new AntPathRequestMatcher("/**", null, true);
|
|
||||||
String variableName = "userName";
|
|
||||||
assertThat(matcher.postProcessVariableName(variableName)).isEqualTo(variableName);
|
|
||||||
}
|
|
||||||
|
|
||||||
private HttpServletRequest createRequestWithNullMethod(String path) {
|
private HttpServletRequest createRequestWithNullMethod(String path) {
|
||||||
when(this.request.getQueryString()).thenReturn("doesntMatter");
|
when(this.request.getQueryString()).thenReturn("doesntMatter");
|
||||||
when(this.request.getServletPath()).thenReturn(path);
|
when(this.request.getServletPath()).thenReturn(path);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user