2
0
Эх сурвалжийг харах

Use AuthorizationManager in <http>

Closes gh-11305
Josh Cummings 3 жил өмнө
parent
commit
2afa9313eb
24 өөрчлөгдсөн 1013 нэмэгдсэн , 1 устгасан
  1. 180 0
      config/src/main/java/org/springframework/security/config/http/AuthorizationFilterParser.java
  2. 35 1
      config/src/main/java/org/springframework/security/config/http/HttpConfigurationBuilder.java
  3. 6 0
      config/src/main/resources/org/springframework/security/config/spring-security-5.8.rnc
  4. 12 0
      config/src/main/resources/org/springframework/security/config/spring-security-5.8.xsd
  5. 6 0
      config/src/main/resources/org/springframework/security/config/spring-security-6.0.rnc
  6. 12 0
      config/src/main/resources/org/springframework/security/config/spring-security-6.0.xsd
  7. 30 0
      config/src/test/java/org/springframework/security/config/http/HttpConfigTests.java
  8. 183 0
      config/src/test/java/org/springframework/security/config/http/InterceptUrlConfigTests.java
  9. 36 0
      config/src/test/resources/org/springframework/security/config/http/HttpConfigTests-AuthorizationManager.xml
  10. 32 0
      config/src/test/resources/org/springframework/security/config/http/HttpConfigTests-MinimalAuthorizationManager.xml
  11. 33 0
      config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-AntMatcherServletPathAuthorizationManager.xml
  12. 36 0
      config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-CamelCasePathVariablesAuthorizationManager.xml
  13. 33 0
      config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-CiRegexMatcherServletPathAuthorizationManager.xml
  14. 33 0
      config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-DefaultMatcherServletPathAuthorizationManager.xml
  15. 35 0
      config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-HasAnyRoleAuthorizationManager.xml
  16. 42 0
      config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-MvcMatchersAuthorizationManager.xml
  17. 41 0
      config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-MvcMatchersPathVariablesAuthorizationManager.xml
  18. 42 0
      config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-MvcMatchersServletPathAuthorizationManager.xml
  19. 36 0
      config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-PatchMethodAuthorizationManager.xml
  20. 36 0
      config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-PathVariablesAuthorizationManager.xml
  21. 33 0
      config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-RegexMatcherServletPathAuthorizationManager.xml
  22. 37 0
      config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-Sec2256AuthorizationManager.xml
  23. 37 0
      config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-TypeConversionPathVariablesAuthorizationManager.xml
  24. 7 0
      docs/modules/ROOT/pages/servlet/appendix/namespace/http.adoc

+ 180 - 0
config/src/main/java/org/springframework/security/config/http/AuthorizationFilterParser.java

