diff --git a/README.md b/README.md index bf216bc..b77766c 100644 --- a/README.md +++ b/README.md @@ -176,8 +176,8 @@ The `AuthenticationFilter` is what detects whether a user needs to be authentica CAS Authentication Filter org.jasig.cas.client.authentication.AuthenticationFilter - casServerLoginUrl - https://battags.ad.ess.rutgers.edu:8443/cas/login + casServerUrlPrefix + https://battags.ad.ess.rutgers.edu:8443/cas serverName @@ -192,7 +192,8 @@ The `AuthenticationFilter` is what detects whether a user needs to be authentica | Property | Description | Required |----------|-------|----------- -| `casServerLoginUrl` | Defines the location of the CAS server login URL, i.e. `https://localhost:8443/cas/login` | Yes +| `casServerUrlPrefix` | The start of the CAS server URL, i.e. `https://localhost:8443/cas` | Yes (unless `casServerLoginUrl` is set) +| `casServerLoginUrl` | Defines the location of the CAS server login URL, i.e. `https://localhost:8443/cas/login`. This overrides `casServerUrlPrefix`, if set. | Yes (unless `casServerUrlPrefix` is set) | `serverName` | The name of the server this application is hosted on. Service URL will be dynamically constructed using this, i.e. https://localhost:8443 (you must include the protocol, but port is optional if it's a standard port). | Yes | `service` | The service URL to send to the CAS server, i.e. `https://localhost:8443/yourwebapp/index.html` | No | `renew` | specifies whether `renew=true` should be sent to the CAS server. Valid values are either `true/false` (or no value at all). Note that `renew` cannot be specified as local `init-param` setting. | No @@ -230,7 +231,8 @@ The SAML 1.1 `AuthenticationFilter` is what detects whether a user needs to be a | Property | Description | Required |----------|-------|----------- -| `casServerLoginUrl` | Defines the location of the CAS server login URL, i.e. `https://localhost:8443/cas/login` | Yes +| `casServerUrlPrefix` | The start of the CAS server URL, i.e. `https://localhost:8443/cas` | Yes (unless `casServerLoginUrl` is set) +| `casServerLoginUrl` | Defines the location of the CAS server login URL, i.e. `https://localhost:8443/cas/login`. This overrides `casServerUrlPrefix`, if set. | Yes (unless `casServerUrlPrefix` is set) | `serverName` | The name of the server this application is hosted on. Service URL will be dynamically constructed using this, i.e. https://localhost:8443 (you must include the protocol, but port is optional if it's a standard port). | Yes | `service` | The service URL to send to the CAS server, i.e. `https://localhost:8443/yourwebapp/index.html` | No | `renew` | specifies whether `renew=true` should be sent to the CAS server. Valid values are either `true/false` (or no value at all). Note that `renew` cannot be specified as local `init-param` setting. | No diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/AuthenticationFilter.java b/cas-client-core/src/main/java/org/jasig/cas/client/authentication/AuthenticationFilter.java index f460c88..07400ef 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/AuthenticationFilter.java +++ b/cas-client-core/src/main/java/org/jasig/cas/client/authentication/AuthenticationFilter.java @@ -93,7 +93,14 @@ public class AuthenticationFilter extends AbstractCasFilter { protected void initInternal(final FilterConfig filterConfig) throws ServletException { if (!isIgnoreInitConfiguration()) { super.initInternal(filterConfig); - setCasServerLoginUrl(getString(ConfigurationKeys.CAS_SERVER_LOGIN_URL)); + + String loginUrl = getString(ConfigurationKeys.CAS_SERVER_LOGIN_URL); + if (loginUrl != null) { + setCasServerLoginUrl(loginUrl); + } else { + setCasServerUrlPrefix(getString(ConfigurationKeys.CAS_SERVER_URL_PREFIX)); + } + setRenew(getBoolean(ConfigurationKeys.RENEW)); setGateway(getBoolean(ConfigurationKeys.GATEWAY)); @@ -133,7 +140,13 @@ public class AuthenticationFilter extends AbstractCasFilter { public void init() { super.init(); - CommonUtils.assertNotNull(this.casServerLoginUrl, "casServerLoginUrl cannot be null."); + + String message = String.format( + "one of %s and %s must not be null.", + ConfigurationKeys.CAS_SERVER_LOGIN_URL.getName(), + ConfigurationKeys.CAS_SERVER_URL_PREFIX.getName()); + + CommonUtils.assertNotNull(this.casServerLoginUrl, message); } public final void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse, @@ -192,6 +205,10 @@ public class AuthenticationFilter extends AbstractCasFilter { this.gateway = gateway; } + public final void setCasServerUrlPrefix(final String casServerUrlPrefix) { + setCasServerLoginUrl(CommonUtils.addTrailingSlash(casServerUrlPrefix) + "login"); + } + public final void setCasServerLoginUrl(final String casServerLoginUrl) { this.casServerLoginUrl = casServerLoginUrl; } diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/util/CommonUtils.java b/cas-client-core/src/main/java/org/jasig/cas/client/util/CommonUtils.java index 32ebb5c..5cff27f 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/util/CommonUtils.java +++ b/cas-client-core/src/main/java/org/jasig/cas/client/util/CommonUtils.java @@ -730,4 +730,13 @@ public final class CommonUtils { return string == null ? "" : string; } + /** + * Adds a trailing slash to the given uri, if it doesn't already have one. + * + * @param uri a string that may or may not end with a slash + * @return the same string, except with a slash suffix (if necessary). + */ + public static String addTrailingSlash(String uri) { + return uri.endsWith("/") ? uri : uri + "/"; + } } diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/validation/AbstractUrlBasedTicketValidator.java b/cas-client-core/src/main/java/org/jasig/cas/client/validation/AbstractUrlBasedTicketValidator.java index 59c4d88..2c9dd94 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/validation/AbstractUrlBasedTicketValidator.java +++ b/cas-client-core/src/main/java/org/jasig/cas/client/validation/AbstractUrlBasedTicketValidator.java @@ -71,8 +71,8 @@ public abstract class AbstractUrlBasedTicketValidator implements TicketValidator * @param casServerUrlPrefix the location of the CAS server. */ protected AbstractUrlBasedTicketValidator(final String casServerUrlPrefix) { - this.casServerUrlPrefix = casServerUrlPrefix; - CommonUtils.assertNotNull(this.casServerUrlPrefix, "casServerUrlPrefix cannot be null."); + CommonUtils.assertNotNull(casServerUrlPrefix, "casServerUrlPrefix cannot be null."); + this.casServerUrlPrefix = CommonUtils.addTrailingSlash(casServerUrlPrefix); } /** @@ -124,9 +124,6 @@ public abstract class AbstractUrlBasedTicketValidator implements TicketValidator int i = 0; buffer.append(this.casServerUrlPrefix); - if (!this.casServerUrlPrefix.endsWith("/")) { - buffer.append("/"); - } buffer.append(suffix); for (Map.Entry entry : urlParameters.entrySet()) { diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/authentication/AuthenticationFilterTests.java b/cas-client-core/src/test/java/org/jasig/cas/client/authentication/AuthenticationFilterTests.java index 742a5cf..214d787 100644 --- a/cas-client-core/src/test/java/org/jasig/cas/client/authentication/AuthenticationFilterTests.java +++ b/cas-client-core/src/test/java/org/jasig/cas/client/authentication/AuthenticationFilterTests.java @@ -47,7 +47,8 @@ public final class AuthenticationFilterTests { private static final String CAS_SERVICE_URL = "https://localhost:8443/service"; - private static final String CAS_LOGIN_URL = "https://localhost:8443/cas/login"; + private static final String CAS_PREFIX = "https://localhost:8443/cas"; + private static final String CAS_LOGIN_URL = CAS_PREFIX + "/login"; private AuthenticationFilter filter; @@ -66,7 +67,25 @@ public final class AuthenticationFilterTests { } @Test - public void testRedirect() throws Exception { + public void testRedirectWithLoginUrlConfig() throws Exception { + doRedirectTest(); + } + + @Test + public void testRedirectWithCasServerPrefixConfig() throws Exception { + replaceFilterWithPrefixConfiguredFilter(); + doRedirectTest(); + } + + private void replaceFilterWithPrefixConfiguredFilter() throws ServletException { + this.filter = new AuthenticationFilter(); + final MockFilterConfig config = new MockFilterConfig(); + config.addInitParameter("casServerUrlPrefix", CAS_PREFIX); + config.addInitParameter("service", CAS_SERVICE_URL); + this.filter.init(config); + } + + private void doRedirectTest() throws IOException, ServletException { final MockHttpSession session = new MockHttpSession(); final MockHttpServletRequest request = new MockHttpServletRequest(); final MockHttpServletResponse response = new MockHttpServletResponse();