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 52006dd..4034b47 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
@@ -217,12 +217,10 @@ public final class CommonUtils {
buffer.append(request.getRequestURI());
if (CommonUtils.isNotBlank(request.getQueryString())) {
- final int location = request.getQueryString().indexOf(
- artifactParameterName + "=");
+ final int location = request.getQueryString().indexOf(artifactParameterName + "=");
if (location == 0) {
- final String returnValue = encode ? response.encodeURL(buffer
- .toString()): buffer.toString();
+ final String returnValue = encode ? response.encodeURL(buffer.toString()): buffer.toString();
if (LOG.isDebugEnabled()) {
LOG.debug("serviceUrl generated: " + returnValue);
}
diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/util/CommonUtilsTests.java b/cas-client-core/src/test/java/org/jasig/cas/client/util/CommonUtilsTests.java
index 99cb6e2..df56d3f 100644
--- a/cas-client-core/src/test/java/org/jasig/cas/client/util/CommonUtilsTests.java
+++ b/cas-client-core/src/test/java/org/jasig/cas/client/util/CommonUtilsTests.java
@@ -6,6 +6,8 @@
package org.jasig.cas.client.util;
import junit.framework.TestCase;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
import java.util.ArrayList;
import java.util.Collection;
@@ -104,4 +106,18 @@ public final class CommonUtilsTests extends TestCase {
assertFalse(CommonUtils.isNotBlank(null));
assertFalse(CommonUtils.isNotBlank(" "));
}
+
+ public void testConstructServiceUrlWithTrailingSlash() {
+ final String CONST_MY_URL = "https://www.myserver.com/hello/hithere/";
+ 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.myserver.com", "ticket", false);
+
+ assertEquals(CONST_MY_URL, constructedUrl);
+
+
+
+ }
}
diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/validation/Saml11TicketValidatorTests.java b/cas-client-core/src/test/java/org/jasig/cas/client/validation/Saml11TicketValidatorTests.java
index b943da4..cb03a49 100644
--- a/cas-client-core/src/test/java/org/jasig/cas/client/validation/Saml11TicketValidatorTests.java
+++ b/cas-client-core/src/test/java/org/jasig/cas/client/validation/Saml11TicketValidatorTests.java
@@ -33,8 +33,7 @@ public final class Saml11TicketValidatorTests extends AbstractTicketValidatorTes
" ResponseID=\"_3b62bece2e8da1c10279db04882012ac\">
+ * Because its tough to share state between valves, we expose the storage mechanism via a static variable. + *
+ * This valve should be ordered before the authentication valves. + * + * @author Scott Battaglia + * @version $Revision$ $Date$ + * @since 3.1.12 + */ +public final class ProxyCallbackValve extends ValveBase { + + private static ProxyGrantingTicketStorage PROXY_GRANTING_TICKET_STORAGE; + + private String proxyGrantingTicketStorageClass; + + private String proxyCallbackUrl; + + public static ProxyGrantingTicketStorage getProxyGrantingTicketStorage() { + return PROXY_GRANTING_TICKET_STORAGE; + } + + public void setProxyGrantingTicketStorageClass(final String proxyGrantingTicketStorageClass) { + this.proxyGrantingTicketStorageClass = proxyGrantingTicketStorageClass; + } + + public void setProxyCallbackUrl(final String proxyCallbackUrl) { + this.proxyCallbackUrl = proxyCallbackUrl; + } + + protected void startInternal() throws LifecycleException { + super.startInternal(); + + try { + CommonUtils.assertNotNull(this.proxyCallbackUrl, "the proxy callback url cannot be null"); + CommonUtils.assertTrue(this.proxyCallbackUrl.startsWith("/"), "proxy callback url must start with \"/\""); + + final Class proxyGrantingTicketStorage = Class.forName(proxyGrantingTicketStorageClass); + PROXY_GRANTING_TICKET_STORAGE = (ProxyGrantingTicketStorage) proxyGrantingTicketStorage.newInstance(); + } catch (final Exception e) { + throw new LifecycleException(e); + } + } + + public void invoke(final Request request, final Response response) throws IOException, ServletException { + if (this.proxyCallbackUrl.equals(request.getRequestURI())) { + CommonUtils.readAndRespondToProxyReceptorRequest(request, response, PROXY_GRANTING_TICKET_STORAGE); + return; + } + + getNext().invoke(request, response); + } +} diff --git a/cas-client-integration-tomcat/src/main/java/org/jasig/cas/client/tomcat/RegExpBasedLogoutValue.java b/cas-client-integration-tomcat/src/main/java/org/jasig/cas/client/tomcat/RegExpBasedLogoutValue.java new file mode 100644 index 0000000..042205e --- /dev/null +++ b/cas-client-integration-tomcat/src/main/java/org/jasig/cas/client/tomcat/RegExpBasedLogoutValue.java @@ -0,0 +1,52 @@ +package org.jasig.cas.client.tomcat; + +import org.apache.catalina.LifecycleException; +import org.apache.catalina.connector.Request; +import org.jasig.cas.client.util.CommonUtils; + +import java.util.regex.Pattern; + +/** + * Matches a number of urls (based on the regular expression) for handling + * log out. + * + * @author Scott Battaglia + * @version $Revision$ $Date$ + * @since 3.1.12 + */ +public final class RegExpBasedLogoutValue extends AbstractLogoutValveBase { + + private String regexpUri; + + private Pattern regexpUriPattern; + + private String redirectUrl; + + public void setRegexpUri(final String regexpUri) { + this.regexpUri = regexpUri; + } + + public void setRedirectUrl(final String redirectUrl) { + this.redirectUrl = redirectUrl; + } + + protected void startInternal() throws LifecycleException { + super.startInternal(); + + try { + CommonUtils.assertNotNull(this.regexpUri, "A Regular Expression must be provided."); + + this.regexpUriPattern = Pattern.compile(this.regexpUri); + } catch (final Exception e) { + throw new LifecycleException(e); + } + } + + protected boolean isLogoutRequest(final Request request) { + return this.regexpUriPattern.matcher(request.getRequestURI()).matches(); + } + + protected String constructRedirectUrl(final Request request) { + return this.redirectUrl; + } +} diff --git a/cas-client-integration-tomcat/src/main/java/org/jasig/cas/client/tomcat/UrlBasedLogoutValve.java b/cas-client-integration-tomcat/src/main/java/org/jasig/cas/client/tomcat/UrlBasedLogoutValve.java new file mode 100644 index 0000000..2410755 --- /dev/null +++ b/cas-client-integration-tomcat/src/main/java/org/jasig/cas/client/tomcat/UrlBasedLogoutValve.java @@ -0,0 +1,55 @@ +package org.jasig.cas.client.tomcat; + +import org.apache.catalina.LifecycleException; +import org.apache.catalina.connector.Request; +import org.jasig.cas.client.util.CommonUtils; + +/** + * Monitors a specific url for logout requests. + * + * @author Scott Battaglia + * @version $Revision$ $Date$ + * @since 3.1.12 + */ +public final class UrlBasedLogoutValve extends AbstractLogoutValveBase { + + private String logoutUri; + + private String redirectUrl; + + /** + * The logout url to watch for logout requests. + * + * @param logoutUri the url. CANNOT be null. MUST be relative and start with "/" + */ + public void setLogoutUri(final String logoutUri) { + this.logoutUri = logoutUri; + } + + /** + * Optional url to redirect to after logout is complete. + * + * @param redirectUrl the url. CAN be NULL. + */ + public void setRedirectUrl(final String redirectUrl) { + this.redirectUrl = redirectUrl; + } + + protected void startInternal() throws LifecycleException { + super.startInternal(); + try { + CommonUtils.assertNotNull(this.logoutUri, "logoutUri cannot be null."); + CommonUtils.assertTrue(this.logoutUri.startsWith("/"), "logoutUri must start with \"/\""); + } catch (final IllegalArgumentException e) { + throw new LifecycleException(e); + } + } + + protected boolean isLogoutRequest(final Request request) { + return this.logoutUri.equals(request.getRequestURI()); + } + + protected String constructRedirectUrl(final Request request) { + return redirectUrl; + } +}