Article Figure 1 Figure 2 Figure 3 Listing 1
Listing 2 oct2006.tar

YALE CAS and Variants of a Single Sign-On Solution

Alan M Berg

This article describes YALE CAS, an open source, Web-based central authentication service [3,9]. In this article, I'll provide an overview of this single sign-on (SSO) solution along with the basics of local implementation. I'll also describe how to install the authentication service, modify CAS to your favorite look and feel, and show how to adapt JSP or servlet-based applications to work seamlessly together. I will, however, exclude detailed explanation of potentially complex interactions that are required by a Web browser and the Web application to generate the necessary feeling of uniformity of interaction.

The uniformity of interaction is the main advantage of SSO solutions and is highly demanded. End users in general gain productivity when they can log in once and interact with all their services. SSO has evolved into a requirement in the portal era as more and more condensed information and thus services flow into one personalized main page. It suffices to say here that the hidden interactions involve URL rewriting, redirection, cookies, and sometimes the target application acting as a proxy for a browser. If you are interested in the collaborations, I recommend following the link [6] in the Resources section.

Background

Yale University supplies the majority of developers for the YALE CAS project. In December 2004, JASIG took over responsibility, and I was first introduced as a developer to the technology [4] when my team needed to instance a portal for students. The portal contains channels that collect information from various systems such as mail, RSS feeds, learning systems, an exam result password-protected Web site, and the library systems. With such a diffuse infrastructure, we can't get away with just password authentication. SSO enables users to log on once, generate a session that is valid across all relevant applications, and then interact seamlessly without typing their passwords again. Once users have found what they are looking for via a portal channel, they may then click on a link and go directly to the underlying application.

We choose Yale CAS for SSO due to a number of motivating factors. The server is easy install, is based on servlet technology, and is contained in one war file. The server is thus easy to maintain.

The portal system we chose was uPortal [7]. UPortal is delivered with native integration with CAS. Client support and the CAS adaptation of Java-based applications are doable. A well-conceived CAS client library does all the hard lifting work for developers for the straightforward adaptation of most common Web-based Java applications. Horde (a mail server), uPortal, BlueSocket, TikiWiki, Mule, Liferay, Moodle, and various other popular applications support CAS natively. The client libraries for developer adaptation of applications include PHP, MOD_CAS for Apache, .Net, Java, and JSP.

A simplification of the installation and customization of Yale CAS is achievable via ESUP [2], which is an open source project from the ESUP-Portail consortium, a French consortium of universities. The ESUP project has taken a specific, slightly aged version of the CAS server and enhanced the deployment process via an Ant script. ESUP has modified the server itself to allow the CAS server to check the user's passwords against a greater range of data sources, including password files, LDAP, databases, and experimentally Active Directory. The project includes an Ant script, which concentrates customizations, language, and look-and-feel settings into two main property files. Modification and maintenance are thus simplified and dumbed down to an appropriate maintenance level.

The main disadvantage of deploying the ESUP project is that the modified YALE CAS server is older and perhaps (though not once seen) a bit more buggy. The main version number is 2, and the newest version you can download sits currently at the 3 level. The newer versions of CAS have a number of protocol enhancements, but none that should affect daily SSO work to any noticeable degree.

The main disadvantages of CAS in general are three-fold:

1. The first disadvantage is that there is no fallback server. If the server fails, then you need to bring up a second cloned instance quickly. In the world of virtualization, through tools such as User Mode Linux [8] or VMWare player and with a monitored infrastructure, this limitation is not too significant.

2. The second and greater limitation is that CAS is purely Web based. Working on redirects and cookies assumes that the user is interacting via a Web browser. Any other approach needs to be forced into functioning.

3. The third limitation is rather more subtle. SSO is not the same as single sign-out. You may have logged out of the CAS server, but that does not mean that you have destroyed the sessions for each application. Without realizing it, you may still be able to view your email or visit a protected page. For each new application, you may need to find an ad hoc logout mechanism. This type of issue becomes much more important when your user base may be interacting from an Internet café, where the next user may use the back button to get their dirty little fingers on the still open sessions.

The clusteredCAS [1] project resides on Sourceforge.net. I note that although the download section is currently empty, later this may not be so. For redundancy purposes, the project is worth tracking.

Installing the CAS server

In this section, I will discuss two subjects. The first is customization of the look and feel of the CAS server. The second subject is how to define the authentication backend, the storage where the user name and passwords reside. By default, and for testing purposes only, the ESUP CAS server will allow the user to succeed if the username and password are the same. We will change the rather unhelpful check to reading from a plain-text password file and mention how easy it is to connect via a simple bind to an LDAP server.

