Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -562,8 +562,9 @@ server:

NOTE: You can trust all proxies by setting the `internal-proxies` to empty (but do not do so in production).

TIP: If you are using Tomcat and terminating SSL at the proxy, configprop:server.tomcat.redirect-context-root[] should be set to `false`.
TIP: If you are using Tomcat, terminating SSL at the proxy, and have set configprop:server.tomcat.use-relative-redirects[] to `false`, then configprop:server.tomcat.redirect-context-root[] should also be set to `false`.
This allows the `X-Forwarded-Proto` header to be honored before any redirects are performed.
When relative redirects are in use, which is Tomcat's default, the context root redirect carries no scheme so there is nothing for the header to correct.

You can take complete control of the configuration of Tomcat's javadoc:org.apache.catalina.valves.RemoteIpValve[] by switching the automatic one off (to do so, set `server.forward-headers-strategy=NONE`) and adding a new valve instance using a javadoc:org.springframework.boot.web.server.WebServerFactoryCustomizer[] bean.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
* @author Florian Storz
* @author Michael Weidmann
* @author Lasse Wulff
* @author Tiziano Basile
* @since 4.0.0
*/
@ConfigurationProperties("server.tomcat")
Expand Down Expand Up @@ -103,9 +104,9 @@ public class TomcatServerProperties {

/**
* Whether HTTP 1.1 and later location headers generated by a call to sendRedirect
* will use relative or absolute redirects.
* will use relative or absolute redirects. Has no effect on a reactive web server.
*/
private boolean useRelativeRedirects;
private boolean useRelativeRedirects = true;

/**
* Character encoding to use to decode the URI.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
*
* @author Brian Clozel
* @author Phillip Webb
* @author Tiziano Basile
*/
class TomcatServletWebServerFactoryCustomizer
implements WebServerFactoryCustomizer<TomcatServletWebServerFactory>, Ordered {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
* Tests for {@link TomcatServerProperties}.
*
* @author Andy Wilkinson
* @author Tiziano Basile
*/
class TomcatServerPropertiesTests {

Expand Down Expand Up @@ -235,8 +236,8 @@ void tomcatInternalProxiesMatchesDefault() {
}

@Test
void tomcatUseRelativeRedirectsDefaultsToFalse() {
assertThat(this.properties.isUseRelativeRedirects()).isFalse();
void tomcatUseRelativeRedirectsDefaultsToTrue() {
assertThat(this.properties.isUseRelativeRedirects()).isTrue();
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
* Tests for {@link TomcatServletWebServerFactoryCustomizer}.
*
* @author Phillip Webb
* @author Tiziano Basile
*/
class TomcatServletWebServerFactoryCustomizerTests {

Expand Down Expand Up @@ -80,14 +81,22 @@ void redirectContextRootCanBeConfigured() {
}

@Test
void useRelativeRedirectsCanBeConfigured() {
bind("server.tomcat.use-relative-redirects=true");
void useRelativeRedirectsDefaultsToTrue() {
assertThat(this.tomcatProperties.isUseRelativeRedirects()).isTrue();
TomcatWebServer server = customizeAndGetServer();
Context context = (Context) server.getTomcat().getHost().findChildren()[0];
assertThat(context.getUseRelativeRedirects()).isTrue();
}

@Test
void useRelativeRedirectsCanBeDisabled() {
bind("server.tomcat.use-relative-redirects=false");
assertThat(this.tomcatProperties.isUseRelativeRedirects()).isFalse();
TomcatWebServer server = customizeAndGetServer();
Context context = (Context) server.getTomcat().getHost().findChildren()[0];
assertThat(context.getUseRelativeRedirects()).isFalse();
}

private void bind(String... inlinedProperties) {
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(this.environment, inlinedProperties);
new Binder(ConfigurationPropertySources.get(this.environment)).bind("server.tomcat",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ void authServerMetadataShouldAllowAccess() {
void anonymousShouldRedirectToLogin() {
RestTestClient.ResponseSpec response = nonFollowingRedirect().get().uri("/").exchange();
response.expectStatus().isFound();
response.expectHeader().location("http://localhost:" + this.port + "/login");
response.expectHeader().location("/login");
}

@Test
Expand Down Expand Up @@ -181,7 +181,7 @@ void anonymousTokenRequestWithAcceptHeaderTextHtmlShouldRedirectToLogin() {
.body(body)
.exchange();
response.expectStatus().isFound();
response.expectHeader().location("http://localhost:" + this.port + "/login");
response.expectHeader().location("/login");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ private RestTestClient nonFollowingRedirect() {
void everythingShouldRedirectToLogin() {
RestTestClient.ResponseSpec response = nonFollowingRedirect().get().uri("/").exchange();
response.expectStatus().isFound();
response.expectHeader().location("http://localhost:" + this.port + "/login");
response.expectHeader().location("/login");
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ private RestTestClient nonFollowingRedirect() {
void everythingShouldRedirectToLogin() {
RestTestClient.ResponseSpec response = nonFollowingRedirect().get().uri("/").exchange();
response.expectStatus().isFound();
response.expectHeader().location("http://localhost:" + this.port + "/login");
response.expectHeader().location("/login");
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureRestTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.test.web.servlet.client.RestTestClient;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
Expand All @@ -38,9 +37,6 @@
@AutoConfigureRestTestClient
class SampleGroovyTemplateApplicationTests {

@LocalServerPort
private int port;

@Autowired
private RestTestClient restTestClient;

Expand All @@ -62,7 +58,7 @@ void testCreate() {
.body(map)
.exchange()
.expectHeader()
.value("Location", (location) -> assertThat(location).contains("localhost:" + this.port));
.value("Location", (location) -> assertThat(location).matches("/\\d+(;jsessionid=[\\w.]+)?"));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ void testLogin() {
assertThat(result.getStatus()).isEqualTo(HttpStatus.FOUND);
URI location = result.getResponseHeaders().getLocation();
assertThat(location).isNotNull();
assertThat(location.toString()).endsWith(this.port + "/");
assertThat(location.toString()).isEqualTo("/");
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ void testHome() {
assertThat(result.getStatus()).isEqualTo(HttpStatus.FOUND);
URI location = result.getResponseHeaders().getLocation();
assertThat(location).isNotNull();
assertThat(location.toString()).endsWith(this.port + "/login");
assertThat(location.toString()).isEqualTo("/login");
}

@Test
Expand Down Expand Up @@ -99,7 +99,7 @@ void testLogin() {
assertThat(result.getStatus()).isEqualTo(HttpStatus.FOUND);
URI location = result.getResponseHeaders().getLocation();
assertThat(location).isNotNull();
assertThat(location.toString()).endsWith(this.port + "/");
assertThat(location.toString()).isEqualTo("/");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ void testHome() {
assertThat(result.getStatus()).isEqualTo(HttpStatus.FOUND);
URI location = result.getResponseHeaders().getLocation();
assertThat(location).isNotNull();
assertThat(location.toString()).endsWith(this.port + "/login");
assertThat(location.toString()).isEqualTo("/login");
}

@Test
Expand Down Expand Up @@ -99,7 +99,7 @@ void testLogin() {
assertThat(result.getStatus()).isEqualTo(HttpStatus.FOUND);
URI location = result.getResponseHeaders().getLocation();
assertThat(location).isNotNull();
assertThat(location.toString()).endsWith(this.port + "/");
assertThat(location.toString()).isEqualTo("/");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ void testHome() {
assertThat(result.getStatus()).isEqualTo(HttpStatus.FOUND);
URI location = result.getResponseHeaders().getLocation();
assertThat(location).isNotNull();
assertThat(location.toString()).endsWith(this.port + "/login");
assertThat(location.toString()).isEqualTo("/login");
}

@Test
Expand Down Expand Up @@ -106,7 +106,7 @@ void testLogin() {
assertThat(result.getStatus()).isEqualTo(HttpStatus.FOUND);
URI location = result.getResponseHeaders().getLocation();
assertThat(location).isNotNull();
assertThat(location.toString()).endsWith(this.port + "/");
assertThat(location.toString()).isEqualTo("/");
}

@org.springframework.boot.test.context.TestConfiguration(proxyBeanMethods = false)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureRestTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.test.web.servlet.client.RestTestClient;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
Expand All @@ -43,9 +42,6 @@ class SampleWebUiApplicationTests {
@Autowired
private RestTestClient restTestClient;

@LocalServerPort
private int port;

@Test
void testHome() {
this.restTestClient.get().uri("/").exchangeSuccessfully().expectBody(String.class).value((body) -> {
Expand All @@ -67,7 +63,7 @@ void testCreate() {
.getResponseHeaders()
.getLocation();
assertThat(location).isNotNull();
assertThat(location.toString()).contains("localhost:" + this.port);
assertThat(location.toString()).matches("/\\d+(;jsessionid=[\\w.]+)?");
}

}
Loading