mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-07 01:54:22 +00:00
Ensure ShibbolethRestController only redirects to trusted URLs
This commit is contained in:
@@ -11,7 +11,9 @@ import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.dspace.app.rest.model.AuthnRest;
|
||||
import org.dspace.core.Utils;
|
||||
import org.dspace.services.ConfigurationService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -53,8 +55,20 @@ public class ShibbolethRestController implements InitializingBean {
|
||||
if (redirectUrl == null) {
|
||||
redirectUrl = configurationService.getProperty("dspace.ui.url");
|
||||
}
|
||||
log.info("Redirecting to " + redirectUrl);
|
||||
response.sendRedirect(redirectUrl);
|
||||
|
||||
// Validate that the redirectURL matches either the server or UI hostname. It *cannot* be an arbitrary URL.
|
||||
String redirectHostName = Utils.getHostName(redirectUrl);
|
||||
String serverHostName = Utils.getHostName(configurationService.getProperty("dspace.server.url"));
|
||||
String clientHostName = Utils.getHostName(configurationService.getProperty("dspace.ui.url"));
|
||||
if (StringUtils.equalsAnyIgnoreCase(redirectHostName, serverHostName, clientHostName)) {
|
||||
log.debug("Shibboleth redirecting to " + redirectUrl);
|
||||
response.sendRedirect(redirectUrl);
|
||||
} else {
|
||||
log.error("Invalid Shibboleth redirectURL=" + redirectUrl +
|
||||
". URL doesn't match hostname of server or UI!");
|
||||
response.sendError(HttpServletResponse.SC_BAD_REQUEST,
|
||||
"Invalid redirectURL! Must match server or ui hostname.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -31,12 +31,29 @@ public class ShibbolethRestControllerIT extends AbstractControllerIntegrationTes
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRedirectToGivenUrl() throws Exception {
|
||||
public void testRedirectToGivenTrustedUrl() throws Exception {
|
||||
String token = getAuthToken(eperson.getEmail(), password);
|
||||
|
||||
getClient(token).perform(get("/api/authn/shibboleth")
|
||||
.param("redirectUrl", "http://dspace.org"))
|
||||
.param("redirectUrl", "http://localhost:8080/server/api/authn/status"))
|
||||
.andExpect(status().is3xxRedirection())
|
||||
.andExpect(redirectedUrl("http://dspace.org"));
|
||||
.andExpect(redirectedUrl("http://localhost:8080/server/api/authn/status"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRedirectToGivenUntrustedUrl() throws Exception {
|
||||
String token = getAuthToken(eperson.getEmail(), password);
|
||||
|
||||
// Now attempt to redirect to a URL that is NOT trusted (i.e. not the Server or UI).
|
||||
// Should result in a 400 error.
|
||||
getClient(token).perform(get("/api/authn/shibboleth")
|
||||
.param("redirectUrl", "http://dspace.org"))
|
||||
.andExpect(status().isBadRequest());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRedirectRequiresAuth() throws Exception {
|
||||
getClient().perform(get("/api/authn/shibboleth"))
|
||||
.andExpect(status().isUnauthorized());
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user