Explorar o código

Various NamespaceHttp*Tests groovy->java

Issue: gh-4939
Josh Cummings %!s(int64=6) %!d(string=hai) anos
pai
achega
cf0c5f9026
Modificáronse 18 ficheiros con 1458 adicións e 1347 borrados
  1. 0 197
      config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/NamespaceHttpCustomFilterTests.groovy
  2. 0 134
      config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/NamespaceHttpFirewallTests.groovy
  3. 0 170
      config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/NamespaceHttpFormLoginTests.groovy
  4. 0 267
      config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/NamespaceHttpHeadersTests.groovy
  5. 0 169
      config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/NamespaceHttpInterceptUrlTests.groovy
  6. 0 142
      config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/NamespaceHttpJeeTests.groovy
  7. 0 115
      config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/NamespaceHttpPortMappingsTests.groovy
  8. 0 73
      config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/NamespaceHttpRequestCacheTests.groovy
  9. 0 80
      config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/NamespaceHttpServerAccessDeniedHandlerTests.groovy
  10. 194 0
      config/src/test/java/org/springframework/security/config/annotation/web/configurers/NamespaceHttpCustomFilterTests.java
  11. 104 0
      config/src/test/java/org/springframework/security/config/annotation/web/configurers/NamespaceHttpFirewallTests.java
  12. 197 0
      config/src/test/java/org/springframework/security/config/annotation/web/configurers/NamespaceHttpFormLoginTests.java
  13. 293 0
      config/src/test/java/org/springframework/security/config/annotation/web/configurers/NamespaceHttpHeadersTests.java
  14. 187 0
      config/src/test/java/org/springframework/security/config/annotation/web/configurers/NamespaceHttpInterceptUrlTests.java
  15. 159 0
      config/src/test/java/org/springframework/security/config/annotation/web/configurers/NamespaceHttpJeeTests.java
  16. 86 0
      config/src/test/java/org/springframework/security/config/annotation/web/configurers/NamespaceHttpPortMappingsTests.java
  17. 123 0
      config/src/test/java/org/springframework/security/config/annotation/web/configurers/NamespaceHttpRequestCacheTests.java
  18. 115 0
      config/src/test/java/org/springframework/security/config/annotation/web/configurers/NamespaceHttpServerAccessDeniedHandlerTests.java

+ 0 - 197
config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/NamespaceHttpCustomFilterTests.groovy