To begin, download the ESUP version 2.07 quick install distribution [2]. Throughout the rest of this document, I shall assume that the ESUP root is /usr/local/esup. Please replace this value with the one for your instance. The distribution relies heavily on the Ant tool; if you do not already have this tool installed, please do so. Under Unix, running ant in the ESUP root directory will produce the following error message:

BUILD FAILED 
/usr/local/esup/build.xml:59: /usr/local/java5/bin/keytool.exe \
  not found, cannot generate client certificate. 
            
The core reason for this message is that the Ant build file has obviously been written under a Windows environment. Under this environment, the Java keytool is called keytool.exe; whereas under Unix, it is named keytool without the extension. Modify the following line in the build.xml file to remove the unnecessary issue.

From:

<property name="jakarta-tomcat.keytool.path" \
  value="${env.JAVA_HOME}/bin/keytool.exe"/>
To:

<property name="jakarta-tomcat.keytool.path" \
  value="${env.JAVA_HOME}/bin/keytool"/>
Running from ESUP root, ant should now result in a successful build.

Next, run ant tomcat-start & and use your Web browser to view the URL http://localhost:8443/cas, which should return a Web page similar to Figure 1. Okay, the server language is French, a beautiful language, but as most of the readers of this magazine are native English speakers let us convert the language. Stop the tomcat server via ant tomcat-stop.

Within /usr/local/esup/properties/build.properties add the following line:

cas-server.lang=en 
Run ant followed by ant tomcat-start. Ah, life is good we have an Anglicized server (see Figure 2).

The next step is to modify the server for our own look and feel. ESUP has thoughtfully provided us with a simple solution. Modifying the property file /usr/local/esup/custom/cas-server-render/esup-portail.org.properties and running ant again builds the new look and feel. Listing 1 is one such example.

Notice that you can change the logo via the properties cas-server.html.logo.url, cas-server.html.logo.width, and cas-server.html.logo.height. You should place the logo picture in /usr/local/esup/custom/cas-server-render/esup-portail.org/webdirectory. Running ant again creates are newly templated server (Figure 3).

Plugging into a password backend is just as simple. Within properties/build.properties comment out the line:

esup-casgeneric.auth=test 
Then add the lines:

esup-casgeneric.auth=file 
esup-casgeneric.auth.file.filename=/usr/local/esup/secrets/passwd 
esup-casgeneric.auth.file.separator=: 
esup-casgeneric.auth.file.encryption=des 
Note that the backend is an esup readonly file /usr/local/esup/secrets/passwd. One line of the file looks like:

alan:xxxxxxx:1000:1000:Alan M Berg,,,:/home/alan:/bin/bash 
where xxxxxxxx is the des encrypted password.

As a root user, you can check the shadow passwords, cut, and paste. Another method that does not involve systems administration privileges is to generate your own crypt password with Perl via the following one-liner:

print crypt("password","salt"); 
Assuming the password is smile%smile, and the salt is a3, then the result generated is a3qmD.Voz82hU. Note that the salt begins the encrypted password and that you cannot use "." as a line separator.

The other supported encryption types are md5 and pammd5. You may even use a plain-text password (plain) but that choice is absolutely a security problem waiting to happen.

Binding to LDAP is just as simple and straightforward. Comment out the lines above and then add:

esup-casgeneric.auth=ldap 
esup-casgeneric.auth.ldap.filter=uid=%u,ou=test_ou,dc=xxxxxx,dc=org 
esup-casgeneric.auth.ldap.url=ldap://ldap.xxxxxx org 
    
The filter and ldap.url should of course point to your servers. The token %u is the login name that the user presents at the login page.

Looking back on this section, thanks to the efforts of ESUP, personalization of look and feel and attachment to different password stores is rather trivial.

Enabling JSP Applications

Now that we have set up the authentication server, it is time to turn to the client side. We are now going to cas-ify a single JSP page. We will achieve this by adding a filter to the root Web application in the ESUP package. The process is the same for any servlet-based application. Filtering follows the chain of responsibility pattern. In other words, before a request reaches the Web application, the filter intercepts it. The same is true when the Web application sends a response. The chain of responsibility is just saying that you can set a number of filters in a row. Once one filter has done its work, it passes the request or response to the next -- if there is a next, that is.

SSO security depends on a properly functioning SSL/TLS infrastructure. The main lesson to learn from this recipe is that the placement of the public certificate of the Tomcat server in its own local keystore is vital for the correct running of SSO. The keystore is a store for certificates that is phrase protected and has a structure that is programmatically understandable from within a Java application.

The Yale development team has made our life easy here. Begin by downloading the client binary. In this example, I used cas-client-java-2.1.1. Within the archive under the dist directory, you will find casclient.jar. Place the jar file in the /usr/local/esup/jakarta-tomcat-5.0.28/webapps/ROOT/WEB-INF-INF/lib directory.

