Skip to content

Commit

Permalink
DefaultRedirectStrategy Host-less Redirect
Browse files Browse the repository at this point in the history
  • Loading branch information
jzheaux committed Sep 5, 2019
1 parent 26a6524 commit e18dda7
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,30 @@
package org.springframework.security.web;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.security.web.util.UrlUtils;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;

/**
* Simple implementation of <tt>RedirectStrategy</tt> which is the default used throughout
* the framework.
*
* @author Luke Taylor
* @author Josh Cummings
* @since 3.0
*/
public class DefaultRedirectStrategy implements RedirectStrategy {

protected final Log logger = LogFactory.getLog(getClass());

private boolean contextRelative;
private boolean hostRelative = true;

/**
* Redirects the response to the supplied URL.
Expand Down Expand Up @@ -68,25 +72,40 @@ protected String calculateRedirectUrl(String contextPath, String url) {
}

// Full URL, including http(s)://
boolean hostRelative = this.hostRelative;
boolean contextRelative = isContextRelative();

if (!isContextRelative()) {
if (!hostRelative && !contextRelative) {
return url;
}

// Calculate the relative URL from the fully qualified URL, minus the last
// occurrence of the scheme and base context.
url = url.substring(url.lastIndexOf("://") + 3); // strip off scheme
url = url.substring(url.indexOf(contextPath) + contextPath.length());
UriComponents components = UriComponentsBuilder
.fromHttpUrl(url).build();

if (url.length() > 1 && url.charAt(0) == '/') {
url = url.substring(1);
String path = components.getPath();
if (contextRelative) {
path = path.substring(path.indexOf(contextPath) + contextPath.length());
if (path.length() > 1 && path.charAt(0) == '/') {
path = path.substring(1);
}
}

return url;
return UriComponentsBuilder
.fromPath(path)
.query(components.getQuery())
.build().toString();
}

/**
* If <tt>true</tt>, causes any redirection URLs to be calculated minus the authority
* (defaults to <tt>true</tt>).
*/
public void setHostRelative(boolean hostRelative) {
this.hostRelative = hostRelative;
}

/**
* If <tt>true</tt>, causes any redirection URLs to be calculated minus the protocol
* If <tt>true</tt>, causes any redirection URLs to be calculated minus the authority
* and context path (defaults to <tt>false</tt>).
*/
public void setContextRelative(boolean useRelativeContext) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@
*/
package org.springframework.security.web;

import static org.assertj.core.api.Assertions.*;

import org.junit.Test;

import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;

import static org.assertj.core.api.Assertions.assertThat;

/**
*
* @author Luke Taylor
Expand Down Expand Up @@ -56,4 +57,34 @@ public void contextRelativeUrlWithMultipleSchemesInHostnameIsHandledCorrectly()

assertThat(response.getRedirectedUrl()).isEqualTo("remainder");
}

// gh-7273
@Test
public void sendRedirectWhenUsingDefaultsThenRemovesHost()
throws Exception {
DefaultRedirectStrategy rds = new DefaultRedirectStrategy();
MockHttpServletRequest request = new MockHttpServletRequest();
request.setContextPath("/context");
MockHttpServletResponse response = new MockHttpServletResponse();

rds.sendRedirect(request, response,
"https://context.blah.com/context/remainder");
assertThat(response.getRedirectedUrl()).isEqualTo("/context/remainder");
}

// gh-7273
@Test
public void sendRedirectWhenHostRelativeFalseThenKeepsHost()
throws Exception {
DefaultRedirectStrategy rds = new DefaultRedirectStrategy();
rds.setHostRelative(false);
MockHttpServletRequest request = new MockHttpServletRequest();
request.setContextPath("/context");
MockHttpServletResponse response = new MockHttpServletResponse();

rds.sendRedirect(request, response,
"https://context.blah.com/context/remainder");

assertThat(response.getRedirectedUrl()).isEqualTo("https://context.blah.com/context/remainder");
}
}

0 comments on commit e18dda7

Please sign in to comment.