Wednesday, 22 May 2013

Configure CAS Server and Client in Java

Central Authentication Service also known as CAS provides single sign on (SSO)functionality to various applications.

CAS application has two parts , first part is in the form of web application which can run on any java EE compliant web server (like tomcat) and act as a server which provides authentication. Second part is in the form of client , which you need to add with your application. In this post , we will try to configure CAS in tomcat , and create a java web application which will use CAS authentication service.

First we will configure CAS server to run as WAR application on tomcat. For this, first download CAS from Here.

Extract the zip file and there you find different implementation of CAS server.Just Copy the cas-server-webapp folder and build a cas.war from pom.xml located in it.By default CAS Server web app will work on only for HTTPS connections , if you want to enable Http connection for CAS , then go to the web app folder and under /WEB-INF/spring-configuration/ticketGrantingTicketCookieGenerator.xml and change the p:cookieSecure="true" to p:cookieSecure="false" , then again create the cas.war from maven.

Now if you want to use it on https connections as well , prepare the tomcat to accept https connections which is explained in this Post.

Now deploy this war on server and you can access cas server at https://localhost:8443/cas or http://localhost:8080/cas.

Now we will create a simple java web application to use SSO of CAS. First download CAS client for java from this link. I have used cas-client-3.1.1-release.Run the pom.xml and add the jars created in the java web application . You should have following jars in your web app :

cas-client-core-3.1.1.jar (from cas-client 3.1.1)
commons-logging-1.1.jar (from cas-client 3.1.1)
xercesImpl.jar (from Apache Xerces release 2.9.1)
xml-apis.jar (from Apache Xerces release 2.9.1)
xmlsec-1.3.0.jar (from cas-client 3.1.1)

Now add these filter configurations to your web.xml.
<filter>
  <filter-name>CAS Authentication Filter</filter-name>
  <filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
  <init-param>
   <param-name>casServerLoginUrl</param-name>
   <param-value>http://localhost:8080/cas/login</param-value>
  </init-param>
  <init-param>
   <param-name>serverName</param-name>
   <param-value>http://localhost:8080</param-value>
  </init-param>
  <init-param>
   <param-name>renew</param-name>
   <param-value>false</param-value>
  </init-param>
  <init-param>
   <param-name>gateway</param-name>
   <param-value>false</param-value>
  </init-param>
 </filter>
 
 <filter>
  <filter-name>CAS Validation Filter</filter-name>
  <filter-class>org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class>
  <init-param>
   <param-name>casServerUrlPrefix</param-name>
   <param-value>http://localhost:8080/cas/</param-value>
  </init-param>
  <init-param>
   <param-name>serverName</param-name>
   <param-value>http://localhost:8080</param-value>
  </init-param>
  <init-param>
   <param-name>proxyCallbackUrl</param-name>
   <param-value>http://localhost:8080/webappcas2/proxyCallback</param-value>
  </init-param>
  <init-param>
   <param-name>proxyReceptorUrl</param-name>
   <param-value>/webappcas2/proxyCallback</param-value>
  </init-param>
 </filter>
 
 <filter>
  <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
  <filter-class>org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>
 </filter>
 
 <filter>
  <filter-name>CAS Assertion Thread Local Filter</filter-name>
  <filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter</filter-class>
 </filter>

 <!-- ************************* -->

<!-- Sign out not yet implemented -->
<!-- 
 <filter-mapping>
  <filter-name>CAS Single Sign Out Filter</filter-name>
  <url-pattern>/*</url-pattern>
 </filter-mapping>
-->

 <filter-mapping>
  <filter-name>CAS Authentication Filter</filter-name>
  <url-pattern>/*</url-pattern>
 </filter-mapping>

 <filter-mapping>
  <filter-name>CAS Validation Filter</filter-name>
  <url-pattern>/*</url-pattern>
 </filter-mapping>
  
 <filter-mapping>
  <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
  <url-pattern>/*</url-pattern>
 </filter-mapping>
 
 <filter-mapping>
  <filter-name>CAS Assertion Thread Local Filter</filter-name>
  <url-pattern>/*</url-pattern>
 </filter-mapping>
 
 <filter-mapping>
  <filter-name>CAS Validation Filter</filter-name>
  <url-pattern>/proxyCallback</url-pattern> 
 </filter-mapping>
That's it . Now if you try to access your web app , you will be redirected to cas login page to login first.Right now CAS web app is configured to allow access with same username and password.You can configure cas-web-app as you wish. Upon successful authentication you will be served the web page from web app .

you can get NullPointerException like this :
java.lang.NullPointerException
    org.jasig.cas.client.util.HttpServletRequestWrapperFilter$CasHttpServletRequestWrapper.getRemoteUser(HttpServletRequestWrapperFilter.java:80)
    org.apache.jsp.include_005fheader_jsp._jspService(include_005fheader_jsp.java:57)
    org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
    org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374)
...

To solve this you can apply patch from this link , or download the patched version from here .

Post Comment and suggestions !!