19. CAS Authentication

19.1 Overview

JA-SIG produces an enterprise-wide single sign on system known as CAS. Unlike other initiatives, JA-SIG's Central Authentication Service is open source, widely used, simple to understand, platform independent, and supports proxy capabilities. Spring Security fully supports CAS, and provides an easy migration path from single-application deployments of Spring Security through to multiple-application deployments secured by an enterprise-wide CAS server.

You can learn more about CAS at http://www.ja-sig.org/products/cas/. You will also need to visit this site to download the CAS Server files.

19.2 How CAS Works

Whilst the CAS web site contains documents that detail the architecture of CAS, we present the general overview again here within the context of Spring Security. Spring Security 2.0 supports CAS 3. At the time of writing, the CAS server was at version 3.2.

Somewhere in your enterprise you will need to setup a CAS server. The CAS server is simply a standard WAR file, so there isn't anything difficult about setting up your server. Inside the WAR file you will customise the login and other single sign on pages displayed to users.

When deploying a CAS 3.2 server, you will also need to specify an AuthenticationHandler in the deployerConfigContext.xml included with CAS. The AuthenticationHandler has a simple method that returns a boolean as to whether a given set of Credentials is valid. Your AuthenticationHandler implementation will need to link into some type of backend authentication repository, such as an LDAP server or database. CAS itself includes numerous AuthenticationHandlers out of the box to assist with this. When you download and deploy the server war file, it is set up to successfully authenticate users who enter a password matching their username, which is useful for testing.

Apart from the CAS server itself, the other key players are of course the secure web applications deployed throughout your enterprise. These web applications are known as "services". There are two types of services: standard services and proxy services. A proxy service is able to request resources from other services on behalf of the user. This will be explained more fully later.

19.3 Configuration of CAS Client

The web application side of CAS is made easy due to Spring Security. It is assumed you already know the basics of using Spring Security, so these are not covered again below. We'll assume a namespace based configuration is being used and add in the CAS beans as required.

You will need to add a ServiceProperties bean to your application context. This represents your service:

  <bean id="serviceProperties" 
        class="org.springframework.security.cas.ServiceProperties">
    <property name="service" 
        value="https://localhost:8443/cas-sample/j_spring_cas_security_check"/>
    <property name="sendRenew" value="false"/>
  </bean>
    

The service must equal a URL that will be monitored by the CasAuthenticationFilter. The sendRenew defaults to false, but should be set to true if your application is particularly sensitive. What this parameter does is tell the CAS login service that a single sign on login is unacceptable. Instead, the user will need to re-enter their username and password in order to gain access to the service.

The following beans should be configured to commence the CAS authentication process:

<security:authentication-manager alias="authenticationManager"/>      
      
<bean id="casFilter" 
      class="org.springframework.security.cas.web.CasAuthenticationFilter">
  <security:custom-filter after="CAS_PROCESSING_FILTER"/>
  <property name="authenticationManager" ref="authenticationManager"/>
  <property name="authenticationFailureUrl" value="/casfailed.jsp"/>
  <property name="defaultTargetUrl" value="/"/>
</bean>

<bean id="casEntryPoint" 
    class="org.springframework.security.cas.web.CasAuthenticationEntryPoint">
  <property name="loginUrl" value="https://localhost:9443/cas/login"/>
  <property name="serviceProperties" ref="serviceProperties"/>
</bean>

 
    

The CasAuthenticationEntryPoint should be selected to drive authentication using entry-point-ref.

The CasAuthenticationFilter has very similar properties to the UsernamePasswordAuthenticationFilter (used for form-based logins). Each property is self-explanatory. Note that we've also used the namespace syntax for setting up an alias to the authentication mnager, since the CasAuthenticationFilter needs a reference to it.

For CAS to operate, the ExceptionTranslationFilter must have its authenticationEntryPoint property set to the CasAuthenticationEntryPoint bean.

The CasAuthenticationEntryPoint must refer to the ServiceProperties bean (discussed above), which provides the URL to the enterprise's CAS login server. This is where the user's browser will be redirected.

Next you need to add a CasAuthenticationProvider and its collaborators:

  <bean id="casAuthenticationProvider" 
      class="org.springframework.security.cas.authentication.CasAuthenticationProvider">
    <security:custom-authentication-provider />
    <property name="userDetailsService" ref="userService"/>
    <property name="serviceProperties" ref="serviceProperties" />
    <property name="ticketValidator">
      <bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator">
        <constructor-arg index="0" value="https://localhost:9443/cas" />
        </bean>
    </property>
    <property name="key" value="an_id_for_this_auth_provider_only"/>
  </bean>
  
  <security:user-service id="userService">
    <security:user name="joe" password="joe" authorities="ROLE_USER" />
    ...
  </security:user-service>      
      

The CasAuthenticationProvider uses a UserDetailsService instance to load the authorities for a user, once they have been authentiated by CAS. We've shown a simple in-memory setup here.

The beans are all reasonable self-explanatory if you refer back to the "How CAS Works" section.