Soulwing Logo

Simplified CAS authentication for Java-based web applications

Overview

Documentation

Container-Managed CAS for Tomcat

This document describes how to configure your Tomcat container to support CAS authentication at the container level, allowing deployed applications to take advantage of CAS using the standard security declarations in web.xml with no need to include a CAS filter in the application itself.

Motivation

An important benefit of the Java Servlet specification is the declarative security mechanism. Using declarations in web.xml, an application can specify the roles required to access the application's resources, and it can specify what kind of authentication should be performed to determine the identity of the user and the roles granted to that user. Generally, the application doesn't need to be concerned with how authentication or authorization is performed, or what specific services and/or resources are required to authenticate and authorize users — the application specifies what needs to be protected and the servlet container takes responsibility for knowing how to implement those protections.

Traditionally, CAS authentication has been plugged in to applications by means of servlet filters and other types of configuration in web.xml. While this approach retains some of the benefits of declarative security, it does move a significant portion of the responsibility for protecting application resources into the application itself. Worse, using CAS filters for authentication in the application generally precludes the use of the container-provided role constraint mechanisms, leaving the application responsible not only for authentication but also for authorization.

CAS filter configuration (such as that needed for the filters in the Soulwing CAS Client) is often very detailed and a bit tricky to get right. In an enterprise application environment using filters for CAS authentication, every deployed application must be correctly configured with essentially the same (highly detailed) CAS configuration. This can be difficult to manage.

Moving CAS support into the container has several important benefits:

A disadvantage of container-managed CAS authentication is that it is not one of the standard authentication modes provided in the Java Servlet specification. Because container-managed CAS is non-standard, a web application whose deployment descriptor specifies CAS authentication can be deployed only in a container that is configured to support it. In enterprise environments where CAS is typically employed, this limitation is unlikely to be a problem.

Another disadvantage of container-managed CAS authentication is that only the Tomcat container is presently supported. Community support in developing adaptations for other servlet containers is welcome.

How it Works

Tomcat provides several useful extension points that are utilized by the Soulwing CAS Client to integrate CAS authentication support with the container. These extension points allow CAS to be easily and consisely configured in Tomcat's server.xml.

Tomcat's Authenticator interface is implemented by a Java object that performs some type of authentication. The standard implementations of the Authenticator interface provide support for BASIC, DIGEST, FORM, and CLIENT-CERT authentication. The Soulwing CAS client's Tomcat support provides an Authenticator that implements the CAS authentication protocol.

An implementation of the Tomcat Realm interface is used to perform the actual authentication against a database of credentials and to lookup the roles granted to an authentic user. In traditional authentication mechanisms such as BASIC, the underlying persistent storage of the realm is used to store the credentials for each known user. The Soulwing client's Tomcat support can utilize any of Tomcat's included Realm providers to determine the roles granted to CAS-authenticated user, while delegating the authentication itself to the CAS server. Additionally, any custom Realm implementation that extends Tomcat's RealmBase can be used with the Soulwing client's Tomcat support.

In the Tomcat container, a Valve serves much the same role as a Filter in a web application. The Soulwing client's CAS support for Tomcat uses several custom Valve implementations to inspect and modify incoming requests to the Tomcat engine as part of CAS protocol processing.

Tomcat provides a context for JNDI resources that can be used by container components and applications deployed in the container. The Soulwing CAS client configuration used in Tomcat places the CAS protocol configuration details into a global naming resource that can be accessed by the CAS Authenticator element. Applications that need to use CAS proxy authentication to access back-end services can also obtain the required CAS configuration and proxy authentication support using a declared <resource-ref> in web.xml

Configuring the Tomcat Container

This section describes the required configuration of the Tomcat container needed to support container-managed CAS authentication. This is known to work with Tomcat 6 and Tomcat 5.

Install library JAR files

Library JAR files needed by container components in Tomcat must be placed in Tomcat's library directory. The location varies, depending on whether you are running Tomcat 6 or Tomcat 5.

Copy the following JAR files into $CATALINA_HOME/lib (or $CATALINA_HOME/common/lib if you are running Tomcat 5).

