Include serverName path when constructing service url

Commit be2a641 introduced a bug which overwrites the serverName path component
when constructing service urls. This makes it impossible to deploy a CAS-
protected application behind a reverse proxy with a path prefix.

Now, the path from the incoming request is appended to the serverName path
instead of overwriting it.
This commit is contained in:
Joshua Smith 2018-10-01 16:03:28 -07:00
parent 2a570b26f1
commit c39735729d
3 changed files with 32 additions and 21 deletions

View File

@ -257,17 +257,7 @@ public final class CommonUtils {
return serverNames[0];
}
private static boolean serverNameContainsPort(final boolean containsScheme, final String serverName) {
if (!containsScheme && serverName.contains(":")) {
return true;
}
final int schemeIndex = serverName.indexOf(":");
final int portIndex = serverName.lastIndexOf(":");
return schemeIndex != portIndex;
}
private static boolean requestIsOnStandardPort(final HttpServletRequest request) {
final int serverPort = request.getServerPort();
return serverPort == 80 || serverPort == 443;
@ -325,23 +315,18 @@ public final class CommonUtils {
originalRequestUrl.setParameters(request.getQueryString());
final URIBuilder builder;
boolean containsScheme = true;
if (!serverName.startsWith("https://") && !serverName.startsWith("http://")) {
builder = new URIBuilder(encode);
builder.setScheme(request.isSecure() ? "https" : "http");
builder.setHost(serverName);
containsScheme = false;
} else {
String scheme = request.isSecure() ? "https://" : "http://";
builder = new URIBuilder(scheme + serverName, encode);
} else {
builder = new URIBuilder(serverName, encode);
}
if (!serverNameContainsPort(containsScheme, serverName) && !requestIsOnStandardPort(request)) {
if (builder.getPort() == -1 && !requestIsOnStandardPort(request)) {
builder.setPort(request.getServerPort());
}
builder.setEncodedPath(request.getRequestURI());
builder.setEncodedPath(builder.getEncodedPath() + request.getRequestURI());
final List<String> serviceParameterNames = Arrays.asList(serviceParameterName.split(","));
if (!serviceParameterNames.isEmpty() && !originalRequestUrl.getQueryParams().isEmpty()) {

View File

@ -523,6 +523,10 @@ public final class URIBuilder {
return this.path;
}
public String getEncodedPath() {
return this.encodedPath;
}
public List<BasicNameValuePair> getQueryParams() {
if (this.queryParams != null) {
return new ArrayList<BasicNameValuePair>(this.queryParams);

View File

@ -139,6 +139,28 @@ public final class CommonUtilsTests extends TestCase {
assertEquals(CONST_MY_URL, constructedUrl);
}
public void testConstructServiceUrlWithServerNameContainingPath() {
final MockHttpServletRequest request = new MockHttpServletRequest("GET", "/hello/hithere/");
request.setScheme("https");
request.setSecure(true);
final MockHttpServletResponse response = new MockHttpServletResponse();
final String constructedUrl = CommonUtils.constructServiceUrl(request, response, null, "www.my.server.com/app",
Protocol.CAS3.getServiceParameterName(), Protocol.CAS3.getArtifactParameterName(), false);
assertEquals("https://www.my.server.com/app/hello/hithere/", constructedUrl);
}
public void testConstructServiceUrlWithServerNameContainingPathAndSchema() {
final MockHttpServletRequest request = new MockHttpServletRequest("GET", "/hello/hithere/");
request.setScheme("https");
request.setSecure(true);
final MockHttpServletResponse response = new MockHttpServletResponse();
final String constructedUrl = CommonUtils.constructServiceUrl(request, response, null, "https://www.my.server.com/app",
Protocol.CAS3.getServiceParameterName(), Protocol.CAS3.getArtifactParameterName(), false);
assertEquals("https://www.my.server.com/app/hello/hithere/", constructedUrl);
}
public void testConstructServiceUrlWithParamsCas() {
final String CONST_MY_URL = "https://www.myserver.com/hello/hithere/";
final MockHttpServletRequest request = new MockHttpServletRequest("GET", "/hello/hithere/");