Now the Web application has access to the casclient library. Next, create ../ROOT/test.jsp page with the following contents:

<html>
<body>
<h2><%=  session.getAttribute(edu.yale.its.tp.cas.client. \
     filter.CASFilter.CAS_FILTER_USER) %></h2>
You are now in the main application. 
</body>
</html>
Note that the session attribute edu.yale.its.tp.cas.client.filter.CASFilter.CAS_FILTER_USER will be set by the CAS filter if the user has successfully logged in.

This leaves two final steps. The first is to activate the filter. The second is to allow the casclient.jar libraries to trust the server certificate of the Tomcat server. Let's start with step one and allow SSO to fail. The motivation for doing this is to see typical error messages and understand the obtuse nature of the messages.

To add the filter, after the description, see Listing 2 and add:

<filter>
    <filter-name>CAS Filter</filter-name>    
    <filter-class>edu.yale.its.tp.cas.client.filter. \  
      CASFilter</filter-class>
    <init-param>
      <param-name>edu.yale.its.tp.cas.client.filter. \     
        loginUrl</param-name>
      <param-value>https://localhost:8443/cas/login</param-value>
    </init-param> 


    <init-param>
      <param-name>edu.yale.its.tp.cas.client.filter. \     
        validateUrl</param-name>
      <param-value>https://localhost:8443/cas/ \       
        serviceValidate</param-value>
    </init-param> 


    <init-param>
      <param-name>edu.yale.its.tp.cas.client.filter. \     
        serverName</param-name>
      <param-value>localhost:8443</param-value>
    </init-param> 


  </filter> 


  <filter-mapping>
    <filter-name>CAS Filter</filter-name>
    <url-pattern>/test.jsp</url-pattern>
  </filter-mapping>
Note that there are only four values to modify. The first is the location of the login page -- obviously for the user to log in. The second is the location of the service that validates the ticket created at logon. The third address is the host of the service. For example, if your application were running at my.company port 9999 then the service value would be my.company:9999. Yes, I realize it is easy to place an http:// before the rest of the value. However, if you do, your configuration will fail. The fourth value is the filter mapping; this tells the filter exactly which requests to intercept, in this case only /test.jsp.

Restarting, or starting, your server now and browsing to https://localhost:8443/test.jsp should redirect you to the CAS login page. After correctly typing your username and password, the following generate 500 error occurs:

Unable to validate ProxyTicketValidator 
In a very indirect way, this is stating that your serviceValidate url has caused a failure. The reason for this failure is purely a lack of trust of the server certificate by the application filter. Such error messages are a sign that the developers are not always in contact with systems administrators. I am a great believer in adding hints to the more common errors that occur to provide sys admins with an intuitive basis for the start of the debugging process.

To enable the necessary trust requires a certificate in the certificate store of the Java distribution that the application is running in and not only in the store that the Tomcat server looks in. Yet another not so obvious requirement. The distribution in most cases is defined by the $JAVA_HOME environment variable.

To gain a clearer picture of what is happening, we shall list the details of the originally generated Keystore. Assuming you have unpacked and moved the ESUP archive to /usr/local/esup and that the Java bin directory is in your path, then the following command will work, under Unix:

keytool -list -v -keystore /usr/local/esup/jakarta-tomcat-5.0.28/ \ 
    conf/server.ks 
Enter keystore password:  secret 
The results given will be similar to:

Keystore type: jks 
Keystore provider: SUN 
Your keystore contains one entry:

Alias name: jakarta-tomcat 
Creation date: Jul 2, 2006 
Entry type: keyEntry 
Certificate chain length: 1 
Certificate[1]: 
Owner: CN=localhost, OU=v, O=Esup-Portail.Org, C=FR 
Issuer: CN=localhost, OU=v, O=Esup-Portail.Org, C=FR 
Serial number: 44a838aa 
Valid from: Sun Jul 02 16:20:42 CDT 2006 until: Sat Sep 30 \
            16:20:42 CDT 2006 
Certificate fingerprints: 
         MD5:  F7:7B:B0:7C:B7:A5:42:0C:BE:FE:8F:88:A1:B6:B2:3D 
         SHA1: B3:04:AA:47:0E:98:C2:56:9C:03:C9:BC:A6:B7:A6: \           
               FA:67:E6:EE:53 
Note that the alias name is jakarta-tomcat and, because the owner and issuer CA are the same, the certificate is self-signed. Self-signing is a common practice for Intranet environments but has the disadvantage of needing the importing of certificates into the Java keystore of the application's Java runtime. Java distributions come with a keystore with certificates from companies such as Verisign and Globalsign contained therein. If you obtain a certificate from one of these CA's and install it, then you need not worry about how to get your server certificates into the client's Java keystore, a possible headache for widespread deployments.

