From 3eac2dd31e0e2fa582c9da4bc7d2ca1385871b9d Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Thu, 24 May 2018 16:14:12 -0400 Subject: [PATCH] Support X-Forwarded-Ssl Issue: SPR-16863 --- .../web/util/UriComponentsBuilder.java | 13 +++++++++++++ .../web/filter/ForwardedHeaderFilterTests.java | 3 ++- .../web/util/UriComponentsBuilderTests.java | 15 +++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java b/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java index 9b29f13762e..ca00debee73 100644 --- a/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java +++ b/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java @@ -743,6 +743,10 @@ public class UriComponentsBuilder implements UriBuilder, Cloneable { scheme(matcher.group(1).trim()); port(null); } + else if (isForwardedSslOn(headers)) { + scheme("https"); + port(null); + } matcher = FORWARDED_HOST_PATTERN.matcher(forwardedToUse); if (matcher.find()) { adaptForwardedHost(matcher.group(1).trim()); @@ -754,6 +758,10 @@ public class UriComponentsBuilder implements UriBuilder, Cloneable { scheme(StringUtils.tokenizeToStringArray(protocolHeader, ",")[0]); port(null); } + else if (isForwardedSslOn(headers)) { + scheme("https"); + port(null); + } String hostHeader = headers.getFirst("X-Forwarded-Host"); if (StringUtils.hasText(hostHeader)) { @@ -780,6 +788,11 @@ public class UriComponentsBuilder implements UriBuilder, Cloneable { return this; } + private boolean isForwardedSslOn(HttpHeaders headers) { + String forwardedSsl = headers.getFirst("X-Forwarded-Ssl"); + return StringUtils.hasText(forwardedSsl) && forwardedSsl.equalsIgnoreCase("on"); + } + private void adaptForwardedHost(String hostToUse) { int portSeparatorIdx = hostToUse.lastIndexOf(':'); if (portSeparatorIdx > hostToUse.lastIndexOf(']')) { diff --git a/spring-web/src/test/java/org/springframework/web/filter/ForwardedHeaderFilterTests.java b/spring-web/src/test/java/org/springframework/web/filter/ForwardedHeaderFilterTests.java index a5fadd84c6e..180237e8ad8 100644 --- a/spring-web/src/test/java/org/springframework/web/filter/ForwardedHeaderFilterTests.java +++ b/spring-web/src/test/java/org/springframework/web/filter/ForwardedHeaderFilterTests.java @@ -33,6 +33,7 @@ import org.springframework.mock.web.test.MockHttpServletRequest; import org.springframework.mock.web.test.MockHttpServletResponse; import static org.junit.Assert.*; +import static org.mockito.Mockito.*; /** * Unit tests for {@link ForwardedHeaderFilter}. @@ -458,7 +459,7 @@ public class ForwardedHeaderFilterTests { }; MockHttpServletResponse response = new MockHttpServletResponse(); - FilterChain filterChain = new MockFilterChain(new HttpServlet() {}, this.filter, filter); + FilterChain filterChain = new MockFilterChain(mock(HttpServlet.class), this.filter, filter); filterChain.doFilter(request, response); return response.getRedirectedUrl(); diff --git a/spring-web/src/test/java/org/springframework/web/util/UriComponentsBuilderTests.java b/spring-web/src/test/java/org/springframework/web/util/UriComponentsBuilderTests.java index 41a3f7e96a7..155704aad1b 100644 --- a/spring-web/src/test/java/org/springframework/web/util/UriComponentsBuilderTests.java +++ b/spring-web/src/test/java/org/springframework/web/util/UriComponentsBuilderTests.java @@ -426,6 +426,21 @@ public class UriComponentsBuilderTests { assertEquals(-1, result.getPort()); } + @Test // SPR-16863 + public void fromHttpRequestWithForwardedSsl() { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setScheme("http"); + request.setServerName("example.org"); + request.setServerPort(10080); + request.addHeader("X-Forwarded-Ssl", "on"); + + HttpRequest httpRequest = new ServletServerHttpRequest(request); + UriComponents result = UriComponentsBuilder.fromHttpRequest(httpRequest).build(); + + assertEquals("https", result.getScheme()); + assertEquals("example.org", result.getHost()); + assertEquals(-1, result.getPort()); + } @Test public void fromHttpRequestWithForwardedHostWithForwardedScheme() {