CAS-ify a Java Application

Instructions and sample code for using the CAS Java client are below. These instructions are meant to give you an idea of how much work it takes to integrate CAS into a web application. Many of the commercial and open source products used in higher education that come with built-in support for CAS, including Drupal, WordPress, Sakai and PeopleSoft, base their support on use of the CAS clients. See the CAS Java Client page for a complete set of integration instructions. This example demonstrates CAS client configuration using the SAML 1.1 protocol.

Note: it is important to use the current version of a given CAS client to ensure the code includes the latest security fixes. The current version of the CAS Java client is 3.5.1.

  • Add code to your application to retrieve the UNI

    import org.jasig.cas.client.authentication.AttributePrincipal;
    
    public class YourServlet extends HttpServiet 
    {
    ...
      public void doPost(HttpServletRequest req, HttpServletResponse res)
            throws IOException, ServletException 
      { 
        ...  
        // The CAS client puts the Principal into the Request:
        AttributePrincipal principal = (AttributePrincipal)req.getUserPrincipal();
        String uni = principal.getName();
        ...etc.
      }
      ...
    }
  • (Optional) Add code to your application to retrieve affiliations

    import org.jasig.cas.client.authentication.AttributePrincipal;
    ...
    public class YourServlet extends HttpServiet 
    {
      public static String STAFF_AFFILIATION = "staff:columbia.edu";
      ...
      public void doPost(HttpServletRequest req, HttpServletResponse res)
            throws IOException, ServletException 
      { 
        ...  
        // Check if the user has a staff affil:
        AttributePrincipal principal = (AttributePrincipal)req.getUserPrincipal();
        Map attributes = (principal==null) 
          ? new HashMap() 
          : principal.getAttributes();
        List affiliations = (List)attributes.get("affiliation");
        boolean isStaff = affiliations.contains(STAFF_AFFILIATION);
         ...etc.
      }
    }
  • Add CAS servlet filters to web.xml, using values for the local CAS server

    Note that depending on the context, "filter" or "servlet filter" may refer to the filter element in web.xml or to the underlying Java class that implements filter behavior. Here it refers to the filter definition that is added to web.xml. You will almost certainly need to define these 3 filters:

    • CAS Authentication Filter
    • CAS Validation Filter
    • CAS HttpServletRequestWrapper Filter

    There are other filters you may also want to declare (see the CAS Client documentation.) In addition, filter-mapping elements need to be added to web.xml to make sure that incoming requests are processed by the correct underlying filters. See the web.xml fragments below, as well as the CAS Client documentation for how to set up filters for the various CAS protocols.

    web.xml

    If the webapp only needs the UNI, use the lightweight AuthenticationFilter and Cas20ProxyReceivingTicketValidationFilter combination as follows:

     <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>https://cas.columbia.edu/cas/login</param-value>
        </init-param>
        <init-param>
          <param-name>serverName</param-name>
          <param-value>https://your-hostname</param-value>  <-- hostname of registered URLs
        </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>https://cas.columbia.edu/cas/</param-value>
        </init-param>
        <init-param>
          <param-name>serverName</param-name>
          <param-value>https://your-hostname</param-value> <-- hostname of registered URLs
        </init-param>
        <init-param>
          <param-name>artifactParameterName</param-name>
          <param-value>ticket</param-value>
        </init-param>
        <init-param>
          <param-name>redirectAfterValidation</param-name>
          <param-value>true</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> 
    
    ;

    If the application needs additional attributes besides the UNI, like affiliations and date of last password change, define SAML11 filters:

     <filter> 
        <filter-name>CAS Authentication Filter</filter-name> 
        <filter-class>org.jasig.cas.client.authentication.Saml11AuthenticationFilter</filter-class> 
         <init-param> 
           <param-name>casServerLoginUrl</param-name> 
           <param-value>https://cas.columbia.edu/cas/login</param-value> 
         </init-param> 
         <init-param> 
           <param-name>serverName</param-name> 
           <param-value>https://your-hostname</param-value>  <-- hostname of registered URLs
         </init-param> 
      </filter> 
    
      <filter>
        <filter-name>CAS Validation Filter</filter-name> 
        <filter-class>org.jasig.cas.client.validation.Saml11TicketValidationFilter</filter-class> 
        <init-param> 
          <param-name>casServerUrlPrefix</param-name> 
          <param-value>https://cas.columbia.edu/cas/</param-value> 
        </init-param> 
        <init-param> 
          <param-name>serverName</param-name> 
          <param-value>https://your-hostname</param-value> <-- hostname of registered URLs
        </init-param> 
        <init-param> 
          <param-name>artifactParameterName</param-name> 
          <param-value>SAMLArt</param-value> 
        </init-param> 
        <init-param> 
          <param-name>serviceParameterName</param-name> 
          <param-value>TARGET</param-value> 
        </init-param> 
        <init-param> 
          <param-name>redirectAfterValidation</param-name> 
          <param-value>true</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> 
    
      <!-- Other filters as needed -->

    Define the filter-mappings. (Note: The filter mappings below direct all default context requests ("/") to the 3 filters defined above.

      <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>
    
        <!-- 
          Other filter mappings as needed. 
          Ordering of filter mappings is important. 
        -->
  • (Optional): Print debugging information in the log

    To print the service ticket validation response in the CAS client log, add the following logger element to your log4j.xml:

      <logger name="org.jasig.cas.client" additivity="false">
          <level value="debug" /> 
          <appender-ref ref="[YOUR-APPENDER]" /> 
      </logger>
  • Add client jars to the application classpath

    WEB-INF/lib
          cas-client-core-3.5.1.jar
          cas-client-support-saml-3.5.1.jar
          jackson-annotations-2.8.0.jar
          jackson-core-2.8.8.jar
          jackson-databind-2.8.8.1.jar
          joda-time-2.9.9.jar
          slf4j-api-1.7.25.jar
    
  • Result

    • Application users are forced to log in thru CAS.
    • The UNI and affiliations are made available to the application via the AttributePrincipal.
    • If appropriate, the SSO session is honored.