Introduction
This post will cover the installation of Tomcat 7 and Central Authentication Service (CAS) 3.52. Although the process is pretty straight forward, there are a lot of bits of information scattered all around for setting these two things up and I figured bringing those to a single place would be useful for others.
Beyond installing CAS and Tomcat 7, this post will cover:
- Configuring and Hardening (SSL wise) Tomcat 7
The next part will cover:
- Authenticating against LDAP
- Using the JPA Ticket Registry with Postgresql
Installing Tomcat 7 and Needed Libraries
To setup Tomcat 7, its needed libraries, and the libraries you will need for CAS, run the following commands:
sudo apt-get update sudo apt-get install tomcat7 maven2 default-jdk libctnative-1 libssl-dev
The above commands will install
- maven2 → This will be used for CAS. We will be using the WAR overlay method.
- Tomcat 7
- default-jdk (openjdk-6) → This is needed by CAS
- libctnative-1 → Installs libraries that will be needed by Apache Portable Runtime
- libssl-dev → Installs libraries for SSL
After the installation there will be several new environment variables that you may want to set (though Tomcat figures them out automatically).
- CATALINA_HOME = /usr/share/tomcat7
- CATALINA_BASE = /var/lib/tomcat7 (we’ll be doing most of our configuring here)
- JAVA_HOME = /usr/lib/jvm/java-6-openjdk-amd64
Note: For the rest of this post and in the other parts of this series, I will use the above variable names.
My JAVA_HOME Path is Different! What Do I Do?
It is possible that your JAVA_HOME path may be different. If you are not running a 64-bit system, the path will probably be /usr/lib/jvm/java-6-openjdk.
If this is not your path you can use the find command to find the cacerts file, which should help you get the path (minus the /jre/lib/security/ part) like so:
find / -name "cacerts"
Or you can check your java alternatives using the update-java-alternatives command, like so:
update-java-alternatives -l
Note: If your java path does not fit /usr/lib/jvm/java-6-openjdk-* or /usr/lib/jvm/java-7-openjdk-*, you will need to set the environment variable JAVA_HOME because Tomcat will not find it.
Configuring Tomcat 7 for SSL
To setup Tomcat to use SSL you will need to either have a self signed certificate or a signed certificate from a Certificate Authority like DigiCert or Verisign. If you want to create a self signed cert, check out this tutorial Creating a Self Signed Cert. If you already have a signed certificate then you can move on to the next part.
When configuring Tomcat to use SSL, you have two options for how you want to do it. The first way is to import the certificate into the cacerts file and use the keystoreFile and keystorePass attributes in the Connector declaration in the server.xml file for Tomcat. If you want to use this approach MuleSoft has a good tutorial on how to do it here (This tutorial also includes the second method close to the bottom).
The other way (the one I’m doing) is to use the attributes SSLCertificateFile and SSLCertificateKeyFile to reference the files directly. Whichever way you choose to go, be sure to define the ciphers attribute like I have done in the code snippet below. This is needed because by default Tomcat will use whatever ciphers the Java library has to offer and some of these are very weak.
Once you have your SSL certificate and key file ready and stored in some place like /etc/ssl/certs you can move on to configuring Tomcat. For this part
- Edit $CATALINA_BASE/conf/server.xmlUn-comment the following section:
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" />
And make it look like
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" SSLCertificateFile="/some/path/cert.crt" SSLCertificateKeyFile="/some/path/cert.key" ciphers="TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA" />
Note: If you are sure that you will not have any Windows XP clients, you can remove the 3DES ciphers.
- Save the file
- Edit /etc/default/tomcat7 and add “-Dhttps.protocols=TLSv1” to the JAVA_OPTS line. Mine looks like this:
JAVA_OPTS="-Djava.awt.headless=true -Xms512M -Xmx1024M -XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=512m -XX:+CMSIncrementalMode -Dhttps.protocols=TLSv1"
Note: You need to make this change because java will allow different ciphers than your restricted CAS instance, which will cause SSL issues.
Note 2: The other parameters in the above line let the JVM allocate more memory for your CAS instance and have it clean said memory more often to make more efficient use of it. It would probably be a good idea to use these flags as well, just adjusted to your servers capability. - Save the file
- Restart tomcat
/etc/init.d/tomcat7 restart
Note: you may also want to watch the catalina log file in another console using
tail -f $CATALINA_BASE/catalina.out
- Open a browser and navigate to https://your_server:8443. If everything worked, you should see the “It Works” screen
Wait! I Want to Use Port 80 and 443, not 8080 and 8443
If you want to use the standard HTTP and SSL ports of 80 and 443, make sure of the following first
- No other application is binding to port 80 or 443
- You are not using IP v6 (this is a restriction of AuthBind)
- Edit $CATALINA_BASE/conf/server.xml and change the following section:
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" URIEncoding="UTF-8" server="Apache" redirectPort="8443" />
And make it look like
<Connector port="80" protocol="HTTP/1.1" connectionTimeout="20000" URIEncoding="UTF-8" server="Apache" redirectPort="443" />
- Edit /etc/default/tomcat7 and make the AUTHBIND line look like:
AUTHBIND=yes
- Restart tomcat
HTTPS Everywhere
Once you have HTTPS/SSL working from the previous part, let’s configure Tomcat so every site goes through HTTPS.
- Edit $CATALINA_BASE/conf/web.xml
- Add the following code snippet to the end of the file, just above the </web-app> line at the end of the file
<security-constraint> <web-resource-collection> <web-resource-name>Protected Context</web-resource-name> <url-pattern>/*</url-pattern> </web-resource-collection> <!-- auth-constraint goes here if you require authentication --> <user-data-constraint> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> </security-constraint>
- Save the file and restart Tomcat7
- Open a web browser and navigate to http://your_server:8080. You should be redirected to https://your_server:8443.
Setting Up The CAS WAR Overlay
One of the easiest and recommend ways to setup CAS is to use the Maven WAR Overlay method. To do this, do the following: (or you can follow the guide from Jasig)
- Create the workspace directory, in the future referred to as $project_home
mkdir /opt/work/cas-local
- Create a file called pom.xml in the created folder, add add the following to it:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd "> <modelVersion>4.0.0</modelVersion> <groupId>edu.university.cas</groupId> <artifactId>local-cas</artifactId> <packaging>war</packaging> <version>1.0-SNAPSHOT</version> <build> <plugins> <plugin> <artifactId>maven-war-plugin</artifactId> <configuration> <warName>cas</warName> </configuration> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>org.jasig.cas</groupId> <artifactId>cas-server-webapp</artifactId> <version>${cas.version}</version> <type>war</type> <scope>runtime</scope> </dependency> </dependencies> <properties> <cas.version>3.5.2</cas.version> </properties> <repositories> <repository> <id>ja-sig</id> <url>http://oss.sonatype.org/content/repositories/releases/ </url> </repository> </repositories> </project>
- Change the groupId tag to have the url for your place of business.
- Next we will add the parts that actually make our CAS package building useful. Our customizations.Create the directory $project_home/src/main/webapp/WEB-INF
- Create a file called deployerConfigContext.xml in the new folder, and populate it with this contents.
- (Optional) The default service context for CAS will work just fine out of the box, but only restrict traffic to IMAP(S) or HTTP(S)If you would like to be a little more restrictive to say, just your domain, you will want to change the following line in deployerConfigContext.xml
<property name="serviceId" value="^(https?|imap?)://.*" />
To something more restrictive, like:
<property name="serviceId" value="^(https?|imaps?)://([A-za-z0-9_-]+\.)*(your_domain\.com)(:\d{1,5})?/.*" />
This will restrict service to HTTP(S) or IMAP(S) from your domain only, with a possible port number in the url.
Note: the “(:\d{1,5})?” part is not needed if you use port 80 and 443 for CAS. - Create a file called cas.properties in the same folder, and populate it with this contents.
- Alter the following line:
server.name=https://localhost:8080
and change it to
server.name=https://<your domain>:<port_number>
e.x. server.name=http://cas.example.com:8443
- Alter this line
host.name=cas01.example.org
and change it to
host.name=<your cas servers FQDN>
e.x. host.name=cas.example.com
- Save the cas.properties file.
- (Optional) If you want to setup throttling of repeat authentication attemps
- Create the file $project_home/src/main/webapp/WEB-INF/cas-servlet.xml and populate it with this contents.
- Change the following bean:
<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping" p:flowRegistry-ref="flowRegistry" p:order="2"> <property name="interceptors"> <ref local="localeChangeInterceptor"/> </property> </bean>
to
<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping" p:flowRegistry-ref="flowRegistry" p:order="2"> <property name="interceptors"> <list> <ref local="localeChangeInterceptor"/> <ref bean="throttleInterceptor"/> </list> </property> </bean>
- Create the file $project_home/src/main/webapp/WEB-INF/spring-configuration/throttleInterceptorTrigger.xml and put the following in it:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"> <bean id="throttleInterceptor" class="org.jasig.cas.web.support.InMemoryThrottledSubmissionByIpAddressAndUsernameHandlerInterceptorAdapter" p:failureRangeInSeconds="120" p:failureThreshold="100"/> <bean id="throttleInterceptorJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean" p:targetObject-ref="throttleInterceptor" p:targetMethod="decrementCounts" /> <bean id="periodicThrottleCleanerTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean" p:jobDetail-ref="throttleInterceptorJobDetail" p:startDelay="0" p:repeatInterval="1000" /> </beans>
- (Optional) If you want to setup a ticket expiration policy for your Ticket Granting Tickets
- Create the file $project_home/src/main/webapp/WEB-INF/spring-configuration/ticketExpirationPolicies.xml
- Populate it with this contents.
- If you want to change the default ticket expiration settings you will want to alter the attributes p:maxTimeToLiveInSeconds and p:timeToKillInSeconds
- Change directory to $project_home
- Run the following command to build you cas package (this cleans the workspace and builds the package).
mvn clean package
- Create a soft link for freshly built cas.war file for Tomcat 7
ln -s target/cas.war /var/lib/tomcat7/webapps/cas.war
The new package should be automatically deployed by Tomcat
NOTE: When rebuilding the cas.war file because you’ve made changes to the configuration, you will want to issue the following commands:
service tomcat7 stop
service tomcat7 start
This is because Tomcat will re-deploy the cas.war and throw a bunch of errors in the log and act wonky, until you stop and restart Tomcat.
- Open a browser and navigate to “https://<your_cas_server>:8443/cas” (minus the port number if you are using port 80 and 443). You should see the CAS login screen.
At this point CAS should be up and hopefully there aren’t any errors being spat in your /var/log/tomcat7/catalina.out log. But, CAS isn’t all the useful yet. It just gives you a nice login box to no where.
In the next part I’ll discuss several things to make CAS more useful:
- Setting up PostgreSQL ticket management
- Configuring CAS to use LDAP
- Configuring CAS to use pooling for LDAP and PostgreSQL
Thank you for the article. I just wanted to ask something. I am doing my senior design project and my topic is to configure mail server with Koha(open source integrated library system) that will run on my university. So far, I installed CAS server(not maven) and I managed to make it work but with https and on 8181 port because Koha is running on 8080, and I don’t know what to do next. Should I use this guide and install it again, delete the previous version or something else? I would be thankful if you could give me some guidelines.
Kind regards
This article might help. If you are able to authenticate against your CAS sever instance at https://yoursever.com:8181/cas/login then you probably do not need to re-install CAS. Though the mavin approach does make upgrading pretty easy. Also, you will probably want to upgrade to version 3.5.3, since it addresses an LDAP vulnerability (assuming your authenticating against LDAP).
One thing I have noticed, where I work is that some students are unable to use cas when SSL is on a higher port like 8443, from home. You may want to turn AUTHBIND on for tomcat so https can run over 443.
I haven’t used or worked with Kohna before, but if you can tell it to use an SSO solution for authentication, you should be able to point it at your login URL and it should be pretty straight forward from there. Just doing a quick look on google, it does look like Khona supports the default CAS authentication setup along with proxy tickets.
Hopefully that helps a bit.
Hello! I am new to cas, at the moment I do my degree thesis based on this and I need help urgently! Well, I already have Cas3.5.2 in tomcat7 (SO linux mint), a directory structure with phpLDAPadmin, an application in php and the last thing I did was install phpCAS console and the version that is in repositories is 1.3.2 ( Does not have the example_simple.php). I have many doubts as to which files to include in the app are all those that brought the phpCAS installation? What files should I modify and what is the exact modification ?. I also downloaded php-cas1.3.4.tgz from https://developer.jasig.org/cas-clients/php/current/ (and this one if you brought example_simple.php) I am now confused, ie I do not know exactly which are the Files that must be included in the application to be protected and also in which part of the application are stored these files. I need help, I need it to work as soon as possible.
Thank you!
I apologize for my English, use a translator!
Hi Beatriz,
For my setup I actually have phpCAS running from a different server than the CAS one. It’s a simple Apache server with the phpCAS tar.gz extracted to /var/www/casTest
In the later versions they seem to have opted to bury the example_simple.php file. You can find it under the folder docs/examples. To make my life easier and easier for my co-workers I made a custom index.php file to sit at the root of /var/www/casTest that loads the example_simple.php file. The code is pretty simple php
header(“Location: https:///casTest/phpCAS/docs/examples/example_simple.php“);
As for what to secure. For phpCAS, nothing really. Unless your cas server address is sensitive, but I doubt it. Other than that, it’s does have any sensitive configuration information in it or its sub-directories.
Hopefully this will get you pointed in the right direction.
hi… i am new to the cas server..can you help me to change the default authentication the cas server
Sorry for the late reply. Which version of CAS are you using. In 4.x and earlier, you will need to edit the beans related to authentication and add the necessary beans to tell cas how to work with the authentication that you want to use.
Thank you for the article. I had already installed CAS 4.0.0 on my linux machine and I want to update it with 5.1.3. Will these steps will work for the same also or not. I am using tomcat 7.
Thanks,
These steps should mostly work; however, deployerConfigContext.xml doesn’t exist anymore in CAS 5.x, the cas.properties file handles pretty much everything and for the things it doesn’t handle, you just tell it where to look
For example, where your JSON service definitions are
### — Service Rregistry — ###
cas.serviceRegistry.json.location=file:///etc/cas/services
Or your logging setup
### — Logging (Log4j2) — ###
logging.config=file:///etc/cas/config/log4j2.xml
log4j.refresh.interval=60000
For things like ldap authentication you fill out the cas.authn.ldap[0] properties to tell CAS how to authenticate and then the cas.authn.attributeRepository.ldap[0] properties to tell cas how to resolve attributes.
If you are authenticating against LDAP/AD, this thread will probably be of use https://groups.google.com/a/apereo.org/forum/?utm_medium=email&utm_source=footer#!msg/cas-user/RKZ8DCDkwXc/hRAvx2feAgAJ