diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/builders/HttpSecurity.java b/config/src/main/java/org/springframework/security/config/annotation/web/builders/HttpSecurity.java index 2688793d08..7c1acd7200 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/web/builders/HttpSecurity.java +++ b/config/src/main/java/org/springframework/security/config/annotation/web/builders/HttpSecurity.java @@ -633,6 +633,52 @@ public final class HttpSecurity extends return getOrApply(new PortMapperConfigurer<>()); } + /** + * Allows configuring a {@link PortMapper} that is available from + * {@link HttpSecurity#getSharedObject(Class)}. Other provided + * {@link SecurityConfigurer} objects use this configured {@link PortMapper} as a + * default {@link PortMapper} when redirecting from HTTP to HTTPS or from HTTPS to + * HTTP (for example when used in combination with {@link #requiresChannel()}. By + * default Spring Security uses a {@link PortMapperImpl} which maps the HTTP port 8080 + * to the HTTPS port 8443 and the HTTP port of 80 to the HTTPS port of 443. + * + *

Example Configuration

+ * + * The following configuration will ensure that redirects within Spring Security from + * HTTP of a port of 9090 will redirect to HTTPS port of 9443 and the HTTP port of 80 + * to the HTTPS port of 443. + * + *
+	 * @Configuration
+	 * @EnableWebSecurity
+	 * public class PortMapperSecurityConfig extends WebSecurityConfigurerAdapter {
+	 *
+	 * 	@Override
+	 * 	protected void configure(HttpSecurity http) throws Exception {
+	 * 		http
+	 * 			.requiresChannel()
+	 * 				.anyRequest().requiresSecure()
+	 * 				.and()
+	 * 			.portMapper(portMapper ->
+	 * 				portMapper
+	 * 					.http(9090).mapsTo(9443)
+	 * 					.http(80).mapsTo(443)
+	 * 			);
+	 * 	}
+	 * }
+	 * 
+ * + * @see #requiresChannel() + * @param portMapperCustomizer the {@link Customizer} to provide more options for + * the {@link PortMapperConfigurer} + * @return the {@link HttpSecurity} for further customizations + * @throws Exception + */ + public HttpSecurity portMapper(Customizer> portMapperCustomizer) throws Exception { + portMapperCustomizer.customize(getOrApply(new PortMapperConfigurer<>())); + return HttpSecurity.this; + } + /** * Configures container based pre authentication. In this case, authentication * is managed by the Servlet Container. diff --git a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/PortMapperConfigurerTests.java b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/PortMapperConfigurerTests.java index bc451f4c95..d9ed42ff22 100644 --- a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/PortMapperConfigurerTests.java +++ b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/PortMapperConfigurerTests.java @@ -22,8 +22,11 @@ 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.PortMapperImpl; import org.springframework.test.web.servlet.MockMvc; +import java.util.Collections; + import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl; @@ -61,4 +64,56 @@ public class PortMapperConfigurerTests { .portMapper(); } } + + @Test + public void requestWhenPortMapperHttpMapsToInLambdaThenRedirectsToHttpsPort() throws Exception { + this.spring.register(HttpMapsToInLambdaConfig.class).autowire(); + + this.mockMvc.perform(get("http://localhost:543")) + .andExpect(redirectedUrl("https://localhost:123")); + } + + @EnableWebSecurity + static class HttpMapsToInLambdaConfig extends WebSecurityConfigurerAdapter { + @Override + protected void configure(HttpSecurity http) throws Exception { + // @formatter:off + http + .requiresChannel() + .anyRequest().requiresSecure() + .and() + .portMapper(portMapper -> + portMapper + .http(543).mapsTo(123) + ); + // @formatter:on + } + } + + @Test + public void requestWhenCustomPortMapperInLambdaThenRedirectsToHttpsPort() throws Exception { + this.spring.register(CustomPortMapperInLambdaConfig.class).autowire(); + + this.mockMvc.perform(get("http://localhost:543")) + .andExpect(redirectedUrl("https://localhost:123")); + } + + @EnableWebSecurity + static class CustomPortMapperInLambdaConfig extends WebSecurityConfigurerAdapter { + @Override + protected void configure(HttpSecurity http) throws Exception { + PortMapperImpl customPortMapper = new PortMapperImpl(); + customPortMapper.setPortMappings(Collections.singletonMap("543", "123")); + // @formatter:off + http + .requiresChannel() + .anyRequest().requiresSecure() + .and() + .portMapper(portMapper -> + portMapper + .portMapper(customPortMapper) + ); + // @formatter:on + } + } }