Another significant point is that the cn's first value is localhost. The server certificate is only valid if the cn has the same value as the server's fully qualified hostname.

Again, we use keytool to export the certificate to cert.txt:

keytool -export -v -rfc -alias jakarta-tomcat -file cert.txt \
  -keystore "/usr/local/esup/jakarta-tomcat-5.0.28/conf/server.ks"
The cert.txt file now exists.

Assuming the environment variable JAVA_HOME is set, importing the keystore under a bash is straightforward:

sudo ${JAVA_HOME}/jre/bin/keytool -import -keystore  \
  "/usr/local/java5/jre/lib/security/cacerts" \ 
  -alias jakarta-tomcat -file cert.txt 
For importing, you may set the alias to any reasonable value you wish. However, that said, you should try to make the alias name at least understandable for your colleagues.

You should now have a working application. Test this assumption by browsing to https://localhost:8443/test.jsp.

An improved version of the cas client exists in yet another open source project, called Extended CAS [5]. The extended code allows for dummy trust, thereby easing the effort required to deploy self-signed certificates, and JNDI configuration for ease of datasource configuration.

A Word of Warning

ESUP has squarely focused the quick install distribution on the developer. Every time you run ant, a deployment of the Tomcat server occurs. During the process, regeneration of a new server certificate occurs. If you seek greater stability, back up the server.ks file and copy over the newer version for every deployment. Modifying the Ant script is trivial, thus avoiding the need for any new certificates in the Java distributions keystore.

In this section, we created our first SSO-enabled JSP application. Although we made a primitive start, we explored the main installation issues of certificate management to the relevant detail.

Future Potential

Once you have installed SSO, you may naturally be wondering which applications have native support. As usual, the answer is not as many as one would like. The participating educational community has geared the series of packages towards their own needs. The list reflects this: horde for email, moodle and Sakai for learning systems, uPortal for a customizable portal. All products are excellent and happily received by a wide, but specific community. Sadly, the range is perhaps not enough to reach a critical mass in the overall market place. I think that the quality of the product deserves a larger user base, hence my motivation for writing this article. Luckily, many Web-based applications are relatively easy to convert to this new way of doing business.

Unix is an old brave workhorse with well-known methods of doing business. Pluggable Authentication Methods (PAM) often handles security. I therefore welcome the existence of PAM CAS. I have not configured an enterprise instance of this module but have used PAM LDAP in conjunction with Web FTP servers, and I find this general approach direct and straightforward.

For Linux fans with LAMP servers, the PHP client looks quite focused on the session-maintaining tasks. Additionally, for the good old Java application, we have covered filters. While wearing my daily working hat as a lead developer, I have helped integrate an Ex libris-based library system via Apache with MOD_CAS sitting on top of MOD_PERL. Therefore, I hope you get the feeling that even if your favorite application is not cas-ified, this may still be a viable path to travel. For example, there are recipes in the wild for cas-ifying Outlook Web access and a number of Sun One and Oracle products.

Finally

In this article, I have shown how to deploy a customized version of a Yale CAS server based on the ESUP quick install distribution. Further, I have shown how to customize Web-based Java applications. I hope I have left you with the feeling that it does not require a rocket scientist out of an old black-and-white, sci-fi, horror film to deploy an open source SSO environment and that this is within your enterprise's grasp. If you wish to challenge yourself, send me an email with a screen grab of your own modified server. I promise to print it and stick that beauty on my wall.

Acknowledgements

I acknowledge the hard work and dedication of the core development team of YALE CAS [10].

Resources

1. Clustering CAS -- http://sourceforge.net/projects/ccas

2. ESUP -- http://esup-casgeneric.sourceforge.net/

3. JA-SIG -- http://www.ja-sig.org/

4. My interaction with Yale CAS -- http://www.mc.manchester.ac.uk/eunis2005/medialibrary/papers/paper_104.pdf

5. Extended Casclient -- http://www.discursive.com/projects/cas-extend/tomcat_jndi.html

6. Proxy CAS Walkthrough -- http://www.jasig.org/wiki/display/CAS/Proxy+CAS+Walkthrough

7. uPortal -- http://www.uportal.org/

8. User Mode Linux -- http://user-mode-linux.sourceforge.net/

9. Yale client (casclient) -- http://www.ja-sig.org/products/cas/downloads/index.html

10. Yale development team -- http://www.ja-sig.org/products/cas/about/index.html

Alan M Berg has been a lead developer at the Central Computer Services at the University of Amsterdam for the past seven years. He likes to get his hands dirty with the building and gluing of systems. In previous incarnations he was a technical writer, an Internet/Linux course writer, and before that a science teacher. He remains agile by playing computer games with his kids (Nelson and Lawrence), who sadly consistently beat him.