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; + } +}