SEC-1328: Fixed issue with redirect to context relative URLs where the context name is part of the domain name.
This commit is contained in:
parent
85a58fd473
commit
76731254c0
|
@ -28,34 +28,40 @@ public class DefaultRedirectStrategy implements RedirectStrategy {
|
||||||
* redirect is being performed to change to HTTPS, for example.
|
* redirect is being performed to change to HTTPS, for example.
|
||||||
*/
|
*/
|
||||||
public void sendRedirect(HttpServletRequest request, HttpServletResponse response, String url) throws IOException {
|
public void sendRedirect(HttpServletRequest request, HttpServletResponse response, String url) throws IOException {
|
||||||
String finalUrl;
|
String redirectUrl = calculateRedirectUrl(request.getContextPath(), url);
|
||||||
if (!url.startsWith("http://") && !url.startsWith("https://")) {
|
redirectUrl = response.encodeRedirectURL(redirectUrl);
|
||||||
if (contextRelative) {
|
|
||||||
finalUrl = url;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
finalUrl = request.getContextPath() + url;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (contextRelative) {
|
|
||||||
// Calculate the relative URL from the fully qualifed URL, minus the protocol and base context.
|
|
||||||
int len = request.getContextPath().length();
|
|
||||||
int index = url.indexOf(request.getContextPath()) + len;
|
|
||||||
finalUrl = url.substring(index);
|
|
||||||
|
|
||||||
if (finalUrl.length() > 1 && finalUrl.charAt(0) == '/') {
|
|
||||||
finalUrl = finalUrl.substring(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
finalUrl = url;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Redirecting to '" + finalUrl + "'");
|
logger.debug("Redirecting to '" + redirectUrl + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
response.sendRedirect(response.encodeRedirectURL(finalUrl));
|
response.sendRedirect(redirectUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String calculateRedirectUrl(String contextPath, String url) {
|
||||||
|
if (!url.startsWith("http://") && !url.startsWith("https://")) {
|
||||||
|
if (contextRelative) {
|
||||||
|
return url;
|
||||||
|
} else {
|
||||||
|
return contextPath + url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Full URL, including http(s)://
|
||||||
|
|
||||||
|
if (!contextRelative) {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate the relative URL from the fully qualifed URL, minus the protocol and base context.
|
||||||
|
url = url.substring(url.indexOf("://") + 3); // strip off protocol
|
||||||
|
url = url.substring(url.indexOf(contextPath) + contextPath.length());
|
||||||
|
|
||||||
|
if (url.length() > 1 && url.charAt(0) == '/') {
|
||||||
|
url = url.substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
package org.springframework.security.web;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.springframework.mock.web.MockHttpServletRequest;
|
||||||
|
import org.springframework.mock.web.MockHttpServletResponse;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Luke Taylor
|
||||||
|
* @since 3.0
|
||||||
|
*/
|
||||||
|
public class DefaultRedirectStrategyTests {
|
||||||
|
@Test
|
||||||
|
public void contextRelativeUrlWithContextNameInHostnameIsHandledCorrectly() throws Exception {
|
||||||
|
DefaultRedirectStrategy rds = new DefaultRedirectStrategy();
|
||||||
|
rds.setContextRelative(true);
|
||||||
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
|
request.setContextPath("/context");
|
||||||
|
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||||
|
|
||||||
|
rds.sendRedirect(request, response, "http://context.blah.com/context/remainder");
|
||||||
|
|
||||||
|
assertEquals("remainder", response.getRedirectedUrl());
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue