Skip to end of metadata
Go to start of metadata
Table of Contents

The Java CAS Client >=3.1.12 supports the Java Authentication and Authorization Service (JAAS) framework, which provides authnz facilities to CAS-enabled JEE applications.

Supported Software

Icon

The Jasig Java CAS client added support for JAAS in version 3.1.11 with specific support for JBoss Application Server version 4.2.3 and higher. After release we discovered a problem on JBoss that required additional features that appear in version 3.1.12. It is strongly recommended that version 3.1.12 be used in production applications. The JAAS integration should be generalizable to any JEE container such as WebSphere, but additional development would be required. If you are interested in collaborating to adapt the JAAS support for other JEE containers, please post a note to the cas-dev mailing list.

Overview

A general JAAS authentication module, CasLoginModule, was added in version 3.1.11 with the specific purpose of providing authentication and authorization services to CAS-enabled JEE applications. The design of the module is simple: given a service URL and a service ticket in a NameCallback and PasswordCallback, respectively, the module contacts the CAS server and attempts to validate the ticket. In keeping with CAS integration for Java applications, a JEE container-specific servlet filter is needed to protect JEE Web applications. The JBoss WebAuthentication component provided a convenient integration piece between a servlet filter and the JAAS framework, so a complete integration solution is available only for JBoss AS versions that provide the WebAuthentication class (4.2.3 and 5.x). The JAAS support should be extensible to any JEE container with additional development.

Configuration

The following configuration instructions make the following assumptions:

  1. Jasig Java CAS client 3.1.12 or later
  2. JBoss AS container supporting the WebAuthentication class
  3. Ability to configure JAAS authentication modules for entire container or deployment descriptor of JEE application

Dependencies

The following Jasig Java CAS Client modules are needed for JAAS support in JBoss:

  • cas-client-core
  • cas-client-integration-jboss

Note that the above modules have their own dependencies as seen from the output of the mvn dependency:tree command:

Most if not all of the JBoss dependencies above should be available to a JEE application deployed to JBoss AS.

Configure CasLoginModule

It is expected that for JEE applications both authentication and authorization services will be required for CAS integration. The following JAAS module configuration file excerpt demonstrates how to leverage SAML 1.1 attribute release in CAS to provide authorization data in addition to authentication:

Sample JAAS Module Configuration

For JBoss it is vitally important to use the above values for principalGroupName and roleGroupName. Additionally, the cacheAssertions and cacheTimeout are required since JBoss by default attempts to reauthenticate the JAAS principal with a fairly aggressive default timeout. Since CAS tickets are single-use authentication tokens by default, assertion caching is required to support periodic reauthentication. A full description of CasLoginModule configuration attributes follows.

  • ticketValidatorClass - Fully-qualified class name of CAS ticket validator class.
  • casServerUrlPrefix - URL to root of CAS Web application context.
  • service (optional) - CAS service parameter that may be overridden by callback handler. NOTE: service must be specified by at least one component such that it is available at service ticket validation time.
  • defaultRoles (optional) - Comma-delimited list of static roles applied to all authenticated principals.
  • roleAttributeNames (optional) - Comma-delimited list of attribute names that describe role data delivered to CAS in the service-ticket validation response that should be applied to the current authenticated principal.
  • principalGroupName (optional) - The name of a group principal containing the primary principal name of the current JAAS subject. The default value is "CallerPrincipal", which is suitable for JBoss.
  • roleGroupName (optional) - The name of a group principal containing all role data. The default value is "Roles", which is suitable for JBoss.
  • cacheAssertions (optional) - Flag to enable assertion caching. This may be required for JAAS providers that attempt to periodically reauthenticate to renew principal. Since CAS tickets are one-time-use, a cached assertion must be provided on reauthentication.
  • cacheTimeout (optional) - Assertion cache timeout in minutes.

Ticket validator configuration attributes, such as tolerance in the example above, are also supported.

Configure Servlet Filters

Integration with the servlet pipeline is required for a number of purposes:

  • Examine servlet request for an authenticated session
  • Redirect to CAS server for unauthenticated sessions
  • Provide service URL and CAS ticket to JAAS pipeline for validation

