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();