CAS Tips & Troubleshooting

Unknown macro: {scrollbar}

Tips

CAS JDBC deployerConfigContext.xml

These are instructions to configure CAS to use JDBC for usernames and passwords.

  1. Add the following bean to deployerConfigContext.xml, changing values where applicable:
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
      <property name="driverClassName">
        <value>com.mysql.jdbc.Driver</value>
      </property>
      <property name="url">
        <value>jdbc:mysql://localhost:3306/hibernate</value>
      </property>
      <property name="username">
        <value>hibuser</value>
     </property>
     <property name="password">
        <value>password</value>
     </property>
    </bean>
    
  2. Replace the default SimpleTestUsernamePasswordAuthenticationHandler bean with this bean, changing values where applicable:
    <bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">
      <property name="dataSource" ref="dataSource" />
      <property name="sql" value="select PASSWORD from USERS where lower(USERNAME) = lower(?)" />
    </bean>
    

CAS LDAP deployerConfigContext.xml

These are instructions to configure CAS to use LDAP for usernames and passwords.

  1. Add the following bean to deployerConfigContext.xml, changing values where applicable:
    <bean id="contextSource" class="org.springframework.ldap.core.support.LdapContextSource">
      <property name="pooled" value="false"/>
      <property name="urls">
        <list>
          <value>ldap://localhost:10389</value>
        </list>
      </property>
      <property name="userDn" value="uid=admin,ou=system"/>
      <property name="password" value="secret"/>
      <property name="baseEnvironmentProperties">
        <map>
          <entry key="java.naming.security.authentication" value="simple" />
        </map>
      </property>
    </bean>
    
  2. Replace the default SimpleTestUsernamePasswordAuthenticationHandler bean with this bean, changing values where applicable
    <bean class="org.jasig.cas.adaptors.ldap.BindLdapAuthenticationHandler">
      <property name="filter" value="uid=%u" />
      <property name="searchBase" value="ou=users,ou=system" />
      <property name="contextSource" ref="contextSource" />
    </bean>
    

Troubleshooting

Note: Some of the items on this page are only applicable if you are configuring a new CAS server.

Enabling SSL on the CAS server

See Enabling SSL on the CAS server.

Enable Logging

The recommended first step is to enable security logging. This is described in Turning on Security Logging. If running JBoss, you should also enable JBoss' security logging. Add the following snippet to server/default/conf/jboss-log4j.xml.

jboss-log4j.xml
<category name="org.jboss.security">
  <priority value="TRACE" class="org.jboss.logging.XLevel"/>
</category>

References

Redirect Loop

The Firefox error below can occur when your SSL certificate is not setup correctly or when your Spring Security config is incorrect. (Internet Explorer also fails but the error message is generic.)

Firefox Error Message

The page isn't redirecting properly Firefox has detected that the server is redirecting the request for this address in a way that will never complete. This problem can sometimes be caused by disabling or refusing to accept cookies.

Essentially, Firefox has detected an infinite loop of redirects. Causes of this problem can be:

  • This can happen with self-signed certificates and is due to the fact that the tomcat entry in the keystore used by Tomcat (as specified in server.xml) is not the same entry in cacerts. In other words, the tomcat entry is not trusted by the JVM. Follow the steps outlined in Trusting the Certificate to verify that the fingerprints match.
  • This can also occur when you do not have a CasAuthenticationProvider defined in your config.
  • The "CAS failed" URL (e.g. /pentaho/casFailed) might be protected. Combine that bug with a ticket validation failure and the result will be an infinite redirect where CAS says "userx is already logged in so redirect back" and Pentaho says "I don't know who you are and this page is protected so redirect."

More than one entry in %USER_HOME%/.keystore

The Tomcat documentation states that the keyAlias attribute is required (on the Connector element in server.xml) if you have more than one entry in %USER_HOME%/.keystore.

"Add this element [PentahoDoc:keyAlias] if your have more than one key in the KeyStore. If the element is not present the first key read in the KeyStore will be used."

jsessionid in service URL

Warning: This tip is only applicable if you are using a version of CAS prior to version 3.0.5.

org.springframework.security.ui.cas.CasProcessingFilterEntryPoint calls request.encodeURL() when constructing the redirect to the CAS login page. When constructing URLs that will be given to the browser, it is good practice to use request.encodeURL(). This ensures that browsers with cookies disabled will still be able to maintain a session on the server. If Tomcat determines that the browser does not support cookies, Tomcat appends a parameter named jsessionid to URLs created with request.encodeURL(). (If the browser does support cookies, the jsessionid is stored in a cookie which doesn't appear in URLs.)

org.apache.catalina.connector.Response, Tomcat's HttpServletResponse implementation, contains the following logic as documented in the javadoc of its isEncodeable() method. This method is called by encodeURL().

Return true if the specified URL should be encoded with a session identifier. This will be true if all of the following conditions are met:

  • The request we are responding to asked for a valid session
  • The requested session ID was not received via a cookie
  • The specified URL points back to somewhere within the web application that is responding to this request

So why all of this background information? Because it's possible that a service, when redirecting to the CAS login page, does not know if the browser can accept cookies yet, and must therefore append the jsessionid to the service URL. When Spring Security goes to validate the ticket, you'll get a BadCredentialsException with a root cause of INVALID SERVICE. Why? Because the service value in the Spring Security {{org.springframework.security.ui.cas.ServiceProperties
}} does not have a jsessionid value in it (but the service value given to CAS does) and therefore the compare fails.

There are several ways to address this problem:

  1. Upgrade to CAS 3.0.5 or later. The CAS team has already addressed this issue in CAS-360. Also see SEC-306 for its relation to Spring Security.
  2. Do not create a session before the CasProcessingFilterEntryPoint runs. For this, you'll need to disallow the creation of sessions within org.springframework.security.ui.ExceptionTranslationFilter (in addition to any session creation done within other filters). Set the createSessionAllowed property to false as in the example below:
    <bean id="exceptionTranslationFilter" class="org.springframework.security.ui.ExceptionTranslationFilter">
      <property name="authenticationEntryPoint">
        <ref local="authenticationProcessingFilterEntryPoint" />
      </property>
      <property name="accessDeniedHandler">
        <bean class="org.springframework.security.ui.AccessDeniedHandlerImpl" />
      </property>
      <property name="createSessionAllowed" value="false" />
    </bean>
    
    The downside to this solution is that your original request is not saved (because the filter has nowhere (e.g. a session) to save it).

    Note: Even though you might disallow session creation in ExceptionTranslationFilter, other filters (even your own filters unrelated to security) might be creating a session, which will force a jsessionid to be appended to the service URL. You'll need to eliminate the session creation in those filters for this workaround to work.

References

503

If you get 503 for an XHTML DTD then you are most likely using an incorrect CAS service ticket validator URL.

unable to find valid certification path to requested target

If you get this message in the server log, you most likely did not execute the "Trusting the Self-Signed Certificate" instructions on Enabling SSL on the CAS Server. Make sure that the cacerts keystore into which you are importing belongs to the JDK running Tomcat.