@@ -0,0 +1,180 @@
+/*
+ * Copyright 2002-2016 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.security.config.http;
+
+import java.util.List;
+import java.util.Map;
+
+import jakarta.servlet.http.HttpServletRequest;
+import org.w3c.dom.Element;
+
+import org.springframework.beans.BeanMetadataElement;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.RuntimeBeanReference;
+import org.springframework.beans.factory.parsing.BeanComponentDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.support.ManagedMap;
+import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
+import org.springframework.beans.factory.xml.BeanDefinitionParser;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.beans.factory.xml.XmlReaderContext;
+import org.springframework.security.authorization.AuthenticatedAuthorizationManager;
+import org.springframework.security.authorization.AuthorizationManager;
+import org.springframework.security.config.Elements;
+import org.springframework.security.web.access.expression.DefaultHttpSecurityExpressionHandler;
+import org.springframework.security.web.access.expression.WebExpressionAuthorizationManager;
+import org.springframework.security.web.access.intercept.AuthorizationFilter;
+import org.springframework.security.web.access.intercept.RequestAuthorizationContext;
+import org.springframework.security.web.access.intercept.RequestMatcherDelegatingAuthorizationManager;
+import org.springframework.security.web.util.matcher.AnyRequestMatcher;
+import org.springframework.security.web.util.matcher.RequestMatcher;
+import org.springframework.util.StringUtils;
+import org.springframework.util.xml.DomUtils;
+
+class AuthorizationFilterParser implements BeanDefinitionParser {
+
+	private static final String ATT_USE_EXPRESSIONS = "use-expressions";
+
+	private static final String ATT_HTTP_METHOD = "method";
+
+	private static final String ATT_PATTERN = "pattern";
+
+	private static final String ATT_ACCESS = "access";
+
+	private static final String ATT_SERVLET_PATH = "servlet-path";
+
+	private String authorizationManagerRef;
+
+	@Override
+	public BeanDefinition parse(Element element, ParserContext parserContext) {
+		if (!isUseExpressions(element)) {
+			parserContext.getReaderContext().error("AuthorizationManager must be used with `use-expressions=\"true\"",
+					element);
+			return null;
+		}
+		this.authorizationManagerRef = createAuthorizationManager(element, parserContext);
+		BeanDefinitionBuilder filterBuilder = BeanDefinitionBuilder.rootBeanDefinition(AuthorizationFilter.class);
+		filterBuilder.getRawBeanDefinition().setSource(parserContext.extractSource(element));
+		BeanDefinition filter = filterBuilder.addConstructorArgReference(this.authorizationManagerRef)
+				.getBeanDefinition();
+		String id = element.getAttribute(AbstractBeanDefinitionParser.ID_ATTRIBUTE);
+		if (StringUtils.hasText(id)) {
+			parserContext.registerComponent(new BeanComponentDefinition(filter, id));
+			parserContext.getRegistry().registerBeanDefinition(id, filter);
+		}
+		return filter;
+	}
+
+	String getAuthorizationManagerRef() {
+		return this.authorizationManagerRef;
+	}
+
+	private String createAuthorizationManager(Element element, ParserContext parserContext) {
+		XmlReaderContext context = parserContext.getReaderContext();
+		String authorizationManagerRef = element.getAttribute("authorization-manager-ref");
+		if (StringUtils.hasText(authorizationManagerRef)) {
+			return authorizationManagerRef;
+		}
+		Element expressionHandlerElt = DomUtils.getChildElementByTagName(element, Elements.EXPRESSION_HANDLER);
+		String expressionHandlerRef = (expressionHandlerElt != null) ? expressionHandlerElt.getAttribute("ref") : null;
+		if (expressionHandlerRef == null) {
+			expressionHandlerRef = registerDefaultExpressionHandler(parserContext);
+		}
+		MatcherType matcherType = MatcherType.fromElement(element);
+		ManagedMap<BeanMetadataElement, BeanDefinition> matcherToExpression = new ManagedMap<>();
+		List<Element> interceptMessages = DomUtils.getChildElementsByTagName(element, Elements.INTERCEPT_URL);
+		for (Element interceptMessage : interceptMessages) {
+			String accessExpression = interceptMessage.getAttribute(ATT_ACCESS);
+			BeanDefinitionBuilder authorizationManager = BeanDefinitionBuilder
+					.rootBeanDefinition(WebExpressionAuthorizationManager.class);
+			authorizationManager.addPropertyReference("expressionHandler", expressionHandlerRef);
+			authorizationManager.addConstructorArgValue(accessExpression);
+			BeanMetadataElement matcher = createMatcher(matcherType, interceptMessage, parserContext);
+			matcherToExpression.put(matcher, authorizationManager.getBeanDefinition());
+		}
+		BeanDefinitionBuilder mds = BeanDefinitionBuilder
+				.rootBeanDefinition(RequestMatcherDelegatingAuthorizationManagerFactory.class);
+		mds.setFactoryMethod("createRequestMatcherDelegatingAuthorizationManager");
+		mds.addConstructorArgValue(matcherToExpression);
+		return context.registerWithGeneratedName(mds.getBeanDefinition());
+	}
+
+	private BeanMetadataElement createMatcher(MatcherType matcherType, Element urlElt, ParserContext parserContext) {
+		String path = urlElt.getAttribute(ATT_PATTERN);
+		String matcherRef = urlElt.getAttribute(HttpSecurityBeanDefinitionParser.ATT_REQUEST_MATCHER_REF);
+		boolean hasMatcherRef = StringUtils.hasText(matcherRef);
+		if (!hasMatcherRef && !StringUtils.hasText(path)) {
+			parserContext.getReaderContext().error("path attribute cannot be empty or null", urlElt);
+		}
+		String method = urlElt.getAttribute(ATT_HTTP_METHOD);
+		if (!StringUtils.hasText(method)) {
+			method = null;
+		}
+		String servletPath = urlElt.getAttribute(ATT_SERVLET_PATH);
+		if (!StringUtils.hasText(servletPath)) {
+			servletPath = null;
+		}
+		else if (!MatcherType.mvc.equals(matcherType)) {
+			parserContext.getReaderContext().error(
+					ATT_SERVLET_PATH + " is not applicable for request-matcher: '" + matcherType.name() + "'", urlElt);
+		}
+		return hasMatcherRef ? new RuntimeBeanReference(matcherRef)
+				: matcherType.createMatcher(parserContext, path, method, servletPath);
+	}
+
+	String registerDefaultExpressionHandler(ParserContext pc) {
+		BeanDefinition expressionHandler = GrantedAuthorityDefaultsParserUtils.registerWithDefaultRolePrefix(pc,
+				DefaultWebSecurityExpressionHandlerBeanFactory.class);
+		String expressionHandlerRef = pc.getReaderContext().generateBeanName(expressionHandler);
+		pc.registerBeanComponent(new BeanComponentDefinition(expressionHandler, expressionHandlerRef));
+		return expressionHandlerRef;
+	}
+
+	boolean isUseExpressions(Element elt) {
+		String useExpressions = elt.getAttribute(ATT_USE_EXPRESSIONS);
+		return !StringUtils.hasText(useExpressions) || "true".equals(useExpressions);
+	}
+
+	private static class RequestMatcherDelegatingAuthorizationManagerFactory {
+
+		private static AuthorizationManager<HttpServletRequest> createRequestMatcherDelegatingAuthorizationManager(
+				Map<RequestMatcher, AuthorizationManager<RequestAuthorizationContext>> beans) {
+			RequestMatcherDelegatingAuthorizationManager.Builder builder = RequestMatcherDelegatingAuthorizationManager
+					.builder();
+			for (Map.Entry<RequestMatcher, AuthorizationManager<RequestAuthorizationContext>> entry : beans
+					.entrySet()) {
+				builder.add(entry.getKey(), entry.getValue());
+			}
+			return builder.add(AnyRequestMatcher.INSTANCE, AuthenticatedAuthorizationManager.authenticated()).build();
+		}
+
+	}
+
+	static class DefaultWebSecurityExpressionHandlerBeanFactory
+			extends GrantedAuthorityDefaultsParserUtils.AbstractGrantedAuthorityDefaultsBeanFactory {
+
+		private DefaultHttpSecurityExpressionHandler handler = new DefaultHttpSecurityExpressionHandler();
+
+		@Override
+		public DefaultHttpSecurityExpressionHandler getBean() {
+			this.handler.setDefaultRolePrefix(this.rolePrefix);
+			return this.handler;
+		}
+
+	}
+
+}

+ 35 - 1
config/src/main/java/org/springframework/security/config/http/HttpConfigurationBuilder.java

@@ -40,6 +40,7 @@ import org.springframework.security.access.vote.RoleVoter;
 import org.springframework.security.config.Elements;
 import org.springframework.security.config.http.GrantedAuthorityDefaultsParserUtils.AbstractGrantedAuthorityDefaultsBeanFactory;
 import org.springframework.security.core.session.SessionRegistryImpl;
+import org.springframework.security.web.access.AuthorizationManagerWebInvocationPrivilegeEvaluator;
 import org.springframework.security.web.access.DefaultWebInvocationPrivilegeEvaluator;
 import org.springframework.security.web.access.channel.ChannelDecisionManagerImpl;
 import org.springframework.security.web.access.channel.ChannelProcessingFilter;
@@ -112,6 +113,10 @@ class HttpConfigurationBuilder {
 
 	private static final String ATT_DISABLE_URL_REWRITING = "disable-url-rewriting";
 
+	private static final String ATT_USE_AUTHORIZATION_MGR = "use-authorization-manager";
+
+	private static final String ATT_AUTHORIZATION_MGR = "authorization-manager-ref";
+
 	private static final String ATT_ACCESS_MGR = "access-decision-manager-ref";
 
 	private static final String ATT_ONCE_PER_REQUEST = "once-per-request";
@@ -219,7 +224,7 @@ class HttpConfigurationBuilder {
 		createServletApiFilter(authenticationManager);
 		createJaasApiFilter();
 		createChannelProcessingFilter();
-		createFilterSecurityInterceptor(authenticationManager);
+		createFilterSecurity(authenticationManager);
 		createAddHeadersFilter();
 		createCorsFilter();
 		createWellKnownChangePasswordRedirectFilter();
@@ -674,6 +679,35 @@ class HttpConfigurationBuilder {
 		this.requestCacheAwareFilter.getConstructorArgumentValues().addGenericArgumentValue(this.requestCache);
 	}
 
+	private void createFilterSecurity(BeanReference authManager) {
+		boolean useAuthorizationManager = Boolean.parseBoolean(this.httpElt.getAttribute(ATT_USE_AUTHORIZATION_MGR));
+		if (useAuthorizationManager) {
+			createAuthorizationFilter();
+			return;
+		}
+		if (StringUtils.hasText(this.httpElt.getAttribute(ATT_AUTHORIZATION_MGR))) {
+			createAuthorizationFilter();
+			return;
+		}
+		createFilterSecurityInterceptor(authManager);
+	}
+
+	private void createAuthorizationFilter() {
+		AuthorizationFilterParser authorizationFilterParser = new AuthorizationFilterParser();
+		BeanDefinition fsiBean = authorizationFilterParser.parse(this.httpElt, this.pc);
+		String fsiId = this.pc.getReaderContext().generateBeanName(fsiBean);
+		this.pc.registerBeanComponent(new BeanComponentDefinition(fsiBean, fsiId));
+		// Create and register a AuthorizationManagerWebInvocationPrivilegeEvaluator for
+		// use with
+		// taglibs etc.
+		BeanDefinition wipe = BeanDefinitionBuilder
+				.rootBeanDefinition(AuthorizationManagerWebInvocationPrivilegeEvaluator.class)
+				.addConstructorArgReference(authorizationFilterParser.getAuthorizationManagerRef()).getBeanDefinition();
+		this.pc.registerBeanComponent(
+				new BeanComponentDefinition(wipe, this.pc.getReaderContext().generateBeanName(wipe)));
+		this.fsi = new RuntimeBeanReference(fsiId);
+	}
+
 	private void createFilterSecurityInterceptor(BeanReference authManager) {
 		boolean useExpressions = FilterInvocationSecurityMetadataSourceParser.isUseExpressions(this.httpElt);
 		RootBeanDefinition securityMds = FilterInvocationSecurityMetadataSourceParser

+ 6 - 0
config/src/main/resources/org/springframework/security/config/spring-security-5.8.rnc

@@ -350,6 +350,12 @@ http.attlist &=
 http.attlist &=
 	## If available, runs the request as the Subject acquired from the JaasAuthenticationToken. Defaults to "false".
 	attribute jaas-api-provision {xsd:boolean}?
+http.attlist &=
+	## Use AuthorizationManager API instead of SecurityMetadataSource
+	attribute use-authorization-manager {xsd:boolean}?
+http.attlist &=
+	## Use this AuthorizationManager instead of deriving one from <intercept-url> elements
+	attribute authorization-manager-ref {xsd:token}?
 http.attlist &=
 	## Optional attribute specifying the ID of the AccessDecisionManager implementation which should be used for authorizing HTTP requests.
 	attribute access-decision-manager-ref {xsd:token}?

+ 12 - 0
config/src/main/resources/org/springframework/security/config/spring-security-5.8.xsd

@@ -1287,6 +1287,18 @@
                 </xs:documentation>
          </xs:annotation>
       </xs:attribute>
+      <xs:attribute name="use-authorization-manager" type="xs:boolean">
+         <xs:annotation>
+            <xs:documentation>Use AuthorizationManager API instead of SecurityMetadataSource
+                </xs:documentation>
+         </xs:annotation>
+      </xs:attribute>
+      <xs:attribute name="authorization-manager-ref" type="xs:token">
+         <xs:annotation>
+            <xs:documentation>Use this AuthorizationManager instead of deriving one from &lt;intercept-url&gt; elements
+                </xs:documentation>
+         </xs:annotation>
+      </xs:attribute>
       <xs:attribute name="access-decision-manager-ref" type="xs:token">
          <xs:annotation>
             <xs:documentation>Optional attribute specifying the ID of the AccessDecisionManager implementation which

+ 6 - 0
config/src/main/resources/org/springframework/security/config/spring-security-6.0.rnc

@@ -350,6 +350,12 @@ http.attlist &=
 http.attlist &=
 	## If available, runs the request as the Subject acquired from the JaasAuthenticationToken. Defaults to "false".
 	attribute jaas-api-provision {xsd:boolean}?
+http.attlist &=
+	## Use AuthorizationManager API instead of SecurityMetadataSource
+	attribute use-authorization-manager {xsd:boolean}?
+http.attlist &=
+	## Use this AuthorizationManager instead of deriving one from <intercept-url> elements
+	attribute authorization-manager-ref {xsd:token}?
 http.attlist &=
 	## Optional attribute specifying the ID of the AccessDecisionManager implementation which should be used for authorizing HTTP requests.
 	attribute access-decision-manager-ref {xsd:token}?

+ 12 - 0
config/src/main/resources/org/springframework/security/config/spring-security-6.0.xsd

@@ -1265,6 +1265,18 @@
                 </xs:documentation>
          </xs:annotation>
       </xs:attribute>
+      <xs:attribute name="use-authorization-manager" type="xs:boolean">
+         <xs:annotation>
+            <xs:documentation>Use AuthorizationManager API instead of SecurityMetadataSource
+                </xs:documentation>
+         </xs:annotation>
+      </xs:attribute>
+      <xs:attribute name="authorization-manager-ref" type="xs:token">
+         <xs:annotation>
+            <xs:documentation>Use this AuthorizationManager instead of deriving one from &lt;intercept-url&gt; elements
+                </xs:documentation>
+         </xs:annotation>
+      </xs:attribute>
       <xs:attribute name="access-decision-manager-ref" type="xs:token">
          <xs:annotation>
             <xs:documentation>Optional attribute specifying the ID of the AccessDecisionManager implementation which

+ 30 - 0
config/src/test/java/org/springframework/security/config/http/HttpConfigTests.java

@@ -16,6 +16,7 @@
 
 package org.springframework.security.config.http;
 
+import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
 import jakarta.servlet.http.HttpServletResponseWrapper;
 import org.apache.http.HttpStatus;
@@ -25,12 +26,17 @@ import org.junit.jupiter.api.extension.ExtendWith;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.mock.web.MockHttpServletRequest;
 import org.springframework.mock.web.MockHttpServletResponse;
+import org.springframework.security.authorization.AuthorizationDecision;
+import org.springframework.security.authorization.AuthorizationManager;
 import org.springframework.security.config.test.SpringTestContext;
 import org.springframework.security.config.test.SpringTestContextExtension;
 import org.springframework.security.web.FilterChainProxy;
 import org.springframework.test.web.servlet.MockMvc;
 
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.BDDMockito.given;
+import static org.mockito.Mockito.verify;
 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl;
 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@@ -59,6 +65,30 @@ public class HttpConfigTests {
 		// @formatter:on
 	}
 
+	@Test
+	public void getWhenUsingMinimalAuthorizationManagerThenRedirectsToLogin() throws Exception {
+		this.spring.configLocations(this.xml("MinimalAuthorizationManager")).autowire();
+		// @formatter:off
+		this.mvc.perform(get("/"))
+				.andExpect(status().isFound())
+				.andExpect(redirectedUrl("http://localhost/login"));
+		// @formatter:on
+	}
+
+	@Test
+	public void getWhenUsingAuthorizationManagerThenRedirectsToLogin() throws Exception {
+		this.spring.configLocations(this.xml("AuthorizationManager")).autowire();
+		AuthorizationManager<HttpServletRequest> authorizationManager = this.spring.getContext()
+				.getBean(AuthorizationManager.class);
+		given(authorizationManager.check(any(), any())).willReturn(new AuthorizationDecision(false));
+		// @formatter:off
+		this.mvc.perform(get("/"))
+				.andExpect(status().isFound())
+				.andExpect(redirectedUrl("http://localhost/login"));
+		// @formatter:on
+		verify(authorizationManager).check(any(), any());
+	}
+
 	@Test
 	public void getWhenUsingMinimalConfigurationThenPreventsSessionAsUrlParameter() throws Exception {
 		this.spring.configLocations(this.xml("Minimal")).autowire();

+ 183 - 0
config/src/test/java/org/springframework/security/config/http/InterceptUrlConfigTests.java

@@ -27,8 +27,10 @@ import org.mockito.stubbing.Answer;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
 import org.springframework.mock.web.MockServletContext;
+import org.springframework.security.authorization.AuthorizationManager;
 import org.springframework.security.config.test.SpringTestContext;
 import org.springframework.security.config.test.SpringTestContextExtension;
+import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
 import org.springframework.test.web.servlet.MockMvc;
 import org.springframework.test.web.servlet.request.RequestPostProcessor;
 import org.springframework.web.bind.annotation.PathVariable;
@@ -36,6 +38,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.context.ConfigurableWebApplicationContext;
 
+import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
 import static org.mockito.BDDMockito.given;
 import static org.mockito.Mockito.mock;
@@ -74,6 +77,23 @@ public class InterceptUrlConfigTests {
 		// @formatter:on
 	}
 
+	/**
+	 * sec-2256
+	 */
+	@Test
+	public void requestWhenMethodIsSpecifiedAndAuthorizationManagerThenItIsNotGivenPriority() throws Exception {
+		this.spring.configLocations(this.xml("Sec2256AuthorizationManager")).autowire();
+		// @formatter:off
+		this.mvc.perform(post("/path").with(userCredentials()))
+				.andExpect(status().isOk());
+		this.mvc.perform(get("/path").with(userCredentials()))
+				.andExpect(status().isOk());
+		// @formatter:on
+		assertThat(this.spring.getContext().getBeanNamesForType(FilterInvocationSecurityMetadataSource.class))
+				.isEmpty();
+		assertThat(this.spring.getContext().getBean(AuthorizationManager.class)).isNotNull();
+	}
+
 	/**
 	 * sec-2355
 	 */
