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:
-
Application developers can use standard directives in
web.xmlto control access to application resources. This reduces the potential for access control configuration errors, because developers can use the familiar<security-constraint>element and related elements. Moreover, developers don't need a detailed knowledge of CAS filters and associated configuration. - Applications that share a common servlet container share the same CAS configuration. This dramatically improves the manageability of the CAS configuration because it is not duplicated in every application. This also improves security by ensuring that CAS is consistently and correctly applied for all applications that use it.
-
Applications can use the standard security role mechanisms
that are already available via the container-managed security. No
CAS-specific authorization mechanisms are needed. And with CAS 3.1
SAML responses, it will ultimately be possible to fully utilize the
authentication and authorization mechanisms inherent to CAS using
standard security directives in
web.xml
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).
soulwing-casclient-0.5.jar— this file is located in the extracted client distribution in thedistfolderjdom.jar— this file is located in the extracted client distribution in thevendor/libfolderjakarta-oro-2.0.8.jar— this file is located in the extracted client distribution in thevendor/libfolder
Copy the following JAR file into $CATALINA_HOME/lib
(or $CATALINA_HOME/server/lib of you are running Tomcat 5).
soulwing-casclient-tomcat-ext-0.5.jar— this file is located in the extracted client distribution in thedistfolder
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.