@@ -1,197 +0,0 @@
-/*
- * Copyright 2002-2013 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.annotation.web.configurers;
-
-import java.io.IOException;
-
-import javax.servlet.FilterChain
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.springframework.context.annotation.Bean
-import org.springframework.context.annotation.Configuration
-import org.springframework.security.access.AccessDecisionManager
-import org.springframework.security.access.AccessDeniedException;
-import org.springframework.security.access.ConfigAttribute
-import org.springframework.security.authentication.AnonymousAuthenticationToken
-import org.springframework.security.authentication.AuthenticationManager;
-import org.springframework.security.config.annotation.BaseSpringSpec
-import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.configuration.BaseWebConfig;
-import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
-import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.AuthenticationException;
-import org.springframework.security.core.authority.AuthorityUtils;
-import org.springframework.security.web.AuthenticationEntryPoint
-import org.springframework.security.web.FilterInvocation
-import org.springframework.security.web.access.AccessDeniedHandler;
-import org.springframework.security.web.access.AccessDeniedHandlerImpl;
-import org.springframework.security.web.access.ExceptionTranslationFilter
-import org.springframework.security.web.access.intercept.FilterSecurityInterceptor
-import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
-import org.springframework.security.web.authentication.AnonymousAuthenticationFilter;
-import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
-import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
-import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
-import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
-import org.springframework.security.web.context.NullSecurityContextRepository;
-import org.springframework.security.web.context.SecurityContextPersistenceFilter
-import org.springframework.security.web.jaasapi.JaasApiIntegrationFilter;
-import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter;
-import org.springframework.security.web.util.matcher.AntPathRequestMatcher
-import org.springframework.security.web.util.matcher.AnyRequestMatcher;
-import org.springframework.security.web.util.matcher.RequestMatcher
-import org.springframework.web.filter.OncePerRequestFilter
-
-import spock.lang.Ignore;
-
-/**
- * Tests to verify that all the functionality of <anonymous> attributes is present
- *
- * @author Rob Winch
- *
- */
-public class NamespaceHttpCustomFilterTests extends BaseSpringSpec {
-	def "http/custom-filter@before"() {
-		when:
-		loadConfig(CustomFilterBeforeConfig)
-		then:
-		filterChain().filters[0].class == CustomFilter
-	}
-
-	@Configuration
-	static class CustomFilterBeforeConfig extends BaseWebConfig {
-		CustomFilterBeforeConfig() {
-			// do not add the default filters to make testing easier
-			super(true)
-		}
-
-		protected void configure(HttpSecurity http) {
-			http
-				.addFilterBefore(new CustomFilter(), UsernamePasswordAuthenticationFilter.class)
-				.formLogin()
-		}
-	}
-
-	def "http/custom-filter@after"() {
-		when:
-		loadConfig(CustomFilterAfterConfig)
-		then:
-		filterChain().filters[1].class == CustomFilter
-	}
-
-	@Configuration
-	static class CustomFilterAfterConfig extends BaseWebConfig {
-		CustomFilterAfterConfig() {
-			// do not add the default filters to make testing easier
-			super(true)
-		}
-
-		protected void configure(HttpSecurity http) {
-			http
-				.addFilterAfter(new CustomFilter(), UsernamePasswordAuthenticationFilter.class)
-				.formLogin()
-		}
-	}
-
-	def "http/custom-filter@position"() {
-		when:
-		loadConfig(CustomFilterPositionConfig)
-		then:
-		filterChain().filters.collect { it.class } == [CustomFilter]
-	}
-
-	@Configuration
-	static class CustomFilterPositionConfig extends BaseWebConfig {
-		CustomFilterPositionConfig() {
-			// do not add the default filters to make testing easier
-			super(true)
-		}
-
-		protected void configure(HttpSecurity http) {
-			http
-				// this works so long as the CustomFilter extends one of the standard filters
-				// if not, use addFilterBefore or addFilterAfter
-				.addFilter(new CustomFilter())
-		}
-	}
-
-	def "http/custom-filter@position at"() {
-		when:
-		loadConfig(CustomFilterPositionAtConfig)
-		then:
-		filterChain().filters.collect { it.class } == [OtherCustomFilter]
-	}
-
-	@Configuration
-	static class CustomFilterPositionAtConfig extends BaseWebConfig {
-		CustomFilterPositionAtConfig() {
-			// do not add the default filters to make testing easier
-			super(true)
-		}
-
-		protected void configure(HttpSecurity http) {
-			http
-				.addFilterAt(new OtherCustomFilter(), UsernamePasswordAuthenticationFilter.class)
-		}
-	}
-
-	def "http/custom-filter no AuthenticationManager in HttpSecurity"() {
-		when:
-		loadConfig(NoAuthenticationManagerInHtppConfigurationConfig)
-		then:
-		filterChain().filters[0].class == CustomFilter
-	}
-
-	@EnableWebSecurity
-	static class NoAuthenticationManagerInHtppConfigurationConfig extends WebSecurityConfigurerAdapter {
-		NoAuthenticationManagerInHtppConfigurationConfig() {
-			super(true)
-		}
-
-		protected AuthenticationManager authenticationManager()
-				throws Exception {
-			return new CustomAuthenticationManager();
-		}
-
-		@Override
-		protected void configure(HttpSecurity http) {
-			http
-				.authorizeRequests()
-					.anyRequest().hasRole("USER")
-					.and()
-				.addFilterBefore(new CustomFilter(), UsernamePasswordAuthenticationFilter.class)
-		}
-	}
-
-	static class CustomFilter extends UsernamePasswordAuthenticationFilter {}
-	static class OtherCustomFilter extends OncePerRequestFilter {
-		protected void doFilterInternal(
-				HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
-		throws ServletException, IOException {
-			filterChain.doFilter(request,response);
-		}
-	}
-
-	static class CustomAuthenticationManager implements AuthenticationManager {
-		public Authentication authenticate(Authentication authentication)
-				throws AuthenticationException {
-			return null;
-		}
-	}
-}

+ 0 - 134
config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/NamespaceHttpFirewallTests.groovy

@@ -1,134 +0,0 @@
-/*
- * Copyright 2002-2013 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.annotation.web.configurers
-
-import org.springframework.context.annotation.Bean;
-
-import javax.servlet.http.HttpServletRequest
-import javax.servlet.http.HttpServletResponse
-
-import org.springframework.context.annotation.Configuration
-import org.springframework.mock.web.MockFilterChain
-import org.springframework.mock.web.MockHttpServletRequest
-import org.springframework.mock.web.MockHttpServletResponse
-import org.springframework.security.config.annotation.BaseSpringSpec
-import org.springframework.security.config.annotation.web.builders.HttpSecurity
-import org.springframework.security.config.annotation.web.builders.WebSecurity
-import org.springframework.security.config.annotation.web.configuration.BaseWebConfig
-import org.springframework.security.web.FilterChainProxy
-import org.springframework.security.web.firewall.DefaultHttpFirewall
-import org.springframework.security.web.firewall.FirewalledRequest
-import org.springframework.security.web.firewall.RequestRejectedException
-
-/**
- * Tests to verify that all the functionality of <http-firewall> attributes is present
- *
- * @author Rob Winch
- *
- */
-public class NamespaceHttpFirewallTests extends BaseSpringSpec {
-	FilterChainProxy springSecurityFilterChain
-	MockHttpServletRequest request
-	MockHttpServletResponse response
-	MockFilterChain chain
-
-	def setup() {
-		request = new MockHttpServletRequest("GET", "")
-		response = new MockHttpServletResponse()
-		chain = new MockFilterChain()
-	}
-
-	def "http-firewall"() {
-		setup:
-			loadConfig(HttpFirewallConfig)
-			springSecurityFilterChain = context.getBean(FilterChainProxy)
-			request.setPathInfo("/public/../private/")
-		when:
-			springSecurityFilterChain.doFilter(request,response,chain)
-		then: "the default firewall is used"
-			thrown(RequestRejectedException)
-	}
-
-	@Configuration
-	static class HttpFirewallConfig extends BaseWebConfig {
-		protected void configure(HttpSecurity http) {
-		}
-	}
-
-	def "http-firewall@ref"() {
-		setup:
-			loadConfig(CustomHttpFirewallConfig)
-			springSecurityFilterChain = context.getBean(FilterChainProxy)
-			request.setParameter("deny", "true")
-		when:
-			springSecurityFilterChain.doFilter(request,response,chain)
-		then: "the custom firewall is used"
-			thrown(RequestRejectedException)
-	}
-
-	@Configuration
-	static class CustomHttpFirewallConfig extends BaseWebConfig {
-		@Override
-		protected void configure(HttpSecurity http) { }
-
-		@Override
-		public void configure(WebSecurity builder)	throws Exception {
-			builder
-				.httpFirewall(new CustomHttpFirewall())
-		}
-	}
-
-	def "http-firewall bean"() {
-		setup:
-		loadConfig(CustomHttpFirewallBeanConfig)
-		springSecurityFilterChain = context.getBean(FilterChainProxy)
-		request.setParameter("deny", "true")
-		when:
-		springSecurityFilterChain.doFilter(request,response,chain)
-		then: "the custom firewall is used"
-		thrown(RequestRejectedException)
-	}
-
-	@Configuration
-	static class CustomHttpFirewallBeanConfig extends BaseWebConfig {
-		@Override
-		protected void configure(HttpSecurity http) { }
-
-		@Bean
-		CustomHttpFirewall firewall() {
-			return new CustomHttpFirewall();
-		}
-	}
-
-	static class CustomHttpFirewall extends DefaultHttpFirewall {
-
-		@Override
-		public FirewalledRequest getFirewalledRequest(HttpServletRequest request)
-				throws RequestRejectedException {
-			if(request.getParameter("deny")) {
-				throw new RequestRejectedException("custom rejection")
-			}
-			return super.getFirewalledRequest(request)
-		}
-
-		@Override
-		public HttpServletResponse getFirewalledResponse(
-				HttpServletResponse response) {
-			return super.getFirewalledRequest(response)
-		}
-
-	}
-}

+ 0 - 170
config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/NamespaceHttpFormLoginTests.groovy

@@ -1,170 +0,0 @@
-
-
-/*
- * Copyright 2002-2013 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.annotation.web.configurers
-
-import org.springframework.context.annotation.Configuration
-import org.springframework.mock.web.MockFilterChain
-import org.springframework.mock.web.MockHttpServletRequest
-import org.springframework.mock.web.MockHttpServletResponse
-import org.springframework.security.config.annotation.BaseSpringSpec
-import org.springframework.security.config.annotation.web.builders.HttpSecurity
-import org.springframework.security.config.annotation.web.builders.WebSecurity
-import org.springframework.security.config.annotation.web.configuration.BaseWebConfig
-import org.springframework.security.web.FilterChainProxy
-import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler
-import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler
-import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
-import org.springframework.security.web.authentication.WebAuthenticationDetailsSource
-
-/**
- * Tests to verify that all the functionality of <anonymous> attributes is present
- *
- * @author Rob Winch
- *
- */
-public class NamespaceHttpFormLoginTests extends BaseSpringSpec {
-	FilterChainProxy springSecurityFilterChain
-
-	def "http/form-login"() {
-		setup:
-		loadConfig(FormLoginConfig)
-			springSecurityFilterChain = context.getBean(FilterChainProxy)
-		when:
-			springSecurityFilterChain.doFilter(request,response,chain)
-		then:
-			response.getRedirectedUrl() == "http://localhost/login"
-		when: "fail to log in"
-			super.setup()
-			request.servletPath = "/login"
-			request.method = "POST"
-			springSecurityFilterChain.doFilter(request,response,chain)
-		then: "sent to login error page"
-			response.getRedirectedUrl() == "/login?error"
-		when: "login success"
-			super.setup()
-			request.servletPath = "/login"
-			request.method = "POST"
-			request.parameters.username = ["user"] as String[]
-			request.parameters.password = ["password"] as String[]
-			springSecurityFilterChain.doFilter(request,response,chain)
-		then: "sent to default succes page"
-			response.getRedirectedUrl() == "/"
-	}
-
-	@Configuration
-	static class FormLoginConfig extends BaseWebConfig {
-
-		@Override
-		public void configure(WebSecurity web) throws Exception {
-			web
-				.ignoring()
-					.antMatchers("/resources/**");
-		}
-
-		@Override
-		protected void configure(HttpSecurity http) {
-			http
-				.authorizeRequests()
-					.anyRequest().hasRole("USER")
-					.and()
-				.formLogin()
-		}
-	}
-
-	def "http/form-login custom"() {
-		setup:
-			loadConfig(FormLoginCustomConfig)
-			springSecurityFilterChain = context.getBean(FilterChainProxy)
-		when:
-			springSecurityFilterChain.doFilter(request,response,chain)
-		then:
-			response.getRedirectedUrl() == "http://localhost/authentication/login"
-		when: "fail to log in"
-			super.setup()
-			request.servletPath = "/authentication/login/process"
-			request.method = "POST"
-			springSecurityFilterChain.doFilter(request,response,chain)
-			then: "sent to login error page"
-			response.getRedirectedUrl() == "/authentication/login?failed"
-		when: "login success"
-			super.setup()
-			request.servletPath = "/authentication/login/process"
-			request.method = "POST"
-			request.parameters.username = ["user"] as String[]
-			request.parameters.password = ["password"] as String[]
-			springSecurityFilterChain.doFilter(request,response,chain)
-		then: "sent to default succes page"
-			response.getRedirectedUrl() == "/default"
-	}
-
-	@Configuration
-	static class FormLoginCustomConfig extends BaseWebConfig {
-		protected void configure(HttpSecurity http) throws Exception {
-			boolean alwaysUseDefaultSuccess = true;
-			http
-				.authorizeRequests()
-					.anyRequest().hasRole("USER")
-					.and()
-				.formLogin()
-					.usernameParameter("username") // form-login@username-parameter
-					.passwordParameter("password") // form-login@password-parameter
-					.loginPage("/authentication/login") // form-login@login-page
-					.failureUrl("/authentication/login?failed") // form-login@authentication-failure-url
-					.loginProcessingUrl("/authentication/login/process") // form-login@login-processing-url
-					.defaultSuccessUrl("/default", alwaysUseDefaultSuccess) // form-login@default-target-url / form-login@always-use-default-target
-		}
-	}
-
-	def "http/form-login custom refs"() {
-		when:
-			loadConfig(FormLoginCustomRefsConfig)
-			springSecurityFilterChain = context.getBean(FilterChainProxy)
-			then: "CustomWebAuthenticationDetailsSource is used"
-			findFilter(UsernamePasswordAuthenticationFilter).authenticationDetailsSource.class == CustomWebAuthenticationDetailsSource
-		when: "fail to log in"
-			request.servletPath = "/login"
-			request.method = "POST"
-			springSecurityFilterChain.doFilter(request,response,chain)
-		then: "sent to login error page"
-			response.getRedirectedUrl() == "/custom/failure"
-		when: "login success"
-			super.setup()
-			request.servletPath = "/login"
-			request.method = "POST"
-			request.parameters.username = ["user"] as String[]
-			request.parameters.password = ["password"] as String[]
-			springSecurityFilterChain.doFilter(request,response,chain)
-		then: "sent to default succes page"
-			response.getRedirectedUrl() == "/custom/targetUrl"
-	}
-
-	@Configuration
-	static class FormLoginCustomRefsConfig extends BaseWebConfig {
-		protected void configure(HttpSecurity http) throws Exception {
-			http
-				.formLogin()
-					.loginPage("/login")
-					.failureHandler(new SimpleUrlAuthenticationFailureHandler("/custom/failure")) // form-login@authentication-failure-handler-ref
-					.successHandler(new SavedRequestAwareAuthenticationSuccessHandler( defaultTargetUrl : "/custom/targetUrl" )) // form-login@authentication-success-handler-ref
-					.authenticationDetailsSource(new CustomWebAuthenticationDetailsSource()) // form-login@authentication-details-source-ref
-					.and();
-		}
-	}
-
-	static class CustomWebAuthenticationDetailsSource extends WebAuthenticationDetailsSource {}
-}

+ 0 - 267
config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/NamespaceHttpHeadersTests.groovy

@@ -1,267 +0,0 @@
-/*
- * Copyright 2002-2013 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.annotation.web.configurers;
-
-import org.springframework.context.annotation.Configuration
-import org.springframework.security.config.annotation.BaseSpringSpec
-import org.springframework.security.config.annotation.web.builders.HttpSecurity
-import org.springframework.security.config.annotation.web.configuration.BaseWebConfig
-import org.springframework.security.web.header.writers.CacheControlHeadersWriter
-import org.springframework.security.web.header.writers.HstsHeaderWriter
-import org.springframework.security.web.header.writers.StaticHeadersWriter
-import org.springframework.security.web.header.writers.XContentTypeOptionsHeaderWriter
-import org.springframework.security.web.header.writers.XXssProtectionHeaderWriter
-import org.springframework.security.web.header.writers.frameoptions.StaticAllowFromStrategy
-import org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter
-import org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter.XFrameOptionsMode
-import org.springframework.security.web.util.matcher.AnyRequestMatcher
-import org.springframework.security.web.util.matcher.RequestMatcher;
-
-/**
- * Tests to verify that all the functionality of <headers> attributes is present
- *
- * @author Rob Winch
- *
- */
-public class NamespaceHttpHeadersTests extends BaseSpringSpec {
-
-	def "http/headers"() {
-		setup:
-			loadConfig(HeadersDefaultConfig)
-			request.secure = true
-		when:
-			springSecurityFilterChain.doFilter(request,response,chain)
-		then:
-			responseHeaders == ['X-Content-Type-Options':'nosniff',
-				'X-Frame-Options':'DENY',
-				'Strict-Transport-Security': 'max-age=31536000 ; includeSubDomains',
-				'Cache-Control': 'no-cache, no-store, max-age=0, must-revalidate',
-				'Pragma':'no-cache',
-				'Expires' : '0',
-				'X-XSS-Protection' : '1; mode=block']
-	}
-
-	@Configuration
-	static class HeadersDefaultConfig extends BaseWebConfig {
-		@Override
-		protected void configure(HttpSecurity http) {
-			http
-				.headers()
-		}
-	}
-
-	def "http/headers/cache-control"() {
-		setup:
-			loadConfig(HeadersCacheControlConfig)
-			request.secure = true
-		when:
-			springSecurityFilterChain.doFilter(request,response,chain)
-		then:
-			responseHeaders == ['Cache-Control': 'no-cache, no-store, max-age=0, must-revalidate',
-				'Expires' : '0',
-				'Pragma':'no-cache']
-	}
-
-	@Configuration
-	static class HeadersCacheControlConfig extends BaseWebConfig {
-		@Override
-		protected void configure(HttpSecurity http) {
-			http
-				.headers()
-					.defaultsDisabled()
-					.cacheControl()
-		}
-	}
-
-	def "http/headers/hsts"() {
-		setup:
-			loadConfig(HstsConfig)
-			request.secure = true
-		when:
-			springSecurityFilterChain.doFilter(request,response,chain)
-		then:
-			responseHeaders == ['Strict-Transport-Security': 'max-age=31536000 ; includeSubDomains']
-	}
-
-	@Configuration
-	static class HstsConfig extends BaseWebConfig {
-		@Override
-		protected void configure(HttpSecurity http) {
-			http
-				.headers()
-					.defaultsDisabled()
-					.httpStrictTransportSecurity()
-		}
-	}
-
-	def "http/headers/hsts custom"() {
-		setup:
-			loadConfig(HstsCustomConfig)
-		when:
-			springSecurityFilterChain.doFilter(request,response,chain)
-		then:
-			responseHeaders == ['Strict-Transport-Security': 'max-age=15768000']
-	}
-
-	@Configuration
-	static class HstsCustomConfig extends BaseWebConfig {
-		@Override
-		protected void configure(HttpSecurity http) {
-			http
-				.headers()
-					// hsts@request-matcher-ref, hsts@max-age-seconds, hsts@include-subdomains
-					.defaultsDisabled()
-					.httpStrictTransportSecurity()
-						.requestMatcher(AnyRequestMatcher.INSTANCE)
-						.maxAgeInSeconds(15768000)
-						.includeSubDomains(false)
-		}
-	}
-
-	def "http/headers/frame-options@policy=SAMEORIGIN"() {
-		setup:
-			loadConfig(FrameOptionsSameOriginConfig)
-		when:
-			springSecurityFilterChain.doFilter(request,response,chain)
-		then:
-			responseHeaders == ['X-Frame-Options': 'SAMEORIGIN']
-	}
-
-	@Configuration
-	static class FrameOptionsSameOriginConfig extends BaseWebConfig {
-		@Override
-		protected void configure(HttpSecurity http) {
-			http
-				.headers()
-					// frame-options@policy=SAMEORIGIN
-					.defaultsDisabled()
-					.frameOptions()
-						.sameOrigin()
-		}
-	}
-
-	// frame-options@strategy, frame-options@value, frame-options@parameter are not provided instead use frame-options@ref
-
-	def "http/headers/frame-options"() {
-		setup:
-			loadConfig(FrameOptionsAllowFromConfig)
-		when:
-			springSecurityFilterChain.doFilter(request,response,chain)
-		then:
-			responseHeaders == ['X-Frame-Options': 'ALLOW-FROM https://example.com']
-	}
-
-
-	@Configuration
-	static class FrameOptionsAllowFromConfig extends BaseWebConfig {
-		@Override
-		protected void configure(HttpSecurity http) {
-			http
-				.headers()
-					// frame-options@ref
-					.defaultsDisabled()
-					.addHeaderWriter(new XFrameOptionsHeaderWriter(new StaticAllowFromStrategy(new URI("https://example.com"))))
-		}
-	}
-
-	def "http/headers/xss-protection"() {
-		setup:
-			loadConfig(XssProtectionConfig)
-		when:
-			springSecurityFilterChain.doFilter(request,response,chain)
-		then:
-			responseHeaders == ['X-XSS-Protection': '1; mode=block']
-	}
-
-	@Configuration
-	static class XssProtectionConfig extends BaseWebConfig {
-		@Override
-		protected void configure(HttpSecurity http) {
-			http
-				.headers()
-					// xss-protection
-					.defaultsDisabled()
-					.xssProtection()
-		}
-	}
-
-	def "http/headers/xss-protection custom"() {
-		setup:
-			loadConfig(XssProtectionCustomConfig)
-		when:
-			springSecurityFilterChain.doFilter(request,response,chain)
-		then:
-			responseHeaders == ['X-XSS-Protection': '1']
-	}
-
-	@Configuration
-	static class XssProtectionCustomConfig extends BaseWebConfig {
-		@Override
-		protected void configure(HttpSecurity http) {
-			http
-				.headers()
-					// xss-protection@enabled and xss-protection@block
-					.defaultsDisabled()
-					.xssProtection()
-						.xssProtectionEnabled(true)
-						.block(false)
-		}
-	}
-
-	def "http/headers/content-type-options"() {
-		setup:
-			loadConfig(ContentTypeOptionsConfig)
-		when:
-			springSecurityFilterChain.doFilter(request,response,chain)
-		then:
-			responseHeaders == ['X-Content-Type-Options': 'nosniff']
-	}
-
-	@Configuration
-	static class ContentTypeOptionsConfig extends BaseWebConfig {
-		@Override
-		protected void configure(HttpSecurity http) {
-			http
-				.headers()
-					// content-type-options
-					.defaultsDisabled()
-					.contentTypeOptions()
-		}
-	}
-
-	// header@name / header@value are not provided instead use header@ref
-
-	def "http/headers/header@ref"() {
-		setup:
-			loadConfig(HeaderRefConfig)
-		when:
-			springSecurityFilterChain.doFilter(request,response,chain)
-		then:
-			responseHeaders == ['customHeaderName': 'customHeaderValue']
-	}
-
-	@Configuration
-	static class HeaderRefConfig extends BaseWebConfig {
-		@Override
-		protected void configure(HttpSecurity http) {
-			http
-				.headers()
-					.defaultsDisabled()
-					.addHeaderWriter(new StaticHeadersWriter("customHeaderName", "customHeaderValue"))
-		}
-	}
-
-}

+ 0 - 169
config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/NamespaceHttpInterceptUrlTests.groovy

@@ -1,169 +0,0 @@
-/*
- * Copyright 2002-2013 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.annotation.web.configurers
-
-import javax.servlet.http.HttpServletResponse
-
-import org.springframework.context.annotation.Configuration
-import org.springframework.http.HttpMethod;
-import org.springframework.mock.web.MockFilterChain
-import org.springframework.mock.web.MockHttpServletRequest;
-import org.springframework.mock.web.MockHttpServletResponse
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
-import org.springframework.security.config.annotation.BaseSpringSpec
-import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
-import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
-import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
-import org.springframework.security.core.authority.AuthorityUtils;
-import org.springframework.security.core.context.SecurityContextImpl
-import org.springframework.security.web.FilterChainProxy
-import org.springframework.security.web.context.HttpRequestResponseHolder
-import org.springframework.security.web.context.HttpSessionSecurityContextRepository
-
-/**
- * Tests to verify that all the functionality of <intercept-url> attributes is present
- *
- * @author Rob Winch
- *
- */
-public class NamespaceHttpInterceptUrlTests extends BaseSpringSpec {
-
-	def "http/intercept-url denied when not logged in"() {
-		setup:
-			loadConfig(HttpInterceptUrlConfig)
-			request.servletPath == "/users"
-		when:
-			springSecurityFilterChain.doFilter(request,response,chain)
-		then:
-			response.status == HttpServletResponse.SC_FORBIDDEN
-	}
-
-	def "http/intercept-url denied when logged in"() {
-		setup:
-			loadConfig(HttpInterceptUrlConfig)
-			login()
-			request.setServletPath("/users")
-		when:
-			springSecurityFilterChain.doFilter(request,response,chain)
-		then:
-			response.status == HttpServletResponse.SC_FORBIDDEN
-	}
-
-	def "http/intercept-url allowed when logged in"() {
-		setup:
-			loadConfig(HttpInterceptUrlConfig)
-			login("admin","ROLE_ADMIN")
-			request.setServletPath("/users")
-		when:
-			springSecurityFilterChain.doFilter(request,response,chain)
-		then:
-			response.status == HttpServletResponse.SC_OK
-			!response.isCommitted()
-	}
-
-	def "http/intercept-url@method=POST"() {
-		setup:
-			loadConfig(HttpInterceptUrlConfig)
-		when:
-			login()
-			request.setServletPath("/admin/post")
-			springSecurityFilterChain.doFilter(request,response,chain)
-		then:
-			response.status == HttpServletResponse.SC_OK
-			!response.isCommitted()
-		when:
-			super.setup()
-			login()
-			request.setServletPath("/admin/post")
-			request.setMethod("POST")
-			springSecurityFilterChain.doFilter(request,response,chain)
-		then:
-			response.status == HttpServletResponse.SC_FORBIDDEN
-		when:
-			super.setup()
-			login("admin","ROLE_ADMIN")
-			request.setServletPath("/admin/post")
-			request.setMethod("POST")
-			springSecurityFilterChain.doFilter(request,response,chain)
-		then:
-			response.status == HttpServletResponse.SC_OK
-			!response.committed
-	}
-
-	def "http/intercept-url@requires-channel"() {
-		setup:
-			loadConfig(HttpInterceptUrlConfig)
-		when:
-			request.setServletPath("/login")
-			request.setRequestURI("/login")
-			springSecurityFilterChain.doFilter(request,response,chain)
-		then:
-			response.redirectedUrl == "https://localhost/login"
-		when:
-			super.setup()
-			request.setServletPath("/secured/a")
-			request.setRequestURI("/secured/a")
-			springSecurityFilterChain.doFilter(request,response,chain)
-		then:
-			response.redirectedUrl == "https://localhost/secured/a"
-		when:
-			super.setup()
-			request.setSecure(true)
-			request.setScheme("https")
-			request.setServletPath("/user")
-			request.setRequestURI("/user")
-			springSecurityFilterChain.doFilter(request,response,chain)
-		then:
-			response.redirectedUrl == "http://localhost/user"
-	}
-
-	@EnableWebSecurity
-	static class HttpInterceptUrlConfig extends WebSecurityConfigurerAdapter {
-
-		@Override
-		protected void configure(HttpSecurity http) throws Exception {
-			http
-				.authorizeRequests()
-					// the line below is similar to intercept-url@pattern:
-					//    <intercept-url pattern="/users**" access="hasRole('ROLE_ADMIN')"/>
-					//    <intercept-url pattern="/sessions/**" access="hasRole('ROLE_ADMIN')"/>
-					.antMatchers("/users**","/sessions/**").hasRole("ADMIN")
-					// the line below is similar to intercept-url@method:
-					//    <intercept-url pattern="/admin/post" access="hasRole('ROLE_ADMIN')" method="POST"/>
-					//    <intercept-url pattern="/admin/another-post/**" access="hasRole('ROLE_ADMIN')" method="POST"/>
-					.antMatchers(HttpMethod.POST, "/admin/post","/admin/another-post/**").hasRole("ADMIN")
-					.antMatchers("/signup").permitAll()
-					.anyRequest().hasRole("USER")
-					.and()
-				.requiresChannel()
-					// NOTE: channel security is configured separately of authorization (i.e. intercept-url@access
-					// the line below is similar to intercept-url@requires-channel="https":
-					//    <intercept-url pattern="/login" requires-channel="https"/>
-					//    <intercept-url pattern="/secured/**" requires-channel="https"/>
-					.antMatchers("/login","/secured/**").requiresSecure()
-					// the line below is similar to intercept-url@requires-channel="http":
-					//    <intercept-url pattern="/**" requires-channel="http"/>
-					.anyRequest().requiresInsecure()
-		}
-		protected void configure(AuthenticationManagerBuilder auth) throws Exception {
-			auth
-				.inMemoryAuthentication()
-					.withUser("user").password("password").roles("USER").and()
-					.withUser("admin").password("password").roles("USER", "ADMIN")
-		}
-	}
-}

+ 0 - 142
config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/NamespaceHttpJeeTests.groovy

@@ -1,142 +0,0 @@
-/*
- * Copyright 2002-2017 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.annotation.web.configurers;
-
-import java.io.IOException;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Bean
-import org.springframework.context.annotation.Configuration
-import org.springframework.mock.web.MockFilterChain
-import org.springframework.mock.web.MockHttpServletRequest;
-import org.springframework.mock.web.MockHttpServletResponse
-import org.springframework.security.access.AccessDecisionManager
-import org.springframework.security.access.AccessDeniedException;
-import org.springframework.security.access.ConfigAttribute
-import org.springframework.security.authentication.AnonymousAuthenticationToken
-import org.springframework.security.authentication.AuthenticationManager;
-import org.springframework.security.config.annotation.BaseSpringSpec
-import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
-import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
-import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
-import org.springframework.security.core.AuthenticationException;
-import org.springframework.security.core.authority.AuthorityUtils;
-import org.springframework.security.core.userdetails.AuthenticationUserDetailsService;
-import org.springframework.security.core.userdetails.UserDetails;
-import org.springframework.security.core.userdetails.UsernameNotFoundException;
-import org.springframework.security.web.AuthenticationEntryPoint
-import org.springframework.security.web.FilterChainProxy
-import org.springframework.security.web.FilterInvocation
-import org.springframework.security.web.access.AccessDeniedHandler;
-import org.springframework.security.web.access.AccessDeniedHandlerImpl;
-import org.springframework.security.web.access.ExceptionTranslationFilter
-import org.springframework.security.web.access.intercept.FilterSecurityInterceptor
-import org.springframework.security.web.authentication.AnonymousAuthenticationFilter;
-import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
-import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler
-import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
-import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
-import org.springframework.security.web.authentication.WebAuthenticationDetailsSource
-import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider;
-import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
-import org.springframework.security.web.authentication.preauth.PreAuthenticatedGrantedAuthoritiesUserDetailsService;
-import org.springframework.security.web.authentication.preauth.j2ee.J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource;
-import org.springframework.security.web.authentication.preauth.j2ee.J2eePreAuthenticatedProcessingFilter;
-import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
-import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
-import org.springframework.security.web.context.NullSecurityContextRepository;
-import org.springframework.security.web.context.SecurityContextPersistenceFilter
-import org.springframework.security.web.jaasapi.JaasApiIntegrationFilter;
-import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter;
-import org.springframework.security.web.util.matcher.AntPathRequestMatcher
-import org.springframework.security.web.util.matcher.AnyRequestMatcher;
-import org.springframework.security.web.util.matcher.RequestMatcher
-import org.springframework.test.util.ReflectionTestUtils;
-
-/**
- * Tests to verify that all the functionality of <jee> attributes is present
- *
- * @author Rob Winch
- *
- */
-public class NamespaceHttpJeeTests extends BaseSpringSpec {
-
-	def "http/jee@mappable-roles"() {
-		when:
-			loadConfig(JeeMappableRolesConfig)
-			J2eePreAuthenticatedProcessingFilter filter = findFilter(J2eePreAuthenticatedProcessingFilter)
-			AuthenticationManager authenticationManager = ReflectionTestUtils.getField(filter,"authenticationManager")
-		then:
-			authenticationManager
-			filter.authenticationDetailsSource.class == J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource
-			filter.authenticationDetailsSource.j2eeMappableRoles == ["ROLE_USER", "ROLE_ADMIN"] as Set
-			authenticationManager.providers.find { it instanceof PreAuthenticatedAuthenticationProvider }.preAuthenticatedUserDetailsService.class == PreAuthenticatedGrantedAuthoritiesUserDetailsService
-	}
-
-	@EnableWebSecurity
-	public static class JeeMappableRolesConfig extends WebSecurityConfigurerAdapter {
-
-		@Override
-		protected void configure(HttpSecurity http) throws Exception {
-			http
-				.authorizeRequests()
-					.anyRequest().hasRole("USER")
-					.and()
-				.jee()
-					.mappableRoles("USER","ADMIN");
-		}
-	}
-
-	def "http/jee@user-service-ref"() {
-		when:
-			loadConfig(JeeUserServiceRefConfig)
-			J2eePreAuthenticatedProcessingFilter filter = findFilter(J2eePreAuthenticatedProcessingFilter)
-			AuthenticationManager authenticationManager = ReflectionTestUtils.getField(filter,"authenticationManager")
-		then:
-			authenticationManager
-			filter.authenticationDetailsSource.class == J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource
-			filter.authenticationDetailsSource.j2eeMappableRoles == ["ROLE_USER", "ROLE_ADMIN"] as Set
-			authenticationManager.providers.find { it instanceof PreAuthenticatedAuthenticationProvider }.preAuthenticatedUserDetailsService.class == CustomUserService
-	}
-
-	@EnableWebSecurity
-	public static class JeeUserServiceRefConfig extends WebSecurityConfigurerAdapter {
-
-		@Override
-		protected void configure(HttpSecurity http) throws Exception {
-			http
-				.authorizeRequests()
-					.anyRequest().hasRole("USER")
-					.and()
-				.jee()
-					.mappableAuthorities("ROLE_USER","ROLE_ADMIN")
-					.authenticatedUserDetailsService(new CustomUserService());
-		}
-	}
-
-	static class CustomUserService implements AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken> {
-		public UserDetails loadUserDetails(
-				PreAuthenticatedAuthenticationToken token)
-				throws UsernameNotFoundException {
-			return null;
-		}
-	}
-}

+ 0 - 115
config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/NamespaceHttpPortMappingsTests.groovy

@@ -1,115 +0,0 @@
-/*
- * Copyright 2002-2013 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.annotation.web.configurers
-
-import org.springframework.context.annotation.Configuration
-import org.springframework.mock.web.MockFilterChain
-import org.springframework.mock.web.MockHttpServletRequest;
-import org.springframework.mock.web.MockHttpServletResponse
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
-import org.springframework.security.config.annotation.BaseSpringSpec
-import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
-import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
-import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
-import org.springframework.security.core.authority.AuthorityUtils;
-import org.springframework.security.core.context.SecurityContextImpl
-import org.springframework.security.web.FilterChainProxy
-import org.springframework.security.web.context.HttpRequestResponseHolder
-import org.springframework.security.web.context.HttpSessionSecurityContextRepository
-
-/**
- * Tests to verify that all the functionality of <port-mappings> attributes is present
- *
- * @author Rob Winch
- *
- */
-public class NamespaceHttpPortMappingsTests extends BaseSpringSpec {
-	FilterChainProxy springSecurityFilterChain
-	MockHttpServletRequest request
-	MockHttpServletResponse response
-	MockFilterChain chain
-
-	def setup() {
-		request = new MockHttpServletRequest("GET", "")
-		request.setMethod("GET")
-		response = new MockHttpServletResponse()
-		chain = new MockFilterChain()
-	}
-
-	def "http/port-mapper works with http/intercept-url@requires-channel"() {
-		setup:
-			loadConfig(HttpInterceptUrlWithPortMapperConfig)
-			springSecurityFilterChain = context.getBean(FilterChainProxy)
-		when:
-			request.setServletPath("/login")
-			request.setRequestURI("/login")
-			request.setServerPort(9080);
-			springSecurityFilterChain.doFilter(request,response,chain)
-		then:
-			response.redirectedUrl == "https://localhost:9443/login"
-		when:
-			setup()
-			request.setServletPath("/secured/a")
-			request.setRequestURI("/secured/a")
-			request.setServerPort(9080);
-			springSecurityFilterChain.doFilter(request,response,chain)
-		then:
-			response.redirectedUrl == "https://localhost:9443/secured/a"
-		when:
-			setup()
-			request.setSecure(true)
-			request.setScheme("https")
-			request.setServerPort(9443);
-			request.setServletPath("/user")
-			request.setRequestURI("/user")
-			springSecurityFilterChain.doFilter(request,response,chain)
-		then:
-			response.redirectedUrl == "http://localhost:9080/user"
-	}
-
-	@EnableWebSecurity
-	static class HttpInterceptUrlWithPortMapperConfig extends WebSecurityConfigurerAdapter {
-
-		@Override
-		protected void configure(HttpSecurity http) throws Exception {
-			http
-				.authorizeRequests()
-					.anyRequest().hasRole("USER")
-					.and()
-				.portMapper()
-					.http(9080).mapsTo(9443)
-					.and()
-				.requiresChannel()
-					.antMatchers("/login","/secured/**").requiresSecure()
-					.anyRequest().requiresInsecure()
-		}
-
-		protected void configure(AuthenticationManagerBuilder auth) throws Exception {
-			auth
-				.inMemoryAuthentication()
-					.withUser("user").password("password").roles("USER").and()
-					.withUser("admin").password("password").roles("USER", "ADMIN")
-		}
-	}
-
-	def login(String username="user", String role="ROLE_USER") {
-		HttpSessionSecurityContextRepository repo = new HttpSessionSecurityContextRepository()
-		HttpRequestResponseHolder requestResponseHolder = new HttpRequestResponseHolder(request, response)
-		repo.loadContext(requestResponseHolder)
-		repo.saveContext(new SecurityContextImpl(authentication: new UsernamePasswordAuthenticationToken(username, null, AuthorityUtils.createAuthorityList(role))), requestResponseHolder.request, requestResponseHolder.response)
-	}
-}

+ 0 - 73
config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/NamespaceHttpRequestCacheTests.groovy

@@ -1,73 +0,0 @@
-/*
- * Copyright 2002-2013 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.annotation.web.configurers;
-
-import java.io.IOException;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.security.access.AccessDeniedException;
-import org.springframework.security.config.annotation.BaseSpringSpec;
-import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.configuration.BaseWebConfig;
-import org.springframework.security.web.access.AccessDeniedHandler;
-import org.springframework.security.web.access.ExceptionTranslationFilter;
-import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
-import org.springframework.security.web.savedrequest.RequestCache;
-
-/**
- * Tests to verify that all the functionality of <request-cache> attributes is present
- *
- * @author Rob Winch
- *
- */
-public class NamespaceHttpRequestCacheTests extends BaseSpringSpec {
-	def "http/request-cache@ref"() {
-		setup:
-			RequestCacheRefConfig.REQUEST_CACHE = Mock(RequestCache)
-		when:
-			loadConfig(RequestCacheRefConfig)
-		then:
-			findFilter(ExceptionTranslationFilter).requestCache == RequestCacheRefConfig.REQUEST_CACHE
-	}
-
-	@Configuration
-	static class RequestCacheRefConfig extends BaseWebConfig {
-		static RequestCache REQUEST_CACHE
-		protected void configure(HttpSecurity http) {
-			http.
-				requestCache()
-					.requestCache(REQUEST_CACHE)
-		}
-	}
-
-	def "http/request-cache@ref defaults to HttpSessionRequestCache"() {
-		when:
-			loadConfig(DefaultRequestCacheRefConfig)
-		then:
-			findFilter(ExceptionTranslationFilter).requestCache.class == HttpSessionRequestCache
-	}
-
-	@Configuration
-	static class DefaultRequestCacheRefConfig extends BaseWebConfig {
-		protected void configure(HttpSecurity http) {
-		}
-	}
-}

+ 0 - 80
config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/NamespaceHttpServerAccessDeniedHandlerTests.groovy

@@ -1,80 +0,0 @@
-/*
- * Copyright 2002-2013 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.annotation.web.configurers;
-
-import java.io.IOException;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.security.access.AccessDeniedException;
-import org.springframework.security.config.annotation.BaseSpringSpec;
-import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.configuration.BaseWebConfig;
-import org.springframework.security.web.access.AccessDeniedHandler;
-import org.springframework.security.web.access.ExceptionTranslationFilter;
-
-/**
- * Tests to verify that all the functionality of <access-denied-handler> attributes is present
- *
- * @author Rob Winch
- *
- */
-public class NamespaceHttpServerAccessDeniedHandlerTests extends BaseSpringSpec {
-	def "http/access-denied-handler@error-page"() {
-		when:
-		loadConfig(AccessDeniedPageConfig)
-		then:
-		findFilter(ExceptionTranslationFilter).accessDeniedHandler.errorPage == "/AccessDeniedPageConfig"
-	}
-
-	@Configuration
-	static class AccessDeniedPageConfig extends BaseWebConfig {
-		protected void configure(HttpSecurity http) {
-			http.
-				exceptionHandling()
-					.accessDeniedPage("/AccessDeniedPageConfig")
-		}
-	}
-
-	def "http/access-denied-handler@ref"() {
-		when:
-		loadConfig(AccessDeniedHandlerRefConfig)
-		then:
-		findFilter(ExceptionTranslationFilter).accessDeniedHandler.class == AccessDeniedHandlerRefConfig.CustomAccessDeniedHandler
-	}
-
-	@Configuration
-	static class AccessDeniedHandlerRefConfig extends BaseWebConfig {
-		protected void configure(HttpSecurity http) {
-			CustomAccessDeniedHandler accessDeniedHandler = new CustomAccessDeniedHandler()
-			http.
-				exceptionHandling()
-					.accessDeniedHandler(accessDeniedHandler)
-		}
-
-		static class CustomAccessDeniedHandler implements AccessDeniedHandler {
-			public void handle(HttpServletRequest request,
-					HttpServletResponse response,
-					AccessDeniedException accessDeniedException)
-					throws IOException, ServletException {
-			}
-		}
-	}
-}

+ 194 - 0
config/src/test/java/org/springframework/security/config/annotation/web/configurers/NamespaceHttpCustomFilterTests.java

@@ -0,0 +1,194 @@
+/*
+ * Copyright 2002-2019 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.annotation.web.configurers;
+
+
+import java.io.IOException;
+import java.util.List;
+import java.util.stream.Collectors;
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.assertj.core.api.ListAssert;
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.config.test.SpringTestRule;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.provisioning.InMemoryUserDetailsManager;
+import org.springframework.security.web.FilterChainProxy;
+import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
+import org.springframework.web.filter.OncePerRequestFilter;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Tests to verify that all the functionality of <custom-filter> attributes is present
+ *
+ * @author Rob Winch
+ * @author Josh Cummings
+ *
+ */
+public class NamespaceHttpCustomFilterTests {
+
+	@Rule
+	public final SpringTestRule spring = new SpringTestRule();
+
+	@Test
+	public void getFiltersWhenFilterAddedBeforeThenBehaviorMatchesNamespace() {
+		this.spring.register(CustomFilterBeforeConfig.class, UserDetailsServiceConfig.class).autowire();
+		assertThatFilters().containsSubsequence(CustomFilter.class, UsernamePasswordAuthenticationFilter.class);
+	}
+
+	@EnableWebSecurity
+	static class CustomFilterBeforeConfig extends WebSecurityConfigurerAdapter {
+		protected void configure(HttpSecurity http) throws Exception {
+			http
+				.addFilterBefore(new CustomFilter(), UsernamePasswordAuthenticationFilter.class)
+				.formLogin();
+		}
+	}
+
+	@Test
+	public void getFiltersWhenFilterAddedAfterThenBehaviorMatchesNamespace() {
+		this.spring.register(CustomFilterAfterConfig.class, UserDetailsServiceConfig.class).autowire();
+		assertThatFilters().containsSubsequence(UsernamePasswordAuthenticationFilter.class, CustomFilter.class);
+	}
+
+	@EnableWebSecurity
+	static class CustomFilterAfterConfig extends WebSecurityConfigurerAdapter {
+		protected void configure(HttpSecurity http) throws Exception {
+			http
+				.addFilterAfter(new CustomFilter(), UsernamePasswordAuthenticationFilter.class)
+				.formLogin();
+		}
+	}
+
+	@Test
+	public void getFiltersWhenFilterAddedThenBehaviorMatchesNamespace() {
+		this.spring.register(CustomFilterPositionConfig.class, UserDetailsServiceConfig.class).autowire();
+		assertThatFilters().containsExactly(CustomFilter.class);
+	}
+
+	@EnableWebSecurity
+	static class CustomFilterPositionConfig extends WebSecurityConfigurerAdapter {
+		CustomFilterPositionConfig() {
+			// do not add the default filters to make testing easier
+			super(true);
+		}
+
+		protected void configure(HttpSecurity http) throws Exception {
+			http
+				// this works so long as the CustomFilter extends one of the standard filters
+				// if not, use addFilterBefore or addFilterAfter
+				.addFilter(new CustomFilter());
+		}
+	}
+
+
+	@Test
+	public void getFiltersWhenFilterAddedAtPositionThenBehaviorMatchesNamespace() {
+		this.spring.register(CustomFilterPositionAtConfig.class, UserDetailsServiceConfig.class).autowire();
+		assertThatFilters().containsExactly(OtherCustomFilter.class);
+	}
+
+	@EnableWebSecurity
+	static class CustomFilterPositionAtConfig extends WebSecurityConfigurerAdapter {
+		CustomFilterPositionAtConfig() {
+			// do not add the default filters to make testing easier
+			super(true);
+		}
+
+		protected void configure(HttpSecurity http) throws Exception {
+			http
+				.addFilterAt(new OtherCustomFilter(), UsernamePasswordAuthenticationFilter.class);
+		}
+	}
+
+	@Test
+	public void getFiltersWhenCustomAuthenticationManagerThenBehaviorMatchesNamespace() {
+		this.spring.register(NoAuthenticationManagerInHttpConfigurationConfig.class).autowire();
+		assertThatFilters().startsWith(CustomFilter.class);
+	}
+
+	@EnableWebSecurity
+	static class NoAuthenticationManagerInHttpConfigurationConfig extends WebSecurityConfigurerAdapter {
+		NoAuthenticationManagerInHttpConfigurationConfig() {
+			super(true);
+		}
+
+		protected AuthenticationManager authenticationManager()
+				throws Exception {
+			return new CustomAuthenticationManager();
+		}
+
+		@Override
+		protected void configure(HttpSecurity http) throws Exception {
+			http
+				.authorizeRequests()
+					.anyRequest().hasRole("USER")
+					.and()
+				.addFilterBefore(new CustomFilter(), UsernamePasswordAuthenticationFilter.class);
+		}
+	}
+
+	@Configuration
+	static class UserDetailsServiceConfig {
+		@Bean
+		public UserDetailsService userDetailsService() {
+			return new InMemoryUserDetailsManager(
+					User.withDefaultPasswordEncoder()
+							.username("user")
+							.password("password")
+							.roles("USER")
+							.build());
+		}
+	}
+
+	static class CustomFilter extends UsernamePasswordAuthenticationFilter {}
+	static class OtherCustomFilter extends OncePerRequestFilter {
+		protected void doFilterInternal(
+				HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
+		throws ServletException, IOException {
+			filterChain.doFilter(request, response);
+		}
+	}
+
+	static class CustomAuthenticationManager implements AuthenticationManager {
+		public Authentication authenticate(Authentication authentication)
+				throws AuthenticationException {
+			return null;
+		}
+	}
+
+	private ListAssert<Class<?>> assertThatFilters() {
+		FilterChainProxy filterChain = this.spring.getContext().getBean(FilterChainProxy.class);
+		List<Class<?>> filters = filterChain.getFilters("/").stream()
+				.map(Object::getClass).collect(Collectors.toList());
+		return assertThat(filters);
+	}
+}

+ 104 - 0
config/src/test/java/org/springframework/security/config/annotation/web/configurers/NamespaceHttpFirewallTests.java

@@ -0,0 +1,104 @@
+/*
+ * Copyright 2002-2013 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.annotation.web.configurers;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.security.config.annotation.web.builders.WebSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.config.test.SpringTestRule;
+import org.springframework.security.web.firewall.DefaultHttpFirewall;
+import org.springframework.security.web.firewall.FirewalledRequest;
+import org.springframework.security.web.firewall.HttpFirewall;
+import org.springframework.security.web.firewall.RequestRejectedException;
+import org.springframework.test.web.servlet.MockMvc;
+
+import static org.assertj.core.api.Assertions.assertThatCode;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+
+/**
+ * Tests to verify that all the functionality of <http-firewall> attributes is present
+ *
+ * @author Rob Winch
+ * @author Josh Cummings
+ */
+public class NamespaceHttpFirewallTests {
+
+	@Rule
+	public final SpringTestRule rule = new SpringTestRule();
+
+	@Autowired
+	MockMvc mvc;
+
+	@Test
+	public void requestWhenPathContainsDoubleDotsThenBehaviorMatchesNamespace() throws Exception {
+		this.rule.register(HttpFirewallConfig.class).autowire();
+		assertThatCode(() -> this.mvc.perform(get("/public/../private/")))
+				.isInstanceOf(RequestRejectedException.class);
+	}
+
+	@EnableWebSecurity
+	static class HttpFirewallConfig {}
+
+	@Test
+	public void requestWithCustomFirewallThenBehaviorMatchesNamespace() {
+		this.rule.register(CustomHttpFirewallConfig.class).autowire();
+		assertThatCode(() -> this.mvc.perform(get("/").param("deny", "true")))
+				.isInstanceOf(RequestRejectedException.class);
+	}
+
+	@EnableWebSecurity
+	static class CustomHttpFirewallConfig extends WebSecurityConfigurerAdapter {
+		@Override
+		public void configure(WebSecurity web) throws Exception {
+			web
+				.httpFirewall(new CustomHttpFirewall());
+		}
+	}
+
+	@Test
+	public void requestWithCustomFirewallBeanThenBehaviorMatchesNamespace() {
+		this.rule.register(CustomHttpFirewallBeanConfig.class).autowire();
+		assertThatCode(() -> this.mvc.perform(get("/").param("deny", "true")))
+				.isInstanceOf(RequestRejectedException.class);
+	}
+
+	@EnableWebSecurity
+	static class CustomHttpFirewallBeanConfig {
+		@Bean
+		HttpFirewall firewall() {
+			return new CustomHttpFirewall();
+		}
+	}
+
+	static class CustomHttpFirewall extends DefaultHttpFirewall {
+
+		@Override
+		public FirewalledRequest getFirewalledRequest(HttpServletRequest request)
+				throws RequestRejectedException {
+			if (request.getParameter("deny") != null) {
+				throw new RequestRejectedException("custom rejection");
+			}
+			return super.getFirewalledRequest(request);
+		}
+	}
+}

+ 197 - 0
config/src/test/java/org/springframework/security/config/annotation/web/configurers/NamespaceHttpFormLoginTests.java

@@ -0,0 +1,197 @@
+/*
+ * Copyright 2002-2019 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.annotation.web.configurers;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.builders.WebSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.config.test.SpringTestRule;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.provisioning.InMemoryUserDetailsManager;
+import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
+import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
+import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
+import org.springframework.test.web.servlet.MockMvc;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl;
+
+/**
+ * Tests to verify that all the functionality of <form-login> attributes is present
+ *
+ * @author Rob Winch
+ * @author Josh Cummings
+ *
+ */
+public class NamespaceHttpFormLoginTests {
+
+	@Rule
+	public final SpringTestRule spring = new SpringTestRule();
+
+	@Autowired
+	MockMvc mvc;
+
+
+	@Test
+	public void formLoginWhenDefaultConfigurationThenMatchesNamespace() throws Exception {
+		this.spring.register(FormLoginConfig.class, UserDetailsServiceConfig.class).autowire();
+
+		this.mvc.perform(get("/"))
+				.andExpect(redirectedUrl("http://localhost/login"));
+
+		this.mvc.perform(post("/login")
+				.with(csrf()))
+				.andExpect(redirectedUrl("/login?error"));
+
+		this.mvc.perform(post("/login")
+				.param("username", "user")
+				.param("password", "password")
+				.with(csrf()))
+				.andExpect(redirectedUrl("/"));
+	}
+
+	@EnableWebSecurity
+	static class FormLoginConfig extends WebSecurityConfigurerAdapter {
+
+		@Override
+		public void configure(WebSecurity web) throws Exception {
+			web
+				.ignoring()
+					.antMatchers("/resources/**");
+		}
+
+		@Override
+		protected void configure(HttpSecurity http) throws Exception {
+			http
+				.authorizeRequests()
+					.anyRequest().hasRole("USER")
+					.and()
+				.formLogin();
+		}
+	}
+
+	@Test
+	public void formLoginWithCustomEndpointsThenBehaviorMatchesNamespace() throws Exception {
+		this.spring.register(FormLoginCustomConfig.class, UserDetailsServiceConfig.class).autowire();
+
+		this.mvc.perform(get("/"))
+				.andExpect(redirectedUrl("http://localhost/authentication/login"));
+
+		this.mvc.perform(post("/authentication/login/process")
+				.with(csrf()))
+				.andExpect(redirectedUrl("/authentication/login?failed"));
+
+		this.mvc.perform(post("/authentication/login/process")
+				.param("username", "user")
+				.param("password", "password")
+				.with(csrf()))
+				.andExpect(redirectedUrl("/default"));
+	}
+
+	@EnableWebSecurity
+	static class FormLoginCustomConfig extends WebSecurityConfigurerAdapter {
+		protected void configure(HttpSecurity http) throws Exception {
+			boolean alwaysUseDefaultSuccess = true;
+			http
+				.authorizeRequests()
+					.anyRequest().hasRole("USER")
+					.and()
+				.formLogin()
+					.usernameParameter("username") // form-login@username-parameter
+					.passwordParameter("password") // form-login@password-parameter
+					.loginPage("/authentication/login") // form-login@login-page
+					.failureUrl("/authentication/login?failed") // form-login@authentication-failure-url
+					.loginProcessingUrl("/authentication/login/process") // form-login@login-processing-url
+					.defaultSuccessUrl("/default", alwaysUseDefaultSuccess); // form-login@default-target-url / form-login@always-use-default-target
+		}
+	}
+
+	@Test
+	public void formLoginWithCustomHandlersThenBehaviorMatchesNamespace() throws Exception {
+		this.spring.register(FormLoginCustomRefsConfig.class, UserDetailsServiceConfig.class).autowire();
+
+		this.mvc.perform(get("/"))
+				.andExpect(redirectedUrl("http://localhost/login"));
+
+		this.mvc.perform(post("/login")
+				.with(csrf()))
+				.andExpect(redirectedUrl("/custom/failure"));
+		verifyBean(WebAuthenticationDetailsSource.class).buildDetails(any(HttpServletRequest.class));
+
+		this.mvc.perform(post("/login")
+				.param("username", "user")
+				.param("password", "password")
+				.with(csrf()))
+				.andExpect(redirectedUrl("/custom/targetUrl"));
+	}
+
+	@EnableWebSecurity
+	static class FormLoginCustomRefsConfig extends WebSecurityConfigurerAdapter {
+		protected void configure(HttpSecurity http) throws Exception {
+			SavedRequestAwareAuthenticationSuccessHandler successHandler =
+					new SavedRequestAwareAuthenticationSuccessHandler();
+			successHandler.setDefaultTargetUrl("/custom/targetUrl");
+
+			http
+				.authorizeRequests()
+					.anyRequest().hasRole("USER")
+					.and()
+				.formLogin()
+					.loginPage("/login")
+					.failureHandler(new SimpleUrlAuthenticationFailureHandler("/custom/failure")) // form-login@authentication-failure-handler-ref
+					.successHandler(successHandler) // form-login@authentication-success-handler-ref
+					.authenticationDetailsSource(authenticationDetailsSource()) // form-login@authentication-details-source-ref
+					.and();
+		}
+
+		@Bean
+		WebAuthenticationDetailsSource authenticationDetailsSource() {
+			return spy(WebAuthenticationDetailsSource.class);
+		}
+	}
+
+	@Configuration
+	static class UserDetailsServiceConfig {
+		@Bean
+		public UserDetailsService userDetailsService() {
+			return new InMemoryUserDetailsManager(
+					User.withDefaultPasswordEncoder()
+							.username("user")
+							.password("password")
+							.roles("USER")
+							.build());
+		}
+	}
+
+	private <T> T verifyBean(Class<T> beanClass) {
+		return verify(this.spring.getContext().getBean(beanClass));
+	}
+}

+ 293 - 0
config/src/test/java/org/springframework/security/config/annotation/web/configurers/NamespaceHttpHeadersTests.java

@@ -0,0 +1,293 @@
+/*
+ * Copyright 2002-2019 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.annotation.web.configurers;
+
+import java.net.URI;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.config.test.SpringTestRule;
+import org.springframework.security.web.header.writers.StaticHeadersWriter;
+import org.springframework.security.web.header.writers.frameoptions.StaticAllowFromStrategy;
+import org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter;
+import org.springframework.security.web.util.matcher.AnyRequestMatcher;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.ResultMatcher;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
+
+/**
+ * Tests to verify that all the functionality of <headers> attributes is present
+ *
+ * @author Rob Winch
+ * @author Josh Cummings
+ *
+ */
+public class NamespaceHttpHeadersTests {
+	static final Map<String, String> defaultHeaders = new LinkedHashMap<>();
+
+	static {
+		defaultHeaders.put("X-Content-Type-Options", "nosniff");
+		defaultHeaders.put("X-Frame-Options", "DENY");
+		defaultHeaders.put("Strict-Transport-Security", "max-age=31536000 ; includeSubDomains");
+		defaultHeaders.put("Cache-Control", "no-cache, no-store, max-age=0, must-revalidate");
+		defaultHeaders.put("Expires", "0");
+		defaultHeaders.put("Pragma", "no-cache");
+		defaultHeaders.put("X-XSS-Protection", "1; mode=block");
+	}
+
+	@Rule
+	public final SpringTestRule spring = new SpringTestRule();
+
+	@Autowired
+	MockMvc mvc;
+
+	@Test
+	public void secureRequestWhenDefaultConfigThenBehaviorMatchesNamespace() throws Exception {
+		this.spring.register(HeadersDefaultConfig.class).autowire();
+
+		this.mvc.perform(get("/").secure(true))
+				.andExpect(includesDefaults());
+	}
+
+	@EnableWebSecurity
+	static class HeadersDefaultConfig extends WebSecurityConfigurerAdapter {
+		@Override
+		protected void configure(HttpSecurity http) throws Exception {
+			http
+				.headers();
+		}
+	}
+
+	@Test
+	public void secureRequestWhenCacheControlOnlyThenBehaviorMatchesNamespace() throws Exception {
+		this.spring.register(HeadersCacheControlConfig.class).autowire();
+
+		this.mvc.perform(get("/").secure(true))
+				.andExpect(includes("Cache-Control", "Expires", "Pragma"));
+	}
+
+	@EnableWebSecurity
+	static class HeadersCacheControlConfig extends WebSecurityConfigurerAdapter {
+		@Override
+		protected void configure(HttpSecurity http) throws Exception {
+			http
+				.headers()
+					.defaultsDisabled()
+					.cacheControl();
+		}
+	}
+
+	@Test
+	public void secureRequestWhenHstsOnlyThenBehaviorMatchesNamespace() throws Exception {
+		this.spring.register(HstsConfig.class).autowire();
+
+		this.mvc.perform(get("/").secure(true))
+				.andExpect(includes("Strict-Transport-Security"));
+	}
+
+	@EnableWebSecurity
+	static class HstsConfig extends WebSecurityConfigurerAdapter {
+		@Override
+		protected void configure(HttpSecurity http) throws Exception {
+			http
+				.headers()
+					.defaultsDisabled()
+					.httpStrictTransportSecurity();
+		}
+	}
+
+	@Test
+	public void requestWhenHstsCustomThenBehaviorMatchesNamespace() throws Exception {
+		this.spring.register(HstsCustomConfig.class).autowire();
+
+		this.mvc.perform(get("/"))
+				.andExpect(includes(Collections.singletonMap("Strict-Transport-Security", "max-age=15768000")));
+	}
+
+	@EnableWebSecurity
+	static class HstsCustomConfig extends WebSecurityConfigurerAdapter {
+		@Override
+		protected void configure(HttpSecurity http) throws Exception {
+			http
+				.headers()
+					// hsts@request-matcher-ref, hsts@max-age-seconds, hsts@include-subdomains
+					.defaultsDisabled()
+					.httpStrictTransportSecurity()
+						.requestMatcher(AnyRequestMatcher.INSTANCE)
+						.maxAgeInSeconds(15768000)
+						.includeSubDomains(false);
+		}
+	}
+
+	@Test
+	public void requestWhenFrameOptionsSameOriginThenBehaviorMatchesNamespace() throws Exception {
+		this.spring.register(FrameOptionsSameOriginConfig.class).autowire();
+
+		this.mvc.perform(get("/"))
+				.andExpect(includes(Collections.singletonMap("X-Frame-Options", "SAMEORIGIN")));
+	}
+
+	@EnableWebSecurity
+	static class FrameOptionsSameOriginConfig extends WebSecurityConfigurerAdapter {
+		@Override
+		protected void configure(HttpSecurity http) throws Exception {
+			http
+				.headers()
+					// frame-options@policy=SAMEORIGIN
+					.defaultsDisabled()
+					.frameOptions()
+						.sameOrigin();
+		}
+	}
+
+	// frame-options@strategy, frame-options@value, frame-options@parameter are not provided instead use frame-options@ref
+
+	@Test
+	public void requestWhenFrameOptionsAllowFromThenBehaviorMatchesNamespace() throws Exception {
+		this.spring.register(FrameOptionsAllowFromConfig.class).autowire();
+
+		this.mvc.perform(get("/"))
+				.andExpect(includes(Collections.singletonMap("X-Frame-Options", "ALLOW-FROM https://example.com")));
+	}
+
+	@EnableWebSecurity
+	static class FrameOptionsAllowFromConfig extends WebSecurityConfigurerAdapter {
+		@Override
+		protected void configure(HttpSecurity http) throws Exception {
+			http
+				.headers()
+					// frame-options@ref
+					.defaultsDisabled()
+					.addHeaderWriter(new XFrameOptionsHeaderWriter(
+							new StaticAllowFromStrategy(URI.create("https://example.com"))));
+		}
+	}
+
+	@Test
+	public void requestWhenXssOnlyThenBehaviorMatchesNamespace() throws Exception {
+		this.spring.register(XssProtectionConfig.class).autowire();
+
+		this.mvc.perform(get("/"))
+				.andExpect(includes("X-XSS-Protection"));
+	}
+
+	@EnableWebSecurity
+	static class XssProtectionConfig extends WebSecurityConfigurerAdapter {
+		@Override
+		protected void configure(HttpSecurity http) throws Exception {
+			http
+				.headers()
+					// xss-protection
+					.defaultsDisabled()
+					.xssProtection();
+		}
+	}
+
+	@Test
+	public void requestWhenXssCustomThenBehaviorMatchesNamespace() throws Exception {
+		this.spring.register(XssProtectionCustomConfig.class).autowire();
+
+		this.mvc.perform(get("/"))
+				.andExpect(includes(Collections.singletonMap("X-XSS-Protection", "1")));
+	}
+
+	@EnableWebSecurity
+	static class XssProtectionCustomConfig extends WebSecurityConfigurerAdapter {
+		@Override
+		protected void configure(HttpSecurity http) throws Exception {
+			http
+				.headers()
+					// xss-protection@enabled and xss-protection@block
+					.defaultsDisabled()
+					.xssProtection()
+						.xssProtectionEnabled(true)
+						.block(false);
+		}
+	}
+
+	@Test
+	public void requestWhenXContentTypeOptionsOnlyThenBehaviorMatchesNamespace() throws Exception {
+		this.spring.register(ContentTypeOptionsConfig.class).autowire();
+
+		this.mvc.perform(get("/"))
+				.andExpect(includes("X-Content-Type-Options"));
+	}
+
+	@EnableWebSecurity
+	static class ContentTypeOptionsConfig extends WebSecurityConfigurerAdapter {
+		@Override
+		protected void configure(HttpSecurity http) throws Exception {
+			http
+				.headers()
+					// content-type-options
+					.defaultsDisabled()
+					.contentTypeOptions();
+		}
+	}
+
+	// header@name / header@value are not provided instead use header@ref
+
+	@Test
+	public void requestWhenCustomHeaderOnlyThenBehaviorMatchesNamespace() throws Exception {
+		this.spring.register(HeaderRefConfig.class).autowire();
+
+		this.mvc.perform(get("/"))
+				.andExpect(includes(Collections.singletonMap("customHeaderName", "customHeaderValue")));
+	}
+
+	@EnableWebSecurity
+	static class HeaderRefConfig extends WebSecurityConfigurerAdapter {
+		@Override
+		protected void configure(HttpSecurity http) throws Exception {
+			http
+				.headers()
+					.defaultsDisabled()
+					.addHeaderWriter(new StaticHeadersWriter("customHeaderName", "customHeaderValue"));
+		}
+	}
+
+	private static ResultMatcher includesDefaults() {
+		return includes(defaultHeaders);
+	}
+
+	private static ResultMatcher includes(String... headerNames) {
+		return includes(defaultHeaders, headerNames);
+	}
+
+	private static ResultMatcher includes(Map<String, String> headers) {
+		return includes(headers, headers.keySet().toArray(new String[headers.size()]));
+	}
+
+	private static ResultMatcher includes(Map<String, String> headers, String... headerNames) {
+		return result -> {
+			assertThat(result.getResponse().getHeaderNames()).hasSameSizeAs(headerNames);
+			for (String headerName : headerNames) {
+				header().string(headerName, headers.get(headerName)).match(result);
+			}
+		};
+	}
+}

+ 187 - 0
config/src/test/java/org/springframework/security/config/annotation/web/configurers/NamespaceHttpInterceptUrlTests.java

@@ -0,0 +1,187 @@
+/*
+ * Copyright 2002-2019 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.annotation.web.configurers;
+
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpMethod;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.config.test.SpringTestRule;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.authority.AuthorityUtils;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.authentication;
+import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+/**
+ * Tests to verify that all the functionality of <intercept-url> attributes is present
+ *
+ * @author Rob Winch
+ * @author Josh Cummings
+ *
+ */
+public class NamespaceHttpInterceptUrlTests {
+
+	@Rule
+	public final SpringTestRule spring = new SpringTestRule();
+
+	@Autowired
+	MockMvc mvc;
+
+	@Test
+	public void unauthenticatedRequestWhenUrlRequiresAuthenticationThenBehaviorMatchesNamespace() throws Exception {
+		this.spring.register(HttpInterceptUrlConfig.class).autowire();
+
+		this.mvc.perform(get("/users"))
+				.andExpect(status().isForbidden());
+	}
+
+	@Test
+	public void authenticatedRequestWhenUrlRequiresElevatedPrivilegesThenBehaviorMatchesNamespace() throws Exception {
+		this.spring.register(HttpInterceptUrlConfig.class).autowire();
+
+
+		this.mvc.perform(get("/users")
+				.with(authentication(user("ROLE_USER"))))
+				.andExpect(status().isForbidden());
+	}
+
+	@Test
+	public void authenticatedRequestWhenAuthorizedThenBehaviorMatchesNamespace() throws Exception {
+		this.spring.register(HttpInterceptUrlConfig.class, BaseController.class).autowire();
+
+		this.mvc.perform(get("/users")
+				.with(authentication(user("ROLE_ADMIN"))))
+				.andExpect(status().isOk())
+				.andReturn();
+	}
+
+	@Test
+	public void requestWhenMappedByPostInterceptUrlThenBehaviorMatchesNamespace() throws Exception {
+		this.spring.register(HttpInterceptUrlConfig.class, BaseController.class).autowire();
+
+		this.mvc.perform(get("/admin/post")
+				.with(authentication(user("ROLE_USER"))))
+				.andExpect(status().isOk());
+
+		this.mvc.perform(post("/admin/post")
+				.with(authentication(user("ROLE_USER"))))
+				.andExpect(status().isForbidden());
+
+		this.mvc.perform(post("/admin/post")
+				.with(csrf())
+				.with(authentication(user("ROLE_ADMIN"))))
+				.andExpect(status().isOk());
+	}
+
+	@Test
+	public void requestWhenRequiresChannelThenBehaviorMatchesNamespace() throws Exception {
+		this.spring.register(HttpInterceptUrlConfig.class).autowire();
+
+		this.mvc.perform(get("/login"))
+				.andExpect(redirectedUrl("https://localhost/login"));
+
+		this.mvc.perform(get("/secured/a"))
+				.andExpect(redirectedUrl("https://localhost/secured/a"));
+
+		this.mvc.perform(get("https://localhost/user"))
+				.andExpect(redirectedUrl("http://localhost/user"));
+	}
+
+	@EnableWebSecurity
+	static class HttpInterceptUrlConfig extends WebSecurityConfigurerAdapter {
+
+		@Override
+		protected void configure(HttpSecurity http) throws Exception {
+			http
+				.authorizeRequests()
+					// the line below is similar to intercept-url@pattern:
+					//    <intercept-url pattern="/users**" access="hasRole('ROLE_ADMIN')"/>
+					//    <intercept-url pattern="/sessions/**" access="hasRole('ROLE_ADMIN')"/>
+					.antMatchers("/users**", "/sessions/**").hasRole("ADMIN")
+					// the line below is similar to intercept-url@method:
+					//    <intercept-url pattern="/admin/post" access="hasRole('ROLE_ADMIN')" method="POST"/>
+					//    <intercept-url pattern="/admin/another-post/**" access="hasRole('ROLE_ADMIN')" method="POST"/>
+					.antMatchers(HttpMethod.POST, "/admin/post", "/admin/another-post/**").hasRole("ADMIN")
+					.antMatchers("/signup").permitAll()
+					.anyRequest().hasRole("USER")
+					.and()
+				.requiresChannel()
+					// NOTE: channel security is configured separately of authorization (i.e. intercept-url@access
+					// the line below is similar to intercept-url@requires-channel="https":
+					//    <intercept-url pattern="/login" requires-channel="https"/>
+					//    <intercept-url pattern="/secured/**" requires-channel="https"/>
+					.antMatchers("/login", "/secured/**").requiresSecure()
+					// the line below is similar to intercept-url@requires-channel="http":
+					//    <intercept-url pattern="/**" requires-channel="http"/>
+					.anyRequest().requiresInsecure();
+		}
+
+		protected void configure(AuthenticationManagerBuilder auth) throws Exception {
+			auth
+				.inMemoryAuthentication()
+					.withUser("user").password("password").roles("USER").and()
+					.withUser("admin").password("password").roles("USER", "ADMIN");
+		}
+	}
+
+	@RestController
+	static class BaseController {
+		@GetMapping("/users")
+		public String users() {
+			return "ok";
+		}
+
+		@GetMapping("/sessions")
+		public String sessions() {
+			return "sessions";
+		}
+
+		@RequestMapping("/admin/post")
+		public String adminPost() {
+			return "adminPost";
+		}
+
+		@GetMapping("/admin/another-post")
+		public String adminAnotherPost() {
+			return "adminAnotherPost";
+		}
+
+		@GetMapping("/signup")
+		public String signup() {
+			return "signup";
+		}
+	}
+
+	private static Authentication user(String role) {
+		return new UsernamePasswordAuthenticationToken("user", null, AuthorityUtils.createAuthorityList(role));
+	}
+
+}

+ 159 - 0
config/src/test/java/org/springframework/security/config/annotation/web/configurers/NamespaceHttpJeeTests.java

@@ -0,0 +1,159 @@
+/*
+ * Copyright 2002-2019 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.annotation.web.configurers;
+
+
+import java.security.Principal;
+import java.util.stream.Collectors;
+
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.config.test.SpringTestRule;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.authority.AuthorityUtils;
+import org.springframework.security.core.userdetails.AuthenticationUserDetailsService;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+/**
+ * Tests to verify that all the functionality of <jee> attributes is present
+ *
+ * @author Rob Winch
+ * @author Josh Cummings
+ *
+ */
+public class NamespaceHttpJeeTests {
+
+	@Rule
+	public final SpringTestRule spring = new SpringTestRule();
+
+	@Autowired
+	MockMvc mvc;
+
+	@Test
+	public void requestWhenJeeUserThenBehaviorDiffersFromNamespaceForRoleNames() throws Exception {
+		this.spring.register(JeeMappableRolesConfig.class, BaseController.class).autowire();
+
+		Principal user = mock(Principal.class);
+		when(user.getName()).thenReturn("joe");
+
+		this.mvc.perform(get("/roles")
+				.principal(user)
+				.with(request -> {
+					request.addUserRole("ROLE_admin");
+					request.addUserRole("ROLE_user");
+					request.addUserRole("ROLE_unmapped");
+					return request;
+				}))
+				.andExpect(status().isOk())
+				.andExpect(content().string("ROLE_admin,ROLE_user"));
+	}
+
+	@EnableWebSecurity
+	public static class JeeMappableRolesConfig extends WebSecurityConfigurerAdapter {
+
+		@Override
+		protected void configure(HttpSecurity http) throws Exception {
+			http
+				.authorizeRequests()
+					.anyRequest().hasRole("user")
+					.and()
+				.jee()
+					.mappableRoles("user", "admin");
+		}
+	}
+
+	@Test
+	public void requestWhenCustomAuthenticatedUserDetailsServiceThenBehaviorMatchesNamespace() throws Exception {
+		this.spring.register(JeeUserServiceRefConfig.class, BaseController.class).autowire();
+
+		Principal user = mock(Principal.class);
+		when(user.getName()).thenReturn("joe");
+
+		User result = new User(user.getName(), "N/A", true, true, true, true,
+				AuthorityUtils.createAuthorityList("ROLE_user"));
+
+		when(bean(AuthenticationUserDetailsService.class).loadUserDetails(any()))
+				.thenReturn(result);
+
+		this.mvc.perform(get("/roles")
+				.principal(user))
+				.andExpect(status().isOk())
+				.andExpect(content().string("ROLE_user"));
+
+		verifyBean(AuthenticationUserDetailsService.class).loadUserDetails(any());
+	}
+
+	@EnableWebSecurity
+	public static class JeeUserServiceRefConfig extends WebSecurityConfigurerAdapter {
+		private final AuthenticationUserDetailsService authenticationUserDetailsService =
+				mock(AuthenticationUserDetailsService.class);
+
+		@Override
+		protected void configure(HttpSecurity http) throws Exception {
+			http
+				.authorizeRequests()
+					.anyRequest().hasRole("user")
+					.and()
+				.jee()
+					.mappableAuthorities("ROLE_user", "ROLE_admin")
+					.authenticatedUserDetailsService(this.authenticationUserDetailsService);
+		}
+
+		@Bean
+		public AuthenticationUserDetailsService authenticationUserDetailsService() {
+			return this.authenticationUserDetailsService;
+		}
+	}
+
+	@RestController
+	static class BaseController {
+		@GetMapping("/authenticated")
+		public String authenticated(Authentication authentication) {
+			return authentication.getName();
+		}
+
+		@GetMapping("/roles")
+		public String roles(Authentication authentication) {
+			return authentication.getAuthorities().stream()
+					.map(Object::toString).collect(Collectors.joining(","));
+		}
+	}
+
+	private <T> T bean(Class<T> beanClass) {
+		return this.spring.getContext().getBean(beanClass);
+	}
+
+	private <T> T verifyBean(Class<T> beanClass) {
+		return verify(this.spring.getContext().getBean(beanClass));
+	}
+}

+ 86 - 0
config/src/test/java/org/springframework/security/config/annotation/web/configurers/NamespaceHttpPortMappingsTests.java

@@ -0,0 +1,86 @@
+/*
+ * Copyright 2002-2019 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.annotation.web.configurers;
+
+
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.config.test.SpringTestRule;
+import org.springframework.test.web.servlet.MockMvc;
+
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl;
+
+/**
+ * Tests to verify that all the functionality of <port-mappings> attributes is present
+ *
+ * @author Rob Winch
+ * @author Josh Cummings
+ *
+ */
+public class NamespaceHttpPortMappingsTests {
+
+	@Rule
+	public final SpringTestRule spring = new SpringTestRule();
+
+	@Autowired
+	MockMvc mvc;
+
+	@Test
+	public void portMappingWhenRequestRequiresChannelThenBehaviorMatchesNamespace() throws Exception {
+		this.spring.register(HttpInterceptUrlWithPortMapperConfig.class).autowire();
+
+		this.mvc.perform(get("http://localhost:9080/login"))
+				.andExpect(redirectedUrl("https://localhost:9443/login"));
+
+		this.mvc.perform(get("http://localhost:9080/secured/a"))
+				.andExpect(redirectedUrl("https://localhost:9443/secured/a"));
+
+		this.mvc.perform(get("https://localhost:9443/user"))
+				.andExpect(redirectedUrl("http://localhost:9080/user"));
+	}
+
+	@EnableWebSecurity
+	static class HttpInterceptUrlWithPortMapperConfig extends WebSecurityConfigurerAdapter {
+
+		@Override
+		protected void configure(HttpSecurity http) throws Exception {
+			http
+				.authorizeRequests()
+					.anyRequest().hasRole("USER")
+					.and()
+				.portMapper()
+					.http(9080).mapsTo(9443)
+					.and()
+				.requiresChannel()
+					.antMatchers("/login", "/secured/**").requiresSecure()
+					.anyRequest().requiresInsecure();
+		}
+
+		protected void configure(AuthenticationManagerBuilder auth) throws Exception {
+			auth
+				.inMemoryAuthentication()
+					.withUser("user").password("password").roles("USER").and()
+					.withUser("admin").password("password").roles("USER", "ADMIN");
+		}
+	}
+}

+ 123 - 0
config/src/test/java/org/springframework/security/config/annotation/web/configurers/NamespaceHttpRequestCacheTests.java

@@ -0,0 +1,123 @@
+/*
+ * Copyright 2002-2019 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.annotation.web.configurers;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.config.test.SpringTestRule;
+import org.springframework.security.core.userdetails.PasswordEncodedUser;
+import org.springframework.security.web.savedrequest.RequestCache;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.MvcResult;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+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.status;
+
+/**
+ * Tests to verify that all the functionality of <request-cache> attributes is present
+ *
+ * @author Rob Winch
+ * @author Josh Cummings
+ *
+ */
+public class NamespaceHttpRequestCacheTests {
+
+	@Rule
+	public final SpringTestRule spring = new SpringTestRule();
+
+	@Autowired
+	MockMvc mvc;
+
+	@Test
+	public void requestWhenCustomRequestCacheThenBehaviorMatchesNamespace() throws Exception {
+		this.spring.register(RequestCacheRefConfig.class).autowire();
+		this.mvc.perform(get("/"))
+				.andExpect(status().isForbidden());
+		verifyBean(RequestCache.class).saveRequest(any(HttpServletRequest.class), any(HttpServletResponse.class));
+	}
+
+	@EnableWebSecurity
+	static class RequestCacheRefConfig extends WebSecurityConfigurerAdapter {
+		protected void configure(HttpSecurity http) throws Exception {
+			http
+				.authorizeRequests()
+					.anyRequest().authenticated()
+					.and()
+				.requestCache()
+					.requestCache(requestCache());
+		}
+
+		protected void configure(AuthenticationManagerBuilder auth) throws Exception {
+			auth
+					.inMemoryAuthentication()
+					.withUser(PasswordEncodedUser.user())
+					.withUser(PasswordEncodedUser.admin());
+		}
+
+		@Bean
+		public RequestCache requestCache() {
+			return mock(RequestCache.class);
+		}
+	}
+
+	@Test
+	public void requestWhenDefaultConfigurationThenUsesHttpSessionRequestCache() throws Exception {
+		this.spring.register(DefaultRequestCacheRefConfig.class).autowire();
+
+		MvcResult result = this.mvc.perform(get("/"))
+				.andExpect(status().isForbidden())
+				.andReturn();
+
+		HttpSession session = result.getRequest().getSession(false);
+		assertThat(session).isNotNull();
+		assertThat(session.getAttribute("SPRING_SECURITY_SAVED_REQUEST")).isNotNull();
+	}
+
+	@EnableWebSecurity
+	static class DefaultRequestCacheRefConfig extends WebSecurityConfigurerAdapter {
+		protected void configure(HttpSecurity http) throws Exception {
+			http
+				.authorizeRequests()
+					.anyRequest().authenticated();
+		}
+
+		protected void configure(AuthenticationManagerBuilder auth) throws Exception {
+			auth
+				.inMemoryAuthentication()
+					.withUser(PasswordEncodedUser.user())
+					.withUser(PasswordEncodedUser.admin());
+		}
+	}
+
+	private <T> T verifyBean(Class<T> beanClass) {
+		return verify(this.spring.getContext().getBean(beanClass));
+	}
+}

+ 115 - 0
config/src/test/java/org/springframework/security/config/annotation/web/configurers/NamespaceHttpServerAccessDeniedHandlerTests.java

@@ -0,0 +1,115 @@
+/*
+ * Copyright 2002-2019 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.annotation.web.configurers;
+
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.security.access.AccessDeniedException;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.config.test.SpringTestRule;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.authority.AuthorityUtils;
+import org.springframework.security.web.access.AccessDeniedHandler;
+import org.springframework.test.web.servlet.MockMvc;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.authentication;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.forwardedUrl;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+/**
+ * Tests to verify that all the functionality of <access-denied-handler> attributes is present
+ *
+ * @author Rob Winch
+ * @author Josh Cummings
+ *
+ */
+public class NamespaceHttpServerAccessDeniedHandlerTests {
+
+	@Rule
+	public final SpringTestRule spring = new SpringTestRule();
+
+	@Autowired
+	MockMvc mvc;
+
+	@Test
+	public void requestWhenCustomAccessDeniedPageThenBehaviorMatchesNamespace() throws Exception {
+		this.spring.register(AccessDeniedPageConfig.class).autowire();
+		this.mvc.perform(get("/")
+				.with(authentication(user())))
+				.andExpect(status().isForbidden())
+				.andExpect(forwardedUrl("/AccessDeniedPageConfig"));
+	}
+
+	@EnableWebSecurity
+	static class AccessDeniedPageConfig extends WebSecurityConfigurerAdapter {
+		protected void configure(HttpSecurity http) throws Exception {
+			http
+				.authorizeRequests()
+					.anyRequest().denyAll()
+					.and()
+				.exceptionHandling()
+					.accessDeniedPage("/AccessDeniedPageConfig");
+		}
+	}
+
+	private static Authentication user() {
+		return new UsernamePasswordAuthenticationToken("user", null, AuthorityUtils.NO_AUTHORITIES);
+	}
+
+	@Test
+	public void requestWhenCustomAccessDeniedHandlerThenBehaviorMatchesNamespace() throws Exception {
+		this.spring.register(AccessDeniedHandlerRefConfig.class).autowire();
+		this.mvc.perform(get("/")
+				.with(authentication(user())));
+		verifyBean(AccessDeniedHandler.class)
+				.handle(any(HttpServletRequest.class), any(HttpServletResponse.class), any(AccessDeniedException.class));
+	}
+
+	@EnableWebSecurity
+	static class AccessDeniedHandlerRefConfig extends WebSecurityConfigurerAdapter {
+		protected void configure(HttpSecurity http) throws Exception {
+			http
+				.authorizeRequests()
+					.anyRequest().denyAll()
+					.and()
+				.exceptionHandling()
+					.accessDeniedHandler(accessDeniedHandler());
+		}
+
+		@Bean
+		AccessDeniedHandler accessDeniedHandler() {
+			return mock(AccessDeniedHandler.class);
+		}
+	}
+
+	private <T> T verifyBean(Class<T> beanClass) {
+		return verify(this.spring.getContext().getBean(beanClass));
+	}
+}