@@ -90,6 +110,25 @@ public class InterceptUrlConfigTests {
 		// @formatter:on
 	}
 
+	/**
+	 * sec-2355
+	 */
+	@Test
+	public void requestWhenUsingPatchAndAuthorizationManagerThenAuthorizesRequestsAccordingly() throws Exception {
+		this.spring.configLocations(this.xml("PatchMethodAuthorizationManager")).autowire();
+		// @formatter:off
+		this.mvc.perform(get("/path").with(userCredentials()))
+				.andExpect(status().isOk());
+		this.mvc.perform(patch("/path").with(userCredentials()))
+				.andExpect(status().isForbidden());
+		this.mvc.perform(patch("/path").with(adminCredentials()))
+				.andExpect(status().isOk());
+		// @formatter:on
+		assertThat(this.spring.getContext().getBeanNamesForType(FilterInvocationSecurityMetadataSource.class))
+				.isEmpty();
+		assertThat(this.spring.getContext().getBean(AuthorizationManager.class)).isNotNull();
+	}
+
 	@Test
 	public void requestWhenUsingHasAnyRoleThenAuthorizesRequestsAccordingly() throws Exception {
 		this.spring.configLocations(this.xml("HasAnyRole")).autowire();
@@ -101,6 +140,20 @@ public class InterceptUrlConfigTests {
 		// @formatter:on
 	}
 
+	@Test
+	public void requestWhenUsingHasAnyRoleAndAuthorizationManagerThenAuthorizesRequestsAccordingly() throws Exception {
+		this.spring.configLocations(this.xml("HasAnyRoleAuthorizationManager")).autowire();
+		// @formatter:off
+		this.mvc.perform(get("/path").with(userCredentials()))
+				.andExpect(status().isOk());
+		this.mvc.perform(get("/path").with(adminCredentials()))
+				.andExpect(status().isForbidden());
+		// @formatter:on
+		assertThat(this.spring.getContext().getBeanNamesForType(FilterInvocationSecurityMetadataSource.class))
+				.isEmpty();
+		assertThat(this.spring.getContext().getBean(AuthorizationManager.class)).isNotNull();
+	}
+
 	/**
 	 * sec-2059
 	 */
@@ -117,6 +170,26 @@ public class InterceptUrlConfigTests {
 		// @formatter:on
 	}
 
+	/**
+	 * sec-2059
+	 */
+	@Test
+	public void requestWhenUsingPathVariablesAndAuthorizationManagerThenAuthorizesRequestsAccordingly()
+			throws Exception {
+		this.spring.configLocations(this.xml("PathVariablesAuthorizationManager")).autowire();
+		// @formatter:off
+		this.mvc.perform(get("/path/user/path").with(userCredentials()))
+				.andExpect(status().isOk());
+		this.mvc.perform(get("/path/otheruser/path").with(userCredentials()))
+				.andExpect(status().isForbidden());
+		this.mvc.perform(get("/path").with(userCredentials()))
+				.andExpect(status().isForbidden());
+		// @formatter:on
+		assertThat(this.spring.getContext().getBeanNamesForType(FilterInvocationSecurityMetadataSource.class))
+				.isEmpty();
+		assertThat(this.spring.getContext().getBean(AuthorizationManager.class)).isNotNull();
+	}
+
 	/**
 	 * gh-3786
 	 */
@@ -133,6 +206,26 @@ public class InterceptUrlConfigTests {
 		// @formatter:on
 	}
 
+	/**
+	 * gh-3786
+	 */
+	@Test
+	public void requestWhenUsingCamelCasePathVariablesAndAuthorizationManagerThenAuthorizesRequestsAccordingly()
+			throws Exception {
+		this.spring.configLocations(this.xml("CamelCasePathVariablesAuthorizationManager")).autowire();
+		// @formatter:off
+		this.mvc.perform(get("/path/user/path").with(userCredentials()))
+				.andExpect(status().isOk());
+		this.mvc.perform(get("/path/otheruser/path").with(userCredentials()))
+				.andExpect(status().isForbidden());
+		this.mvc.perform(get("/PATH/user/path").with(userCredentials()))
+				.andExpect(status().isForbidden());
+		// @formatter:on
+		assertThat(this.spring.getContext().getBeanNamesForType(FilterInvocationSecurityMetadataSource.class))
+				.isEmpty();
+		assertThat(this.spring.getContext().getBean(AuthorizationManager.class)).isNotNull();
+	}
+
 	/**
 	 * sec-2059
 	 */
@@ -147,6 +240,24 @@ public class InterceptUrlConfigTests {
 		// @formatter:on
 	}
 
+	/**
+	 * sec-2059
+	 */
+	@Test
+	public void requestWhenUsingPathVariablesAndTypeConversionAndAuthorizationManagerThenAuthorizesRequestsAccordingly()
+			throws Exception {
+		this.spring.configLocations(this.xml("TypeConversionPathVariablesAuthorizationManager")).autowire();
+		// @formatter:off
+		this.mvc.perform(get("/path/1/path").with(userCredentials()))
+				.andExpect(status().isOk());
+		this.mvc.perform(get("/path/2/path").with(userCredentials()))
+				.andExpect(status().isForbidden());
+		// @formatter:on
+		assertThat(this.spring.getContext().getBeanNamesForType(FilterInvocationSecurityMetadataSource.class))
+				.isEmpty();
+		assertThat(this.spring.getContext().getBean(AuthorizationManager.class)).isNotNull();
+	}
+
 	@Test
 	public void requestWhenUsingMvcMatchersThenAuthorizesRequestsAccordingly() throws Exception {
 		this.spring.configLocations(this.xml("MvcMatchers")).autowire();
@@ -155,6 +266,17 @@ public class InterceptUrlConfigTests {
 		this.mvc.perform(get("/path/")).andExpect(status().isUnauthorized());
 	}
 
+	@Test
+	public void requestWhenUsingMvcMatchersAndAuthorizationManagerThenAuthorizesRequestsAccordingly() throws Exception {
+		this.spring.configLocations(this.xml("MvcMatchersAuthorizationManager")).autowire();
+		this.mvc.perform(get("/path")).andExpect(status().isUnauthorized());
+		this.mvc.perform(get("/path.html")).andExpect(status().isUnauthorized());
+		this.mvc.perform(get("/path/")).andExpect(status().isUnauthorized());
+		assertThat(this.spring.getContext().getBeanNamesForType(FilterInvocationSecurityMetadataSource.class))
+				.isEmpty();
+		assertThat(this.spring.getContext().getBean(AuthorizationManager.class)).isNotNull();
+	}
+
 	@Test
 	public void requestWhenUsingMvcMatchersAndPathVariablesThenAuthorizesRequestsAccordingly() throws Exception {
 		this.spring.configLocations(this.xml("MvcMatchersPathVariables")).autowire();
@@ -168,6 +290,23 @@ public class InterceptUrlConfigTests {
 		// @formatter:on
 	}
 
+	@Test
+	public void requestWhenUsingMvcMatchersAndPathVariablesAndAuthorizationManagerThenAuthorizesRequestsAccordingly()
+			throws Exception {
+		this.spring.configLocations(this.xml("MvcMatchersPathVariablesAuthorizationManager")).autowire();
+		// @formatter:off
+		this.mvc.perform(get("/path/user/path").with(userCredentials()))
+				.andExpect(status().isOk());
+		this.mvc.perform(get("/path/otheruser/path").with(userCredentials()))
+				.andExpect(status().isForbidden());
+		this.mvc.perform(get("/PATH/user/path").with(userCredentials()))
+				.andExpect(status().isForbidden());
+		// @formatter:on
+		assertThat(this.spring.getContext().getBeanNamesForType(FilterInvocationSecurityMetadataSource.class))
+				.isEmpty();
+		assertThat(this.spring.getContext().getBean(AuthorizationManager.class)).isNotNull();
+	}
+
 	@Test
 	public void requestWhenUsingMvcMatchersAndServletPathThenAuthorizesRequestsAccordingly() throws Exception {
 		this.spring.configLocations(this.xml("MvcMatchersServletPath")).autowire();
@@ -184,30 +323,74 @@ public class InterceptUrlConfigTests {
 		// @formatter:on
 	}
 
+	@Test
+	public void requestWhenUsingMvcMatchersAndServletPathAndAuthorizationManagerThenAuthorizesRequestsAccordingly()
+			throws Exception {
+		this.spring.configLocations(this.xml("MvcMatchersServletPathAuthorizationManager")).autowire();
+		MockServletContext servletContext = mockServletContext("/spring");
+		ConfigurableWebApplicationContext context = this.spring.getContext();
+		context.setServletContext(servletContext);
+		// @formatter:off
+		this.mvc.perform(get("/spring/path").servletPath("/spring"))
+				.andExpect(status().isUnauthorized());
+		this.mvc.perform(get("/spring/path.html").servletPath("/spring"))
+				.andExpect(status().isUnauthorized());
+		this.mvc.perform(get("/spring/path/").servletPath("/spring"))
+				.andExpect(status().isUnauthorized());
+		// @formatter:on
+		assertThat(this.spring.getContext().getBeanNamesForType(FilterInvocationSecurityMetadataSource.class))
+				.isEmpty();
+		assertThat(this.spring.getContext().getBean(AuthorizationManager.class)).isNotNull();
+	}
+
 	@Test
 	public void configureWhenUsingAntMatcherAndServletPathThenThrowsException() {
 		assertThatExceptionOfType(BeanDefinitionParsingException.class)
 				.isThrownBy(() -> this.spring.configLocations(this.xml("AntMatcherServletPath")).autowire());
 	}
 
+	@Test
+	public void configureWhenUsingAntMatcherAndServletPathAndAuthorizationManagerThenThrowsException() {
+		assertThatExceptionOfType(BeanDefinitionParsingException.class).isThrownBy(
+				() -> this.spring.configLocations(this.xml("AntMatcherServletPathAuthorizationManager")).autowire());
+	}
+
 	@Test
 	public void configureWhenUsingRegexMatcherAndServletPathThenThrowsException() {
 		assertThatExceptionOfType(BeanDefinitionParsingException.class)
 				.isThrownBy(() -> this.spring.configLocations(this.xml("RegexMatcherServletPath")).autowire());
 	}
 
+	@Test
+	public void configureWhenUsingRegexMatcherAndServletPathAndAuthorizationManagerThenThrowsException() {
+		assertThatExceptionOfType(BeanDefinitionParsingException.class).isThrownBy(
+				() -> this.spring.configLocations(this.xml("RegexMatcherServletPathAuthorizationManager")).autowire());
+	}
+
 	@Test
 	public void configureWhenUsingCiRegexMatcherAndServletPathThenThrowsException() {
 		assertThatExceptionOfType(BeanDefinitionParsingException.class)
 				.isThrownBy(() -> this.spring.configLocations(this.xml("CiRegexMatcherServletPath")).autowire());
 	}
 
+	@Test
+	public void configureWhenUsingCiRegexMatcherAndServletPathAndAuthorizationManagerThenThrowsException() {
+		assertThatExceptionOfType(BeanDefinitionParsingException.class).isThrownBy(() -> this.spring
+				.configLocations(this.xml("CiRegexMatcherServletPathAuthorizationManager")).autowire());
+	}
+
 	@Test
 	public void configureWhenUsingDefaultMatcherAndServletPathThenThrowsException() {
 		assertThatExceptionOfType(BeanDefinitionParsingException.class)
 				.isThrownBy(() -> this.spring.configLocations(this.xml("DefaultMatcherServletPath")).autowire());
 	}
 
+	@Test
+	public void configureWhenUsingDefaultMatcherAndServletPathAndAuthorizationManagerThenThrowsException() {
+		assertThatExceptionOfType(BeanDefinitionParsingException.class).isThrownBy(() -> this.spring
+				.configLocations(this.xml("DefaultMatcherServletPathAuthorizationManager")).autowire());
+	}
+
 	private static RequestPostProcessor adminCredentials() {
 		return httpBasic("admin", "password");
 	}

+ 36 - 0
config/src/test/resources/org/springframework/security/config/http/HttpConfigTests-AuthorizationManager.xml

@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2002-2018 the original author or authors.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~       https://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<b:beans xmlns:b="http://www.springframework.org/schema/beans"
+		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+		xmlns="http://www.springframework.org/schema/security"
+		xsi:schemaLocation="
+			http://www.springframework.org/schema/security
+			https://www.springframework.org/schema/security/spring-security.xsd
+			http://www.springframework.org/schema/beans
+			https://www.springframework.org/schema/beans/spring-beans.xsd">
+
+	<http auto-config="true" authorization-manager-ref="ref">
+		<intercept-url pattern="/**" access="permitAll"/>
+	</http>
+
+	<b:bean id="ref" class="org.mockito.Mockito" factory-method="mock">
+		<b:constructor-arg value="org.springframework.security.authorization.AuthorizationManager"/>
+	</b:bean>
+
+	<b:import resource="userservice.xml"/>
+</b:beans>

+ 32 - 0
config/src/test/resources/org/springframework/security/config/http/HttpConfigTests-MinimalAuthorizationManager.xml

@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2002-2018 the original author or authors.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~       https://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<b:beans xmlns:b="http://www.springframework.org/schema/beans"
+		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+		xmlns="http://www.springframework.org/schema/security"
+		xsi:schemaLocation="
+			http://www.springframework.org/schema/security
+			https://www.springframework.org/schema/security/spring-security.xsd
+			http://www.springframework.org/schema/beans
+			https://www.springframework.org/schema/beans/spring-beans.xsd">
+
+	<http auto-config="true" use-authorization-manager="true">
+		<intercept-url pattern="/**" access="hasRole('USER')"/>
+	</http>
+
+	<b:import resource="userservice.xml"/>
+</b:beans>

+ 33 - 0
config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-AntMatcherServletPathAuthorizationManager.xml

@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2002-2018 the original author or authors.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~       https://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<b:beans xmlns:b="http://www.springframework.org/schema/beans"
+		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+		xmlns="http://www.springframework.org/schema/security"
+		xsi:schemaLocation="
+			http://www.springframework.org/schema/security
+			https://www.springframework.org/schema/security/spring-security.xsd
+			http://www.springframework.org/schema/beans
+			https://www.springframework.org/schema/beans/spring-beans.xsd">
+
+	<http request-matcher="ant" use-authorization-manager="true">
+		<intercept-url pattern="/path" access="denyAll" servlet-path="/spring"/>
+		<http-basic/>
+	</http>
+
+	<b:import resource="userservice.xml"/>
+</b:beans>

+ 36 - 0
config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-CamelCasePathVariablesAuthorizationManager.xml

@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2002-2018 the original author or authors.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~       https://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<b:beans xmlns:b="http://www.springframework.org/schema/beans"
+		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+		xmlns="http://www.springframework.org/schema/security"
+		xsi:schemaLocation="
+			http://www.springframework.org/schema/security
+			https://www.springframework.org/schema/security/spring-security.xsd
+			http://www.springframework.org/schema/beans
+			https://www.springframework.org/schema/beans/spring-beans.xsd">
+
+	<http auto-config="true" use-authorization-manager="true">
+		<intercept-url pattern="/path/{userName}/**" access="#userName == authentication.name"/>
+		<intercept-url pattern="/**" access="denyAll"/>
+		<http-basic/>
+	</http>
+
+	<b:bean name="path" class="org.springframework.security.config.http.InterceptUrlConfigTests.PathController"/>
+
+	<b:import resource="userservice.xml"/>
+</b:beans>

+ 33 - 0
config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-CiRegexMatcherServletPathAuthorizationManager.xml

@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2002-2018 the original author or authors.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~       https://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<b:beans xmlns:b="http://www.springframework.org/schema/beans"
+		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+		xmlns="http://www.springframework.org/schema/security"
+		xsi:schemaLocation="
+			http://www.springframework.org/schema/security
+			https://www.springframework.org/schema/security/spring-security.xsd
+			http://www.springframework.org/schema/beans
+			https://www.springframework.org/schema/beans/spring-beans.xsd">
+
+	<http request-matcher="ciRegex" use-authorization-manager="true">
+		<intercept-url pattern="/path" access="denyAll" servlet-path="/spring"/>
+		<http-basic/>
+	</http>
+
+	<b:import resource="userservice.xml"/>
+</b:beans>

+ 33 - 0
config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-DefaultMatcherServletPathAuthorizationManager.xml

@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2002-2018 the original author or authors.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~       https://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<b:beans xmlns:b="http://www.springframework.org/schema/beans"
+		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+		xmlns="http://www.springframework.org/schema/security"
+		xsi:schemaLocation="
+			http://www.springframework.org/schema/security
+			https://www.springframework.org/schema/security/spring-security.xsd
+			http://www.springframework.org/schema/beans
+			https://www.springframework.org/schema/beans/spring-beans.xsd">
+
+	<http use-authorization-manager="true">
+		<intercept-url pattern="/path" access="denyAll" servlet-path="/spring"/>
+		<http-basic/>
+	</http>
+
+	<b:import resource="userservice.xml"/>
+</b:beans>

+ 35 - 0
config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-HasAnyRoleAuthorizationManager.xml

@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2002-2018 the original author or authors.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~       https://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<b:beans xmlns:b="http://www.springframework.org/schema/beans"
+		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+		xmlns="http://www.springframework.org/schema/security"
+		xsi:schemaLocation="
+			http://www.springframework.org/schema/security
+			https://www.springframework.org/schema/security/spring-security.xsd
+			http://www.springframework.org/schema/beans
+			https://www.springframework.org/schema/beans/spring-beans.xsd">
+
+	<http auto-config="true" use-authorization-manager="true">
+		<intercept-url pattern="/**" access="hasAnyRole('ROLE_DEVELOPER', 'ROLE_USER')"/>
+		<http-basic/>
+	</http>
+
+	<b:bean name="path" class="org.springframework.security.config.http.InterceptUrlConfigTests.PathController"/>
+
+	<b:import resource="userservice.xml"/>
+</b:beans>

+ 42 - 0
config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-MvcMatchersAuthorizationManager.xml

@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2002-2018 the original author or authors.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~       https://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<b:beans xmlns:b="http://www.springframework.org/schema/beans"
+		xmlns:mvc="http://www.springframework.org/schema/mvc"
+		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+		xmlns="http://www.springframework.org/schema/security"
+		xsi:schemaLocation="
+			http://www.springframework.org/schema/security
+			https://www.springframework.org/schema/security/spring-security.xsd
+			http://www.springframework.org/schema/beans
+			https://www.springframework.org/schema/beans/spring-beans.xsd
+			http://www.springframework.org/schema/mvc
+			https://www.springframework.org/schema/mvc/spring-mvc.xsd">
+
+	<http auto-config="true" request-matcher="mvc" use-authorization-manager="true">
+		<intercept-url pattern="/path" access="denyAll"/>
+		<http-basic/>
+	</http>
+
+	<mvc:annotation-driven>
+		<mvc:path-matching suffix-pattern="true"/>
+	</mvc:annotation-driven>
+
+	<b:bean name="path" class="org.springframework.security.config.http.InterceptUrlConfigTests.PathController"/>
+
+	<b:import resource="userservice.xml"/>
+</b:beans>

+ 41 - 0
config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-MvcMatchersPathVariablesAuthorizationManager.xml

@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2002-2018 the original author or authors.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~       https://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<b:beans xmlns:b="http://www.springframework.org/schema/beans"
+		 xmlns:mvc="http://www.springframework.org/schema/mvc"
+		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+		xmlns="http://www.springframework.org/schema/security"
+		xsi:schemaLocation="
+			http://www.springframework.org/schema/security
+			https://www.springframework.org/schema/security/spring-security.xsd
+			http://www.springframework.org/schema/beans
+			https://www.springframework.org/schema/beans/spring-beans.xsd
+			http://www.springframework.org/schema/mvc
+			https://www.springframework.org/schema/mvc/spring-mvc.xsd">
+
+	<http auto-config="true" use-authorization-manager="true">
+		<intercept-url pattern="/path/{un}/**" access="#un == 'user'"/>
+		<intercept-url pattern="/**" access="denyAll"/>
+		<http-basic/>
+	</http>
+
+	<mvc:annotation-driven/>
+
+	<b:bean name="path" class="org.springframework.security.config.http.InterceptUrlConfigTests.PathController"/>
+
+	<b:import resource="userservice.xml"/>
+</b:beans>

+ 42 - 0
config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-MvcMatchersServletPathAuthorizationManager.xml

@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2002-2018 the original author or authors.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~       https://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<b:beans xmlns:b="http://www.springframework.org/schema/beans"
+		xmlns:mvc="http://www.springframework.org/schema/mvc"
+		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+		xmlns="http://www.springframework.org/schema/security"
+		xsi:schemaLocation="
+			http://www.springframework.org/schema/security
+			https://www.springframework.org/schema/security/spring-security.xsd
+			http://www.springframework.org/schema/beans
+			https://www.springframework.org/schema/beans/spring-beans.xsd
+			http://www.springframework.org/schema/mvc
+			https://www.springframework.org/schema/mvc/spring-mvc.xsd">
+
+	<http auto-config="true" request-matcher="mvc" use-authorization-manager="true">
+		<intercept-url pattern="/path" access="denyAll" servlet-path="/spring"/>
+		<http-basic/>
+	</http>
+
+	<mvc:annotation-driven>
+		<mvc:path-matching suffix-pattern="true"/>
+	</mvc:annotation-driven>
+
+	<b:bean name="path" class="org.springframework.security.config.http.InterceptUrlConfigTests.PathController"/>
+
+	<b:import resource="userservice.xml"/>
+</b:beans>

+ 36 - 0
config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-PatchMethodAuthorizationManager.xml

@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2002-2018 the original author or authors.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~       https://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<b:beans xmlns:b="http://www.springframework.org/schema/beans"
+		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+		xmlns="http://www.springframework.org/schema/security"
+		xsi:schemaLocation="
+			http://www.springframework.org/schema/security
+			https://www.springframework.org/schema/security/spring-security.xsd
+			http://www.springframework.org/schema/beans
+			https://www.springframework.org/schema/beans/spring-beans.xsd">
+
+	<http auto-config="true" use-authorization-manager="true">
+		<intercept-url pattern="/**" method="PATCH" access="hasRole('ADMIN')"/>
+		<http-basic/>
+		<csrf disabled="true"/>
+	</http>
+
+	<b:bean name="path" class="org.springframework.security.config.http.InterceptUrlConfigTests.PathController"/>
+
+	<b:import resource="userservice.xml"/>
+</b:beans>

+ 36 - 0
config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-PathVariablesAuthorizationManager.xml

@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2002-2018 the original author or authors.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~       https://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<b:beans xmlns:b="http://www.springframework.org/schema/beans"
+		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+		xmlns="http://www.springframework.org/schema/security"
+		xsi:schemaLocation="
+			http://www.springframework.org/schema/security
+			https://www.springframework.org/schema/security/spring-security.xsd
+			http://www.springframework.org/schema/beans
+			https://www.springframework.org/schema/beans/spring-beans.xsd">
+
+	<http auto-config="true" use-authorization-manager="true">
+		<intercept-url pattern="/path/{un}/**" access="#un == authentication.name"/>
+		<intercept-url pattern="/**" access="denyAll"/>
+		<http-basic/>
+	</http>
+
+	<b:bean name="path" class="org.springframework.security.config.http.InterceptUrlConfigTests.PathController"/>
+
+	<b:import resource="userservice.xml"/>
+</b:beans>

+ 33 - 0
config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-RegexMatcherServletPathAuthorizationManager.xml

@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2002-2018 the original author or authors.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~       https://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<b:beans xmlns:b="http://www.springframework.org/schema/beans"
+		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+		xmlns="http://www.springframework.org/schema/security"
+		xsi:schemaLocation="
+			http://www.springframework.org/schema/security
+			https://www.springframework.org/schema/security/spring-security.xsd
+			http://www.springframework.org/schema/beans
+			https://www.springframework.org/schema/beans/spring-beans.xsd">
+
+	<http request-matcher="regex" use-authorization-manager="true">
+		<intercept-url pattern="/path" access="denyAll" servlet-path="/spring"/>
+		<http-basic/>
+	</http>
+
+	<b:import resource="userservice.xml"/>
+</b:beans>

+ 37 - 0
config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-Sec2256AuthorizationManager.xml

@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2002-2018 the original author or authors.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~       https://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<b:beans xmlns:b="http://www.springframework.org/schema/beans"
+		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+		xmlns="http://www.springframework.org/schema/security"
+		xsi:schemaLocation="
+			http://www.springframework.org/schema/security
+			https://www.springframework.org/schema/security/spring-security.xsd
+			http://www.springframework.org/schema/beans
+			https://www.springframework.org/schema/beans/spring-beans.xsd">
+
+	<http auto-config="true" use-authorization-manager="true">
+		<intercept-url pattern="/path" access="hasRole('USER')"/>
+		<intercept-url pattern="/path" method="GET" access="denyAll"/>
+		<http-basic/>
+		<csrf disabled="true"/>
+	</http>
+
+	<b:bean name="path" class="org.springframework.security.config.http.InterceptUrlConfigTests.PathController"/>
+
+	<b:import resource="userservice.xml"/>
+</b:beans>

+ 37 - 0
config/src/test/resources/org/springframework/security/config/http/InterceptUrlConfigTests-TypeConversionPathVariablesAuthorizationManager.xml

@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2002-2018 the original author or authors.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~       https://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<b:beans xmlns:b="http://www.springframework.org/schema/beans"
+		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+		xmlns="http://www.springframework.org/schema/security"
+		xsi:schemaLocation="
+			http://www.springframework.org/schema/security
+			https://www.springframework.org/schema/security/spring-security.xsd
+			http://www.springframework.org/schema/beans
+			https://www.springframework.org/schema/beans/spring-beans.xsd">
+
+	<http auto-config="true" use-authorization-manager="true">
+		<intercept-url pattern="/path/{un}/**" access="@id.isOne(#un)"/>
+		<intercept-url pattern="/**" access="denyAll"/>
+		<http-basic/>
+	</http>
+
+	<b:bean name="path" class="org.springframework.security.config.http.InterceptUrlConfigTests.PathController"/>
+	<b:bean name="id" class="org.springframework.security.config.http.InterceptUrlConfigTests.Id"/>
+
+	<b:import resource="userservice.xml"/>
+</b:beans>

+ 7 - 0
docs/modules/ROOT/pages/servlet/appendix/namespace/http.adoc

@@ -29,6 +29,13 @@ These are fixed and cannot be replaced with alternatives.
 === <http> Attributes
 The attributes on the `<http>` element control some of the properties on the core filters.
 
+[[nsa-http-use-authorization-manager]]
+* **use-authorization-manager**
+Use AuthorizationManager API instead of SecurityMetadataSource
+
+[[nsa-http-authorization-manager-ref]]
+* **access-decision-manager-ref**
+Use this AuthorizationManager instead of deriving one from <intercept-url> elements
 
 [[nsa-http-access-decision-manager-ref]]
 * **access-decision-manager-ref**