Copy the following JAR file into $CATALINA_HOME/lib (or $CATALINA_HOME/server/lib of you are running Tomcat 5).

Augment Tomcat's Default Authenticators

In Tomcat's catalina.jar, the properties resource Authenticators.properties contains the mapping of authentication method names (e.g. BASIC, DIGEST, etc) to provider Authenticator class names. The file contents are as follows (the last line has been added to enable CAS authentication support).

# These must match the allowed values for auth-method as defined by the spec 
BASIC=org.apache.catalina.authenticator.BasicAuthenticator
CLIENT-CERT=org.apache.catalina.authenticator.SSLAuthenticator
DIGEST=org.apache.catalina.authenticator.DigestAuthenticator
FORM=org.apache.catalina.authenticator.FormAuthenticator
NONE=org.apache.catalina.authenticator.NonLoginAuthenticator
CAS=org.soulwing.cas.apps.tomcat.CasAuthenticator
		  

The safest way to override the default Authenticator.properties is to extract it from catalina.jar and then edit it to add the CAS authentication type to the file.

To extract the default Authenticators.properties, use these commands (you may need to make adjustments for your shell's syntax)

Tomcat 6

cd $CATALINA_HOME/lib
jar -xvf catalina.jar org/apache/catalina/startup/Authenticators.properties
		  

Tomcat 5

cd $CATALINA_HOME/server/classes
jar -xvf ../server/lib/catalina.jar org/apache/catalina/startup/Authenticators.properties
		  

After the file has been extracted, open it in your favorite plain text editor and add the line for CAS shown above.

Configure a CasProtocolConfiguration Resource

Inside Tomcat's <GlobalNamingResources> element in server.xml, you need to add a <Resource> for the CAS protocol configuration. If your server.xml already has the global naming resources element, add the <Resource> shown here to it, otherwise paste the entire text shown here inside of the <Server> element.

<GlobalNamingResources>
  <Resource name="CasProtocolConfiguration" auth="Container"
      type="org.soulwing.cas.client.ProtocolConfigurationImpl"
      factory="org.soulwing.cas.client.ProtocolConfigurationFactory"
      description="CAS protocol configuration"
      serverUrl="YOUR CAS SERVER URL HERE" 
      serviceUrl="YOUR TOMCAT SERVER URL HERE" />
</GlobalNamingResources>
      

Replace the value for the serverUrl attribute with the URL for your CAS server. The URL must not include a servlet path such as /login; e.g. http://cas.my.org/cas

Replace the value for the serviceUrl attribute with the base URL for the Tomcat server in which CAS is being configured; e.g. https://tomcat.my.org:8443

If you wish to allow applications to make use of CAS proxy authentication to authenticate to back-end web services, you must also configure the proxyCallbackUrl attribute. This attribute specifies the base URL for the Tomcat server in which CAS is being configured, plus the same URI specified in the ProxyCallbackValve described further below; e.g. https://tomcat.my.org:8443/casProxyCallback

Realm Configuration

In order to use CAS authentication with Tomcat, you must configure a <Realm> element in the <Engine>, <Host>, or <Context> in which it is to be used. The CAS client components for Tomcat support any of the Realm implementations provided with Tomcat. Custom realms that extend Tomcat's RealmBase are also supported.

The configured Realm must include usernames and roles for each CAS user. Often, the same user database resource that supports the CAS server can be configured using a JndiRealm or JdbcRealm. Note that for an application using CAS authentication, the credentials in the user database resource are not used by the realm itself because the authentication is delegated to CAS. In this case the realm is used merely to determine the roles granted to a CAS authenticated user.

A simple working configuration can be achieved using Tomcat's UserDatabaseRealm with usernames and roles configured in tomcat-users.xml. Note that you need not configure all of the users known to your CAS server in your Tomcat user database — only those users who need to access applications deployed in the Tomcat instance need to be configured. Also, while the passwords configured tomcat-users.xml are not used for applications that specify CAS authentication, they are used for applications that specify a different authentication method (e.g. BASIC).

CAS Valve Configuration

The <Valve> elements used for CAS authentication can be configured in server.xml within any <Engine>, <Host>, or <Context>. These instructions assume that you want CAS authentication to be provided for any application deployed in the Tomcat engine, and thus the CAS valves are configured at the <Engine> level. However, you can constrain CAS support to just a virtual host or a particular application, by configuring the required values at the <Host> or <Context> levels, respectively.

Configure a ResourceValve

Due to an apparent constraint of the Tomcat class loader configuration, the CAS Authenticator cannot directly access the CAS protocol configuration resource. To workaround this limitation, the CAS ResourceValve is responsible for looking up the protocol configuration resource in the global naming context and setting it as a container-private request attribute.

Add the following <Valve> element to server.xml inside of the <Engine> element (but outside any <Host> or <Context> elements).

<Valve className="org.soulwing.cas.apps.tomcat.ResourceValve"
  config="CasProtocolConfiguration"
  authenticatorClass="org.soulwing.cas.filter.ServiceValidationAuthenticator" />
      

The config attribute value specifies the name of the protocol configuration resource. You can omit it if you use CasProtocolConfiguration as the name of your protocol configuration resource.

The authenticatorClass attribute value specifies the fully-qualified class name of the CAS FilterAuthenticator implementation to use to perform CAS ticket validation. The default value shown above validates normal CAS service authentication tickets. If you wish to allow proxy authentication tickets as well as normal service authentication tickets, use the ProxyValidationAuthenticator instead. If the authenticatorClass attribute isn't specified, ServiceValidationAuthenticator is used by default.

Configure a LogoutValve (optional)

If you wish to allow deployed applications to request CAS logout, configure a LogoutValve. This valve removes the CAS authentication state from a user's session and optionally redirects to the CAS global logout URL.

Add the following <Valve> element to server.xml inside of the <Engine> element (but outside any <Host> or <Context> elements).

<Valve className="org.soulwing.cas.apps.tomcat.LogoutValve"
  logoutUri="/casLogout"
  redirectUrl="/logout.html"/>
      

The logoutUri attribute specifies a URI that the valve will look for in incoming requests to the Tomcat engine. A request for this URI will result in the user's CAS authentication state being cleared. If the request includes the query parameter global=true, the request will be redirected to the CAS global logout URL.

The redirectUrl attribute specifies a URL to which the request will be redirected if CAS global logout is not requested as described above.

Typically, an application will implement logout by defining its own logout URI and associated servlet or controller. When the application's logout URI is requested by a user, the logout servlet/controller will invalidate the user's session and then redirect the request to the URI configured for the LogoutValve to continue the logout process.

Configure a ProxyCallbackValve (optional)

If you wish to allow deployed applications to request proxy authentication tickets using the ProxyTicketService resource, you must configure a ProxyCallbackValve in addition to configuring the proxyCallbackUrl attribute in the protocol configuration resource (as mentioned above).

Add the following <Valve> element to server.xml inside of the <Engine> element (but outside any <Host> or <Context> elements).

<Valve className="org.soulwing.cas.apps.tomcat.ProxyCallbackValve"
  proxyCallbackUri="/casProxyCallback"/>
      

The proxyCallbackUri attribute specifies a URI that the valve will look for in incoming requests to the Tomcat engine. A request for this URI that includes the expected CAS proxy granting ticket parameters (as set by a CAS server) will cause the proxy granting ticket to be registered in the session for the request and thus made available to the application. The value specified for the URI must be the same as that used in constructing the proxyCallbackUrl attribute specified in the protocol configuration resource.

Restart Tomcat

After making these changes, restart Tomcat... it's CAS-ified!

Configuring Applications to Use Container-Managed CAS

Applications request the CAS authentication method by specifying it in web.xml using the following configuration.

<login-config>
  <auth-method>CAS</auth-method>
</login-config>
      

Additionally, applications will need to configure web.xml with <security-role> elements to identify application roles and <security-constraint> elements to constrain access to application resources. Consult the Java Servlet Specification for more information about configuring these elements.