1
0
mirror of synced 2026-08-04 09:17:02 +00:00

MvcRequestMatcher servletPath / JavaConfig

Issue: gh-3987
This commit is contained in:
Rob Winch
2016-07-21 00:40:43 -05:00
parent 050198e51b
commit 3befb1c8a6
22 changed files with 1302 additions and 62 deletions
@@ -16,11 +16,6 @@
package org.springframework.security.web.servlet.util.matcher;
import java.util.Collections;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.springframework.http.HttpMethod;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.security.web.util.matcher.RequestVariablesExtractor;
@@ -31,20 +26,32 @@ import org.springframework.web.servlet.handler.MatchableHandlerMapping;
import org.springframework.web.servlet.handler.RequestMatchResult;
import org.springframework.web.util.UrlPathHelper;
import javax.servlet.http.HttpServletRequest;
import java.util.Collections;
import java.util.Map;
/**
* A {@link RequestMatcher} that uses Spring MVC's {@link HandlerMappingIntrospector} to
* match the path and extract variables.
*
* <p>
* It is important to understand that Spring MVC's matching is relative to the servlet
* path. This means if you have mapped any servlet to a path that starts with "/" and is
* greater than one, you should also specify the {@link #setServletPath(String)}
* attribute to differentiate mappings.
* </p>
*
* @author Rob Winch
* @since 4.1.1
*/
public final class MvcRequestMatcher
public class MvcRequestMatcher
implements RequestMatcher, RequestVariablesExtractor {
private final DefaultMatcher defaultMatcher = new DefaultMatcher();
private final HandlerMappingIntrospector introspector;
private final String pattern;
private HttpMethod method;
private String servletPath;
public MvcRequestMatcher(HandlerMappingIntrospector introspector, String pattern) {
this.introspector = introspector;
@@ -56,6 +63,9 @@ public final class MvcRequestMatcher
if (this.method != null && !this.method.name().equals(request.getMethod())) {
return false;
}
if (this.servletPath != null && !this.servletPath.equals(request.getServletPath())) {
return false;
}
MatchableHandlerMapping mapping = getMapping(request);
if (mapping == null) {
return this.defaultMatcher.matches(request);
@@ -97,6 +107,24 @@ public final class MvcRequestMatcher
this.method = method;
}
/**
* The servlet path to match on. The default is undefined which means any servlet
* path.
*
* @param servletPath the servletPath to set
*/
public void setServletPath(String servletPath) {
this.servletPath = servletPath;
}
protected final String getServletPath() {
return this.servletPath;
}
protected final String getMvcPattern() {
return this.pattern;
}
private class DefaultMatcher implements RequestMatcher, RequestVariablesExtractor {
private final UrlPathHelper pathHelper = new UrlPathHelper();
@@ -124,4 +152,4 @@ public final class MvcRequestMatcher
return Collections.emptyMap();
}
}
}
}
@@ -108,6 +108,31 @@ public class MvcRequestMatcherTests {
assertThat(this.matcher.extractUriTemplateVariables(this.request)).isEmpty();
}
@Test
public void matchesServletPathTrue() throws Exception {
when(this.introspector.getMatchableHandlerMapping(this.request))
.thenReturn(this.mapping);
when(this.mapping.match(eq(this.request), this.pattern.capture()))
.thenReturn(this.result);
this.matcher.setServletPath("/spring");
this.request.setServletPath("/spring");
assertThat(this.matcher.matches(this.request)).isTrue();
assertThat(this.pattern.getValue()).isEqualTo("/path");
}
@Test
public void matchesServletPathFalse() throws Exception {
when(this.introspector.getMatchableHandlerMapping(this.request))
.thenReturn(this.mapping);
when(this.mapping.match(eq(this.request), this.pattern.capture()))
.thenReturn(this.result);
this.matcher.setServletPath("/spring");
this.request.setServletPath("/");
assertThat(this.matcher.matches(this.request)).isFalse();
}
@Test
public void matchesPathOnlyTrue() throws Exception {
when(this.introspector.getMatchableHandlerMapping(this.request))