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.
|