Add setFavorRelativeUris
This places the new functionality behind a setting so that we can remain passive until we can change the setting in the next major release. Issue gh-7273
This commit is contained in:
+40
-6
@@ -78,6 +78,8 @@ public class LoginUrlAuthenticationEntryPoint implements AuthenticationEntryPoin
|
||||
|
||||
private boolean useForward = false;
|
||||
|
||||
private boolean favorRelativeUris = false;
|
||||
|
||||
private final RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
|
||||
|
||||
/**
|
||||
@@ -144,23 +146,41 @@ public class LoginUrlAuthenticationEntryPoint implements AuthenticationEntryPoin
|
||||
protected String buildRedirectUrlToLoginPage(HttpServletRequest request, HttpServletResponse response,
|
||||
AuthenticationException authException) {
|
||||
String loginForm = determineUrlToUseForThisRequest(request, response, authException);
|
||||
if (UrlUtils.isAbsoluteUrl(loginForm) || !this.forceHttps || "https".equals(request.getScheme())) {
|
||||
if (UrlUtils.isAbsoluteUrl(loginForm)) {
|
||||
return loginForm;
|
||||
}
|
||||
if (requiresRewrite(request)) {
|
||||
return httpsUri(request, loginForm);
|
||||
}
|
||||
return this.favorRelativeUris ? loginForm : absoluteUri(request, loginForm).getUrl();
|
||||
}
|
||||
|
||||
private boolean requiresRewrite(HttpServletRequest request) {
|
||||
return this.forceHttps && "http".equals(request.getScheme());
|
||||
}
|
||||
|
||||
private String httpsUri(HttpServletRequest request, String path) {
|
||||
int serverPort = this.portResolver.getServerPort(request);
|
||||
Integer httpsPort = this.portMapper.lookupHttpsPort(serverPort);
|
||||
if (httpsPort == null) {
|
||||
logger.warn(LogMessage.format("Unable to redirect to HTTPS as no port mapping found for HTTP port %s",
|
||||
serverPort));
|
||||
return loginForm;
|
||||
return this.favorRelativeUris ? path : absoluteUri(request, path).getUrl();
|
||||
}
|
||||
RedirectUrlBuilder builder = absoluteUri(request, path);
|
||||
builder.setScheme("https");
|
||||
builder.setPort(httpsPort);
|
||||
return builder.getUrl();
|
||||
}
|
||||
|
||||
private RedirectUrlBuilder absoluteUri(HttpServletRequest request, String path) {
|
||||
RedirectUrlBuilder urlBuilder = new RedirectUrlBuilder();
|
||||
urlBuilder.setScheme("https");
|
||||
urlBuilder.setScheme(request.getScheme());
|
||||
urlBuilder.setServerName(request.getServerName());
|
||||
urlBuilder.setPort(httpsPort);
|
||||
urlBuilder.setPort(this.portResolver.getServerPort(request));
|
||||
urlBuilder.setContextPath(request.getContextPath());
|
||||
urlBuilder.setPathInfo(loginForm);
|
||||
return urlBuilder.getUrl();
|
||||
urlBuilder.setPathInfo(path);
|
||||
return urlBuilder;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -238,4 +258,18 @@ public class LoginUrlAuthenticationEntryPoint implements AuthenticationEntryPoin
|
||||
return this.useForward;
|
||||
}
|
||||
|
||||
/**
|
||||
* Favor using relative URIs when formulating a redirect.
|
||||
*
|
||||
* <p>
|
||||
* Note that a relative redirect is not always possible. For example, when redirecting
|
||||
* from {@code http} to {@code https}, the URL needs to be absolute.
|
||||
* </p>
|
||||
* @param favorRelativeUris whether to favor relative URIs or not
|
||||
* @since 6.5
|
||||
*/
|
||||
public void setFavorRelativeUris(boolean favorRelativeUris) {
|
||||
this.favorRelativeUris = favorRelativeUris;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+55
-5
@@ -129,18 +129,18 @@ public class LoginUrlAuthenticationEntryPointTests {
|
||||
ep.setPortResolver(new MockPortResolver(80, 443));
|
||||
ep.afterPropertiesSet();
|
||||
ep.commence(request, response, null);
|
||||
assertThat(response.getRedirectedUrl()).isEqualTo("/bigWebApp/hello");
|
||||
assertThat(response.getRedirectedUrl()).isEqualTo("https://www.example.com/bigWebApp/hello");
|
||||
request.setServerPort(8443);
|
||||
response = new MockHttpServletResponse();
|
||||
ep.setPortResolver(new MockPortResolver(8080, 8443));
|
||||
ep.commence(request, response, null);
|
||||
assertThat(response.getRedirectedUrl()).isEqualTo("/bigWebApp/hello");
|
||||
assertThat(response.getRedirectedUrl()).isEqualTo("https://www.example.com:8443/bigWebApp/hello");
|
||||
// access to https via http port
|
||||
request.setServerPort(8080);
|
||||
response = new MockHttpServletResponse();
|
||||
ep.setPortResolver(new MockPortResolver(8080, 8443));
|
||||
ep.commence(request, response, null);
|
||||
assertThat(response.getRedirectedUrl()).isEqualTo("/bigWebApp/hello");
|
||||
assertThat(response.getRedirectedUrl()).isEqualTo("https://www.example.com:8443/bigWebApp/hello");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -158,7 +158,7 @@ public class LoginUrlAuthenticationEntryPointTests {
|
||||
request.setServerPort(80);
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
ep.commence(request, response, null);
|
||||
assertThat(response.getRedirectedUrl()).isEqualTo("/bigWebApp/hello");
|
||||
assertThat(response.getRedirectedUrl()).isEqualTo("http://localhost/bigWebApp/hello");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -178,7 +178,7 @@ public class LoginUrlAuthenticationEntryPointTests {
|
||||
ep.commence(request, response, null);
|
||||
// Response doesn't switch to HTTPS, as we didn't know HTTP port 8888 to HTTP port
|
||||
// mapping
|
||||
assertThat(response.getRedirectedUrl()).isEqualTo("/bigWebApp/hello");
|
||||
assertThat(response.getRedirectedUrl()).isEqualTo("http://localhost:8888/bigWebApp/hello");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -237,4 +237,54 @@ public class LoginUrlAuthenticationEntryPointTests {
|
||||
assertThatIllegalArgumentException().isThrownBy(ep::afterPropertiesSet);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void commenceWhenFavorRelativeUrisThenHttpsSchemeNotIncluded() throws Exception {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.setRequestURI("/some_path");
|
||||
request.setScheme("https");
|
||||
request.setServerName("www.example.com");
|
||||
request.setContextPath("/bigWebApp");
|
||||
request.setServerPort(443);
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
LoginUrlAuthenticationEntryPoint ep = new LoginUrlAuthenticationEntryPoint("/hello");
|
||||
ep.setFavorRelativeUris(true);
|
||||
ep.setPortMapper(new PortMapperImpl());
|
||||
ep.setForceHttps(true);
|
||||
ep.setPortMapper(new PortMapperImpl());
|
||||
ep.setPortResolver(new MockPortResolver(80, 443));
|
||||
ep.afterPropertiesSet();
|
||||
ep.commence(request, response, null);
|
||||
assertThat(response.getRedirectedUrl()).isEqualTo("/bigWebApp/hello");
|
||||
request.setServerPort(8443);
|
||||
response = new MockHttpServletResponse();
|
||||
ep.setPortResolver(new MockPortResolver(8080, 8443));
|
||||
ep.commence(request, response, null);
|
||||
assertThat(response.getRedirectedUrl()).isEqualTo("/bigWebApp/hello");
|
||||
// access to https via http port
|
||||
request.setServerPort(8080);
|
||||
response = new MockHttpServletResponse();
|
||||
ep.setPortResolver(new MockPortResolver(8080, 8443));
|
||||
ep.commence(request, response, null);
|
||||
assertThat(response.getRedirectedUrl()).isEqualTo("/bigWebApp/hello");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void commenceWhenFavorRelativeUrisThenHttpSchemeNotIncluded() throws Exception {
|
||||
LoginUrlAuthenticationEntryPoint ep = new LoginUrlAuthenticationEntryPoint("/hello");
|
||||
ep.setFavorRelativeUris(true);
|
||||
ep.setPortMapper(new PortMapperImpl());
|
||||
ep.setPortResolver(new MockPortResolver(80, 443));
|
||||
ep.afterPropertiesSet();
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.setRequestURI("/some_path");
|
||||
request.setContextPath("/bigWebApp");
|
||||
request.setScheme("http");
|
||||
request.setServerName("localhost");
|
||||
request.setContextPath("/bigWebApp");
|
||||
request.setServerPort(80);
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
ep.commence(request, response, null);
|
||||
assertThat(response.getRedirectedUrl()).isEqualTo("/bigWebApp/hello");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user