The WebAuthenticationFilter performs these operations for the JBoss AS container. It is important to note that this filter simply collects the service URL and CAS ticket from the request and passes it to the JAAS pipeline. It is assumed that the CasLoginModule will be present in the JAAS pipeline to consume the data and perform ticket validation. The following web.xml excerpts demonstrate how to integrate WebAuthenticationFilter into a JEE Web application.

Sample Web Deployment Descriptor
  • No labels

3 Comments

  1. Notes to make it work in JBoss 6.

    • You need to copy cas-client-core-<version>.jar and cas-client-integration-jboss-<version>.jar to your lib dir. Later, restart the server.
    • The JAAS LoginModule configuration is in conf/login-config.xml and the format is:
    <application-policy name="cas">
    <authentication>
        <login-module code="org.jasig.cas.client.jaas.CasLoginModule" flag="required">
           <module-option name="ticketValidatorClass">org.jasig.cas.client.validation.Saml11TicketValidator</module-option>
             <module-option name="casServerUrlPrefix">http://yourcasserver/cas</module-option>
             <module-option name="tolerance">20000</module-option>
             <module-option name="defaultRoles">admin,user</module-option>
             <module-option name="roleAttributeNames">memberOf,eduPersonAffiliation,authorities</module-option>
             <module-option name="principalGroupName">CallerPrincipal</module-option>
             <module-option name="roleGroupName">Roles</module-option>
             <module-option name="cacheAssertions">true</module-option>
             <module-option name="cacheTimeout">480</module-option>
          </login-module>
       </authentication>
    </application-policy>

    Use it instead of:

    cas {
      org.jasig.cas.client.jaas.CasLoginModule required
        ticketValidatorClass="org.jasig.cas.client.validation.Saml11TicketValidator"
        casServ
      ...
    • Not use the Saml11TicketValidator doesn't work out of the box. Use Cas20ServiceTicketValidator instead.
    • Finally, modify the deploy/jbossweb.sar/server.xml and uncomment:
    <Valve className="org.apache.catalina.authenticator.SingleSignOn" />

    In some sites says this is not necesary but it is.

    And remember not to add <security-constraint>, <login-config> elements in your web.xml if so your login-config will not be enabled.

    If you have any trouble, you can enable the log of cas in deploy/jboss-logging.xml adding:

    <logger category="org.jasig">
       <level name="TRACE" />
    </logger>
     
  2. There is a bug starting from JBoss5 that won't let you to get the authenticated CAS username  (https://issues.jboss.org/browse/EJBTHREE-1756) from the EJB container using the standard method context.getCallerPrincipal(). Calling that method from an EJB will return the service parameter instead the username.

    For JBoss we can use the SecurityAssociation class to get the CAS principal:

    for(Principal p: SecurityAssociation.getSubject().getPrincipals()) {
        if(p instanceof org.jasig.cas.client.jaas.AssertionPrincipal) { 
             return p.getName();
         }
    }

    That snippet will return us the username used to authenticate into CAS. If you prefer a more portable solution, since that one couldn't be usable into another application server, you could use the workarround provided in the previous link to the bug description. 

    In my case, I'm using RestEasy integrated with EJB (http://docs.jboss.org/resteasy/docs/2.0.0.GA/userguide/html_single/index.html#RESTEasy_EJB_Integration) In that scenario I've not access to the SecurityClient so the workarround proposed is not valid. We can still using the no portable solution (SecurityAssociation) or propagate "manually" the username form the http layer to the EJB container. 

    /** this class will be used to assign the authenticated username to the current thread */
    public class CASThreadLocal {
        private static threadLocal<String> thread = new ThreadLocal<String>();
        public static ThreadLocal<String> get() {
            return thread;
        }
    }

    In the http layer we can get the valid username and store it:

    String username = servletRequest.getUserPrincipal().getName();
    CASThreadLocal.get().set(username);

    Later, in the ejb's we can access to the authenticated username:

    String username = CASThreadLocal.get().get();

    I hope this will be useful to improve the CAS/JEE Integration.

     
  3. Is there a way to use the CAS + JAAS Integration, along with using the <security-constraints> in the web.xml file then?