Add match result for servlet requests

Fixes gh-7148
This commit is contained in:
Eddú Meléndez 2019-07-25 21:15:21 -05:00 committed by Josh Cummings
parent 2c836a171a
commit 496579dde2
7 changed files with 104 additions and 16 deletions

View File

@ -50,6 +50,7 @@ import java.util.Map;
* *
* @author Joe Grandja * @author Joe Grandja
* @author Rob Winch * @author Rob Winch
* @author Eddú Meléndez
* @since 5.1 * @since 5.1
* @see OAuth2AuthorizationRequestResolver * @see OAuth2AuthorizationRequestResolver
* @see OAuth2AuthorizationRequestRedirectFilter * @see OAuth2AuthorizationRequestRedirectFilter
@ -147,7 +148,7 @@ public final class DefaultOAuth2AuthorizationRequestResolver implements OAuth2Au
private String resolveRegistrationId(HttpServletRequest request) { private String resolveRegistrationId(HttpServletRequest request) {
if (this.authorizationRequestMatcher.matches(request)) { if (this.authorizationRequestMatcher.matches(request)) {
return this.authorizationRequestMatcher return this.authorizationRequestMatcher
.extractUriTemplateVariables(request).get(REGISTRATION_ID_URI_VARIABLE_NAME); .matcher(request).getVariables().get(REGISTRATION_ID_URI_VARIABLE_NAME);
} }
return null; return null;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2018 the original author or authors. * Copyright 2002-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -40,6 +40,7 @@ import org.springframework.util.Assert;
* Expression-based {@code FilterInvocationSecurityMetadataSource}. * Expression-based {@code FilterInvocationSecurityMetadataSource}.
* *
* @author Luke Taylor * @author Luke Taylor
* @author Eddú Meléndez
* @since 3.0 * @since 3.0
*/ */
public final class ExpressionBasedFilterInvocationSecurityMetadataSource public final class ExpressionBasedFilterInvocationSecurityMetadataSource
@ -111,7 +112,7 @@ public final class ExpressionBasedFilterInvocationSecurityMetadataSource
@Override @Override
Map<String, String> extractVariables(HttpServletRequest request) { Map<String, String> extractVariables(HttpServletRequest request) {
return this.matcher.extractUriTemplateVariables(request); return this.matcher.matcher(request).getVariables();
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2016 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,7 +16,6 @@
package org.springframework.security.web.servlet.util.matcher; package org.springframework.security.web.servlet.util.matcher;
import java.util.Collections;
import java.util.Map; import java.util.Map;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@ -43,6 +42,7 @@ import org.springframework.web.util.UrlPathHelper;
* </p> * </p>
* *
* @author Rob Winch * @author Rob Winch
* @author Eddú Meléndez
* @since 4.1.1 * @since 4.1.1
*/ */
public class MvcRequestMatcher implements RequestMatcher, RequestVariablesExtractor { public class MvcRequestMatcher implements RequestMatcher, RequestVariablesExtractor {
@ -93,13 +93,18 @@ public class MvcRequestMatcher implements RequestMatcher, RequestVariablesExtrac
*/ */
@Override @Override
public Map<String, String> extractUriTemplateVariables(HttpServletRequest request) { public Map<String, String> extractUriTemplateVariables(HttpServletRequest request) {
return matcher(request).getVariables();
}
@Override
public MatchResult matcher(HttpServletRequest request) {
MatchableHandlerMapping mapping = getMapping(request); MatchableHandlerMapping mapping = getMapping(request);
if (mapping == null) { if (mapping == null) {
return this.defaultMatcher.extractUriTemplateVariables(request); return this.defaultMatcher.matcher(request);
} }
RequestMatchResult result = mapping.match(request, this.pattern); RequestMatchResult result = mapping.match(request, this.pattern);
return result == null ? Collections.<String, String>emptyMap() return result == null ? MatchResult.notMatch()
: result.extractUriTemplateVariables(); : MatchResult.match(result.extractUriTemplateVariables());
} }
/** /**
@ -160,12 +165,18 @@ public class MvcRequestMatcher implements RequestMatcher, RequestVariablesExtrac
@Override @Override
public Map<String, String> extractUriTemplateVariables( public Map<String, String> extractUriTemplateVariables(
HttpServletRequest request) { HttpServletRequest request) {
return matcher(request).getVariables();
}
@Override
public MatchResult matcher(HttpServletRequest request) {
String lookupPath = this.pathHelper.getLookupPathForRequest(request); String lookupPath = this.pathHelper.getLookupPathForRequest(request);
if (matches(lookupPath)) { if (matches(lookupPath)) {
return this.pathMatcher.extractUriTemplateVariables( Map<String, String> variables = this.pathMatcher.extractUriTemplateVariables(
MvcRequestMatcher.this.pattern, lookupPath); MvcRequestMatcher.this.pattern, lookupPath);
return MatchResult.match(variables);
} }
return Collections.emptyMap(); return MatchResult.notMatch();
} }
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2018 the original author or authors. * Copyright 2002-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -49,6 +49,7 @@ import org.springframework.web.util.UrlPathHelper;
* *
* @author Luke Taylor * @author Luke Taylor
* @author Rob Winch * @author Rob Winch
* @author Eddú Meléndez
* @since 3.1 * @since 3.1
* *
* @see org.springframework.util.AntPathMatcher * @see org.springframework.util.AntPathMatcher
@ -182,11 +183,16 @@ public final class AntPathRequestMatcher
@Override @Override
public Map<String, String> extractUriTemplateVariables(HttpServletRequest request) { public Map<String, String> extractUriTemplateVariables(HttpServletRequest request) {
return matcher(request).getVariables();
}
@Override
public MatchResult matcher(HttpServletRequest request) {
if (this.matcher == null || !matches(request)) { if (this.matcher == null || !matches(request)) {
return Collections.emptyMap(); return MatchResult.notMatch();
} }
String url = getRequestPath(request); String url = getRequestPath(request);
return this.matcher.extractUriTemplateVariables(url); return MatchResult.match(this.matcher.extractUriTemplateVariables(url));
} }
private String getRequestPath(HttpServletRequest request) { private String getRequestPath(HttpServletRequest request) {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2016 the original author or authors. * Copyright 2002-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -15,12 +15,16 @@
*/ */
package org.springframework.security.web.util.matcher; package org.springframework.security.web.util.matcher;
import java.util.Collections;
import java.util.Map;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
/** /**
* Simple strategy to match an <tt>HttpServletRequest</tt>. * Simple strategy to match an <tt>HttpServletRequest</tt>.
* *
* @author Luke Taylor * @author Luke Taylor
* @author Eddú Meléndez
* @since 3.0.2 * @since 3.0.2
*/ */
public interface RequestMatcher { public interface RequestMatcher {
@ -33,4 +37,61 @@ public interface RequestMatcher {
*/ */
boolean matches(HttpServletRequest request); boolean matches(HttpServletRequest request);
/**
* @since 5.2
*/
default MatchResult matcher(HttpServletRequest request) {
boolean match = matches(request);
return new MatchResult(match, Collections.emptyMap());
}
/**
* The result of matching
*/
class MatchResult {
private final boolean match;
private final Map<String, String> variables;
MatchResult(boolean match, Map<String, String> variables) {
this.match = match;
this.variables = variables;
}
public boolean isMatch() {
return this.match;
}
public Map<String, String> getVariables() {
return this.variables;
}
/**
* Creates an instance of {@link MatchResult} that is a match with no variables
*
* @return
*/
public static MatchResult match() {
return new MatchResult(true, Collections.emptyMap());
}
/**
* Creates an instance of {@link MatchResult} that is a match with the specified variables
*
* @param variables
* @return
*/
public static MatchResult match(Map<String, String> variables) {
return new MatchResult(true, variables);
}
/**
* Creates an instance of {@link MatchResult} that is not a match.
*
* @return
*/
public static MatchResult notMatch() {
return new MatchResult(false, Collections.emptyMap());
}
}
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2016 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -25,6 +25,7 @@ import javax.servlet.http.HttpServletRequest;
* *
* @author Rob Winch * @author Rob Winch
* @since 4.1.1 * @since 4.1.1
* @deprecated
*/ */
public interface RequestVariablesExtractor { public interface RequestVariablesExtractor {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2016 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -40,6 +40,7 @@ import static org.mockito.Mockito.when;
/** /**
* @author Rob Winch * @author Rob Winch
* @author Eddú Meléndez
*/ */
@RunWith(MockitoJUnitRunner.class) @RunWith(MockitoJUnitRunner.class)
public class MvcRequestMatcherTests { public class MvcRequestMatcherTests {
@ -73,6 +74,8 @@ public class MvcRequestMatcherTests {
assertThat(this.matcher.extractUriTemplateVariables(this.request)) assertThat(this.matcher.extractUriTemplateVariables(this.request))
.containsEntry("p", "path"); .containsEntry("p", "path");
assertThat(this.matcher.matcher(this.request).getVariables())
.containsEntry("p", "path");
} }
@Test @Test
@ -85,6 +88,7 @@ public class MvcRequestMatcherTests {
.thenReturn(this.result); .thenReturn(this.result);
assertThat(this.matcher.extractUriTemplateVariables(this.request)).isEmpty(); assertThat(this.matcher.extractUriTemplateVariables(this.request)).isEmpty();
assertThat(this.matcher.matcher(this.request).getVariables()).isEmpty();
} }
@Test @Test
@ -94,6 +98,8 @@ public class MvcRequestMatcherTests {
assertThat(this.matcher.extractUriTemplateVariables(this.request)) assertThat(this.matcher.extractUriTemplateVariables(this.request))
.containsEntry("p", "path"); .containsEntry("p", "path");
assertThat(this.matcher.matcher(this.request).getVariables())
.containsEntry("p", "path");
} }
@Test @Test
@ -102,6 +108,7 @@ public class MvcRequestMatcherTests {
when(this.introspector.getMatchableHandlerMapping(this.request)).thenReturn(null); when(this.introspector.getMatchableHandlerMapping(this.request)).thenReturn(null);
assertThat(this.matcher.extractUriTemplateVariables(this.request)).isEmpty(); assertThat(this.matcher.extractUriTemplateVariables(this.request)).isEmpty();
assertThat(this.matcher.matcher(this.request).getVariables()).isEmpty();
} }
@Test @Test