diff --git a/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/AbstractAuthenticator.java b/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/AbstractAuthenticator.java
new file mode 100644
index 0000000..9b17b5e
--- /dev/null
+++ b/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/AbstractAuthenticator.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2007 The JA-SIG Collaborative. All rights reserved. See license
+ * distributed with this file and available online at
+ * http://www.ja-sig.org/products/cas/overview/license/index.html
+ */
+package org.jasig.cas.client.tomcat.v6;
+
+import org.apache.catalina.LifecycleEvent;
+import org.apache.catalina.LifecycleException;
+import org.apache.catalina.LifecycleListener;
+import org.apache.catalina.Realm;
+import org.apache.catalina.authenticator.AuthenticatorBase;
+import org.apache.catalina.connector.Request;
+import org.apache.catalina.connector.Response;
+import org.apache.catalina.deploy.LoginConfig;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jasig.cas.client.tomcat.AuthenticatorDelegate;
+import org.jasig.cas.client.tomcat.CasRealm;
+import org.jasig.cas.client.util.CommonUtils;
+import org.jasig.cas.client.validation.TicketValidator;
+
+import java.io.IOException;
+import java.security.Principal;
+
+/**
+ * Base authenticator for all authentication protocols supported by CAS.
+ *
+ * @author Scott Battaglia
+ * @version $Revision$ $Date$
+ * @since 3.1.12
+ */
+public abstract class AbstractAuthenticator extends AuthenticatorBase implements LifecycleListener {
+
+ protected final Log log = LogFactory.getLog(getClass());
+
+ private final AuthenticatorDelegate delegate = new AuthenticatorDelegate();
+
+ private String casServerUrlPrefix;
+
+ private String encoding;
+
+ private boolean encode;
+
+ private boolean renew;
+
+ protected abstract String getAuthenticationMethod();
+
+ protected abstract String getArtifactParameterName();
+
+ protected abstract String getServiceParameterName();
+
+ protected abstract TicketValidator getTicketValidator();
+
+
+ public void start() throws LifecycleException {
+ super.start();
+ this.log.debug("Starting...");
+ final Realm realm = this.context.getRealm();
+ if (!(realm instanceof CasRealm)) {
+ throw new LifecycleException("Expected CasRealm but got " + realm.getInfo());
+ }
+ try {
+ CommonUtils.assertNotNull(this.casServerUrlPrefix, "casServerUrlPrefix cannot be null.");
+ CommonUtils.assertNotNull(this.delegate.getCasServerLoginUrl(), "casServerLoginUrl cannot be null.");
+ CommonUtils.assertTrue(
+ this.delegate.getServerName() != null || this.delegate.getServiceUrl() != null,
+ "either serverName or serviceUrl must be set.");
+ this.delegate.setRealm((CasRealm) realm);
+ } catch (final Exception e) {
+ throw new LifecycleException(e);
+ }
+ // Complete delegate initialization after the component is started.
+ // See #lifecycleEvent() method.
+ addLifecycleListener(this);
+ }
+
+ protected final String getCasServerUrlPrefix() {
+ return this.casServerUrlPrefix;
+ }
+
+ public final void setCasServerUrlPrefix(final String casServerUrlPrefix) {
+ this.casServerUrlPrefix = casServerUrlPrefix;
+ }
+
+ public final void setCasServerLoginUrl(final String casServerLoginUrl) {
+ this.delegate.setCasServerLoginUrl(casServerLoginUrl);
+ }
+
+ public final boolean isEncode() {
+ return this.encode;
+ }
+
+ public final void setEncode(final boolean encode) {
+ this.encode = encode;
+ }
+
+ protected final boolean isRenew() {
+ return this.renew;
+ }
+
+ public void setRenew(final boolean renew) {
+ this.renew = renew;
+ }
+
+ public final void setServerName(final String serverName) {
+ this.delegate.setServerName(serverName);
+ }
+
+ public final void setServiceUrl(final String serviceUrl) {
+ this.delegate.setServiceUrl(serviceUrl);
+ }
+
+ protected final String getEncoding() {
+ return this.encoding;
+ }
+
+ public final void setEncoding(final String encoding) {
+ this.encoding = encoding;
+ }
+
+ /** {@inheritDoc} */
+ public final boolean authenticate(final Request request, final Response response, final LoginConfig loginConfig) throws IOException {
+ Principal principal = request.getUserPrincipal();
+ boolean result = false;
+ if (principal == null) {
+ // Authentication sets the response headers for status and redirect if needed
+ principal = this.delegate.authenticate(request.getRequest(), response);
+ if (principal != null) {
+ request.setAuthType(getAuthenticationMethod());
+ request.setUserPrincipal(principal);
+ result = true;
+ }
+ } else {
+ result = true;
+ }
+ return result;
+ }
+
+ /** {@inheritDoc} */
+ public void lifecycleEvent(final LifecycleEvent event) {
+ if (AFTER_START_EVENT.equals(event.getType())) {
+ this.log.debug("Processing lifecycle event " + AFTER_START_EVENT);
+ this.delegate.setTicketValidator(getTicketValidator());
+ this.delegate.setArtifactParameterName(getArtifactParameterName());
+ this.delegate.setServiceParameterName(getServiceParameterName());
+ }
+ }
+
+ /** {@inheritDoc} */
+ public String getInfo() {
+ return getClass().getName() + "/1.0";
+ }
+}
diff --git a/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/AbstractCasAuthenticator.java b/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/AbstractCasAuthenticator.java
new file mode 100644
index 0000000..2ac6995
--- /dev/null
+++ b/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/AbstractCasAuthenticator.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2007 The JA-SIG Collaborative. All rights reserved. See license
+ * distributed with this file and available online at
+ * http://www.ja-sig.org/products/cas/overview/license/index.html
+ */
+package org.jasig.cas.client.tomcat.v6;
+
+/**
+ * Base class for all CAS protocol authenticators.
+ *
+ * @author Scott Battaglia
+ * @version $Revision$ $Date$
+ * @since 3.1.12
+ */
+public abstract class AbstractCasAuthenticator extends AbstractAuthenticator {
+
+ private String proxyCallbackUrl;
+
+
+ protected final String getProxyCallbackUrl() {
+ return this.proxyCallbackUrl;
+ }
+
+ public final void setProxyCallbackUrl(final String proxyCallbackUrl) {
+ this.proxyCallbackUrl = proxyCallbackUrl;
+ }
+
+ protected final String getArtifactParameterName() {
+ return "ticket";
+ }
+
+ protected final String getServiceParameterName() {
+ return "service";
+ }
+}
diff --git a/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/AbstractCasRealm.java b/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/AbstractCasRealm.java
new file mode 100644
index 0000000..d0133d6
--- /dev/null
+++ b/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/AbstractCasRealm.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2010 The JA-SIG Collaborative. All rights reserved. See license
+ * distributed with this file and available online at
+ * http://www.ja-sig.org/products/cas/overview/license/index.html
+ */
+package org.jasig.cas.client.tomcat.v6;
+
+import java.security.Principal;
+
+import org.apache.catalina.realm.RealmBase;
+import org.jasig.cas.client.tomcat.CasRealm;
+
+/**
+ * Base Realm implementation for all CAS realms.
+ *
+ * @author Marvin S. Addison
+ * @version $Revision$
+ *
+ */
+public abstract class AbstractCasRealm extends RealmBase implements CasRealm {
+ /** {@inheritDoc} */
+ public Principal authenticate(final Principal p) {
+ return getDelegate().authenticate(p);
+ }
+
+ /** {@inheritDoc} */
+ public String[] getRoles(final Principal p) {
+ return getDelegate().getRoles(p);
+ }
+
+ /** {@inheritDoc} */
+ public boolean hasRole(final Principal principal, final String role) {
+ return getDelegate().hasRole(principal, role);
+ }
+
+ /** {@inheritDoc} */
+ public String toString() {
+ return getName();
+ }
+
+ /** {@inheritDoc} */
+ public String getInfo() {
+ return getClass().getName() + "/1.0";
+ }
+
+ /** {@inheritDoc} */
+ protected String getName() {
+ return getClass().getSimpleName();
+ }
+
+ /** {@inheritDoc} */
+ protected String getPassword(final String username) {
+ throw new UnsupportedOperationException();
+ }
+
+ /** {@inheritDoc} */
+ protected Principal getPrincipal(String username) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @return Delegate that all {@link CasRealm} operations are delegated to.
+ */
+ protected abstract CasRealm getDelegate();
+}
diff --git a/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/AbstractLifecycleValve.java b/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/AbstractLifecycleValve.java
new file mode 100644
index 0000000..c8a16c1
--- /dev/null
+++ b/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/AbstractLifecycleValve.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2010 The JA-SIG Collaborative. All rights reserved. See license
+ * distributed with this file and available online at
+ * http://www.ja-sig.org/products/cas/overview/license/index.html
+ */
+package org.jasig.cas.client.tomcat.v6;
+
+import org.apache.catalina.Lifecycle;
+import org.apache.catalina.LifecycleException;
+import org.apache.catalina.LifecycleListener;
+import org.apache.catalina.util.LifecycleSupport;
+import org.apache.catalina.valves.ValveBase;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Base Valve implementation for valves that need Catalina lifecycle
+ * management, including {@link #start()} and {@link #stop()} methods.
+ *
+ * @author Marvin S. Addison
+ * @version $Revision$
+ *
+ */
+public abstract class AbstractLifecycleValve extends ValveBase implements Lifecycle {
+ /** Logger instance */
+ protected final Log log = LogFactory.getLog(getClass());
+
+ /** Lifecycle listeners */
+ private LifecycleSupport lifecycle = new LifecycleSupport(this);
+
+
+ /** {@inheritDoc} */
+ public void addLifecycleListener(final LifecycleListener listener) {
+ lifecycle.addLifecycleListener(listener);
+ }
+
+ /** {@inheritDoc} */
+ public LifecycleListener[] findLifecycleListeners() {
+ return lifecycle.findLifecycleListeners();
+ }
+
+ /** {@inheritDoc} */
+ public void removeLifecycleListener(final LifecycleListener listener) {
+ lifecycle.removeLifecycleListener(listener);
+ }
+
+ /** {@inheritDoc} */
+ public void start() throws LifecycleException {
+ log.debug("Valve starting.");
+ }
+
+ /** {@inheritDoc} */
+ public void stop() throws LifecycleException {
+ log.debug("Valve stopping.");
+ }
+
+}
diff --git a/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/AbstractLogoutValve.java b/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/AbstractLogoutValve.java
new file mode 100644
index 0000000..1bbf15d
--- /dev/null
+++ b/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/AbstractLogoutValve.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2007 The JA-SIG Collaborative. All rights reserved. See license
+ * distributed with this file and available online at
+ * http://www.ja-sig.org/products/cas/overview/license/index.html
+ */
+package org.jasig.cas.client.tomcat.v6;
+
+import org.apache.catalina.connector.Request;
+import org.apache.catalina.connector.Response;
+import org.jasig.cas.client.util.AbstractCasFilter;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpSession;
+import java.io.IOException;
+
+/**
+ * Abstract base class for Container-managed log out. Removes the attributes
+ * from the session.
+ *
+ * @author Scott Battaglia
+ * @version $Revision$ $Date$
+ * @since 3.1.12
+ */
+public abstract class AbstractLogoutValve extends AbstractLifecycleValve {
+
+ public final void invoke(final Request request, final Response response) throws IOException, ServletException {
+
+ if (!isLogoutRequest(request)) {
+ log.debug("Current request URI [ " + request.getRequestURI() + "] is not a logout request.");
+ getNext().invoke(request, response);
+ return;
+ }
+
+ final HttpSession httpSession = request.getSession(false);
+
+ if (httpSession != null) {
+ httpSession.removeAttribute(AbstractCasFilter.CONST_CAS_ASSERTION);
+ }
+
+ final String redirectUrl = constructRedirectUrl(request);
+
+ if (redirectUrl != null) {
+ response.sendRedirect(redirectUrl);
+ }
+ }
+
+ /**
+ * Determines if this is a request to destroy the container-managed single sign on session.
+ *
+ * @param request the request. CANNOT be NULL.
+ * @return true if it is a logout request, false otherwise.
+ */
+ protected abstract boolean isLogoutRequest(Request request);
+
+ /**
+ * Constructs a url to redirect to.
+ *
+ * @param request the original request.
+ * @return the url to redirect to. CAN be NULL.
+ */
+ protected abstract String constructRedirectUrl(Request request);
+}
diff --git a/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/AssertionCasRealm.java b/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/AssertionCasRealm.java
new file mode 100644
index 0000000..5cd8f94
--- /dev/null
+++ b/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/AssertionCasRealm.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2010 The JA-SIG Collaborative. All rights reserved. See license
+ * distributed with this file and available online at
+ * http://www.ja-sig.org/products/cas/overview/license/index.html
+ */
+package org.jasig.cas.client.tomcat.v6;
+
+import org.jasig.cas.client.tomcat.AssertionCasRealmDelegate;
+import org.jasig.cas.client.tomcat.CasRealm;
+
+/**
+ * Tomcat Realm that implements {@link CasRealm} for principal and
+ * role data backed by the CAS {@link Assertion}.
+ *
+ * Authentication always succeeds and simply returns the given principal.
+ *
+ * @author Marvin S. Addison
+ * @version $Revision$
+ *
+ */
+public class AssertionCasRealm extends AbstractCasRealm {
+ private final AssertionCasRealmDelegate delegate = new AssertionCasRealmDelegate();
+
+ /**
+ * @param name Name of the attribute in the principal that contains role data.
+ */
+ public void setRoleAttributeName(final String name) {
+ delegate.setRoleAttributeName(name);
+ }
+
+ /** {@inheritDoc} */
+ protected CasRealm getDelegate() {
+ return delegate;
+ }
+}
diff --git a/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/Cas10CasAuthenticator.java b/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/Cas10CasAuthenticator.java
new file mode 100644
index 0000000..e351c27
--- /dev/null
+++ b/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/Cas10CasAuthenticator.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2007 The JA-SIG Collaborative. All rights reserved. See license
+ * distributed with this file and available online at
+ * http://www.ja-sig.org/products/cas/overview/license/index.html
+ */
+package org.jasig.cas.client.tomcat.v6;
+
+import org.apache.catalina.LifecycleException;
+import org.jasig.cas.client.validation.Cas10TicketValidator;
+import org.jasig.cas.client.validation.TicketValidator;
+
+/**
+ * Authenticator that handles CAS 1.0 protocol.
+ *
+ * @author Scott Battaglia
+ * @version $Revision$ $Date$
+ * @since 3.1.12
+ */
+public class Cas10CasAuthenticator extends AbstractCasAuthenticator {
+ public static final String AUTH_METHOD = "CAS10";
+
+ private Cas10TicketValidator ticketValidator;
+
+ protected TicketValidator getTicketValidator() {
+ return this.ticketValidator;
+ }
+
+ protected String getAuthenticationMethod() {
+ return AUTH_METHOD;
+ }
+
+ public void start() throws LifecycleException {
+ super.start();
+ this.ticketValidator = new Cas10TicketValidator(getCasServerUrlPrefix());
+ lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);
+ this.log.debug("Startup completed.");
+ }
+}
diff --git a/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/Cas20CasAuthenticator.java b/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/Cas20CasAuthenticator.java
new file mode 100644
index 0000000..80f246c
--- /dev/null
+++ b/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/Cas20CasAuthenticator.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2007 The JA-SIG Collaborative. All rights reserved. See license
+ * distributed with this file and available online at
+ * http://www.ja-sig.org/products/cas/overview/license/index.html
+ */
+package org.jasig.cas.client.tomcat.v6;
+
+import org.apache.catalina.LifecycleException;
+import org.jasig.cas.client.validation.Cas20ServiceTicketValidator;
+import org.jasig.cas.client.validation.TicketValidator;
+
+/**
+ * Authenticator that handles the CAS 2.0 protocol.
+ *
+ * @author Scott Battaglia
+ * @version $Revision$ $Date$
+ * @since 3.1.12
+ */
+public final class Cas20CasAuthenticator extends AbstractCasAuthenticator {
+ public static final String AUTH_METHOD = "CAS20";
+
+ private Cas20ServiceTicketValidator ticketValidator;
+
+ protected TicketValidator getTicketValidator() {
+ return this.ticketValidator;
+ }
+
+ protected String getAuthenticationMethod() {
+ return AUTH_METHOD;
+ }
+
+ public void start() throws LifecycleException {
+ super.start();
+ this.ticketValidator = new Cas20ServiceTicketValidator(getCasServerUrlPrefix());
+ if (getEncoding() != null) {
+ this.ticketValidator.setEncoding(getEncoding());
+ }
+ this.ticketValidator.setProxyCallbackUrl(getProxyCallbackUrl());
+ this.ticketValidator.setProxyGrantingTicketStorage(ProxyCallbackValve.getProxyGrantingTicketStorage());
+ this.ticketValidator.setRenew(isRenew());
+ lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);
+ this.log.debug("Startup completed.");
+ }
+}
diff --git a/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/Cas20ProxyCasAuthenticator.java b/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/Cas20ProxyCasAuthenticator.java
new file mode 100644
index 0000000..c0e7eb3
--- /dev/null
+++ b/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/Cas20ProxyCasAuthenticator.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2007 The JA-SIG Collaborative. All rights reserved. See license
+ * distributed with this file and available online at
+ * http://www.ja-sig.org/products/cas/overview/license/index.html
+ */
+package org.jasig.cas.client.tomcat.v6;
+
+import org.apache.catalina.LifecycleException;
+import org.jasig.cas.client.util.CommonUtils;
+import org.jasig.cas.client.validation.Cas20ProxyTicketValidator;
+import org.jasig.cas.client.validation.TicketValidator;
+
+/**
+ * Authenticator that handles the CAS 2.0 protocol with proxying support.
+ *
+ * @author Scott Battaglia
+ * @version $Revision$ $Date$
+ * @since 3.1.12
+ */
+public final class Cas20ProxyCasAuthenticator extends AbstractCasAuthenticator {
+ public static final String AUTH_METHOD = "CAS20-PROXY";
+
+ private Cas20ProxyTicketValidator ticketValidator;
+
+ private boolean acceptAnyProxy;
+
+ private String allowedProxyChains;
+
+ public void setAcceptAnyProxy(final boolean acceptAnyProxy) {
+ this.acceptAnyProxy = acceptAnyProxy;
+ }
+
+ public void setAllowedProxyChains(final String allowedProxyChains) {
+ this.allowedProxyChains = allowedProxyChains;
+ }
+
+ protected TicketValidator getTicketValidator() {
+ return this.ticketValidator;
+ }
+
+ protected String getAuthenticationMethod() {
+ return AUTH_METHOD;
+ }
+
+ public void start() throws LifecycleException {
+ super.start();
+ this.ticketValidator = new Cas20ProxyTicketValidator(getCasServerUrlPrefix());
+ this.ticketValidator.setRenew(isRenew());
+ this.ticketValidator.setProxyCallbackUrl(getProxyCallbackUrl());
+ this.ticketValidator.setProxyGrantingTicketStorage(ProxyCallbackValve.getProxyGrantingTicketStorage());
+ this.ticketValidator.setAcceptAnyProxy(this.acceptAnyProxy);
+ this.ticketValidator.setAllowedProxyChains(CommonUtils.createProxyList(this.allowedProxyChains));
+ if (getEncoding() != null) {
+ this.ticketValidator.setEncoding(getEncoding());
+ }
+ lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);
+ this.log.debug("Startup completed.");
+ }
+}
diff --git a/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/PropertiesCasRealm.java b/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/PropertiesCasRealm.java
new file mode 100644
index 0000000..09b3493
--- /dev/null
+++ b/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/PropertiesCasRealm.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2010 The JA-SIG Collaborative. All rights reserved. See license
+ * distributed with this file and available online at
+ * http://www.ja-sig.org/products/cas/overview/license/index.html
+ */
+package org.jasig.cas.client.tomcat.v6;
+
+import org.apache.catalina.LifecycleException;
+import org.jasig.cas.client.tomcat.CasRealm;
+import org.jasig.cas.client.tomcat.PropertiesCasRealmDelegate;
+
+/**
+ * Tomcat Realm that implements {@link CasRealm} backed by properties file
+ * containing usernames/and roles of the following format:
+ *
+ * username1=role1,role2,role3 + * username2=role1 + * username3=role2,role3 + *+ * User authentication succeeds if the name of the given principal exists as + * a username in the properties file. + * + * @author Marvin S. Addison + * @version $Revision$ + * + */ +public class PropertiesCasRealm extends AbstractCasRealm { + private final PropertiesCasRealmDelegate delegate = new PropertiesCasRealmDelegate(); + + /** + * @param path Path to properties file container username/role data. + */ + public void setPropertiesFilePath(final String path) { + delegate.setPropertiesFilePath(path); + } + + /** {@inheritDoc} */ + public void start() throws LifecycleException { + super.start(); + delegate.readProperties(); + } + + /** {@inheritDoc} */ + protected CasRealm getDelegate() { + return delegate; + } + +} diff --git a/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/ProxyCallbackValve.java b/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/ProxyCallbackValve.java new file mode 100644 index 0000000..8258472 --- /dev/null +++ b/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/ProxyCallbackValve.java @@ -0,0 +1,70 @@ +/* + * Copyright 2007 The JA-SIG Collaborative. All rights reserved. See license + * distributed with this file and available online at + * http://www.ja-sig.org/products/cas/overview/license/index.html + */ +package org.jasig.cas.client.tomcat.v6; + +import org.apache.catalina.LifecycleException; +import org.apache.catalina.connector.Request; +import org.apache.catalina.connector.Response; +import org.jasig.cas.client.proxy.ProxyGrantingTicketStorage; +import org.jasig.cas.client.util.CommonUtils; + +import javax.servlet.ServletException; +import java.io.IOException; + +/** + * Handles watching a url for the proxy callback. + *
+ * 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 AbstractLifecycleValve { + + 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; + } + + public void start() throws LifecycleException { + super.start(); + + 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-v6/src/main/java/org/jasig/cas/client/tomcat/v6/RegExpBasedLogoutValue.java b/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/RegExpBasedLogoutValue.java new file mode 100644 index 0000000..eb04188 --- /dev/null +++ b/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/RegExpBasedLogoutValue.java @@ -0,0 +1,57 @@ +/* + * Copyright 2007 The JA-SIG Collaborative. All rights reserved. See license + * distributed with this file and available online at + * http://www.ja-sig.org/products/cas/overview/license/index.html + */ +package org.jasig.cas.client.tomcat.v6; + +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 AbstractLogoutValve { + + 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; + } + + public void start() throws LifecycleException { + super.start(); + + 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-v6/src/main/java/org/jasig/cas/client/tomcat/v6/Saml11Authenticator.java b/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/Saml11Authenticator.java new file mode 100644 index 0000000..614800a --- /dev/null +++ b/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/Saml11Authenticator.java @@ -0,0 +1,67 @@ +/* + * Copyright 2010 The JA-SIG Collaborative. All rights reserved. See license + * distributed with this file and available online at + * http://www.ja-sig.org/products/cas/overview/license/index.html + */ +package org.jasig.cas.client.tomcat.v6; + +import org.apache.catalina.LifecycleException; +import org.jasig.cas.client.validation.Saml11TicketValidator; +import org.jasig.cas.client.validation.TicketValidator; + +/** + * CAS authenticator that uses the SAML 1.1 protocol. + * + * @author Marvin S. Addison + * @version $Revision$ + * + */ +public class Saml11Authenticator extends AbstractAuthenticator { + public static final String AUTH_METHOD = "SAML11"; + + private Saml11TicketValidator ticketValidator; + + /** SAML protocol clock drift tolerance in ms */ + private int tolerance = -1; + + + /** + * @param ms SAML clock drift tolerance in milliseconds. + */ + public void setTolerance(final int ms) { + this.tolerance = ms; + } + + public void start() throws LifecycleException { + super.start(); + this.ticketValidator = new Saml11TicketValidator(getCasServerUrlPrefix()); + if (this.tolerance > -1) { + this.ticketValidator.setTolerance(this.tolerance); + } + if (getEncoding() != null) { + this.ticketValidator.setEncoding(getEncoding()); + } + this.ticketValidator.setRenew(isRenew()); + lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null); + this.log.debug("Startup completed."); + } + + protected TicketValidator getTicketValidator() { + return this.ticketValidator; + } + + protected String getAuthenticationMethod() { + return AUTH_METHOD; + } + + /** {@inheritDoc} */ + protected String getArtifactParameterName() { + return "SAMLart"; + } + + /** {@inheritDoc} */ + protected String getServiceParameterName() { + return "TARGET"; + } + +} diff --git a/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/UrlBasedLogoutValve.java b/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/UrlBasedLogoutValve.java new file mode 100644 index 0000000..a59b7b8 --- /dev/null +++ b/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/UrlBasedLogoutValve.java @@ -0,0 +1,60 @@ +/* + * Copyright 2007 The JA-SIG Collaborative. All rights reserved. See license + * distributed with this file and available online at + * http://www.ja-sig.org/products/cas/overview/license/index.html + */ +package org.jasig.cas.client.tomcat.v6; + +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 AbstractLogoutValve { + + 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; + } + + public void start() throws LifecycleException { + super.start(); + 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; + } +}