Single Sign On (SSO): How to use Active Directory as an authentication method for CAS service?

mico picture mico · Jun 20, 2011 · Viewed 28.9k times · Source

I am developing a portal to Liferay and want to apply there a Single Sign On mechanism (SSO). I am using Jasig CAS for centralized authentication of my multiple web applications. Until now I know that I am able to use CAS as an authentication method but the next step would be to add some more intelligence and ask the authentication from an Active Directory server.

This should be possible by using AD as a "database" towards which the authentication is made, but I am new on these things and do not know how to make this with Jasig CAS.

Any clue how to accomplish this task?

Answer

John King picture John King · Jun 22, 2011

I'm making a few assumptions here, so please let me know if I'm off target:

  1. You're using a version of CAS between 3.3.2 and 3.4.8.
  2. You want to tie CAS into Active Directory via LDAP (for Kerberos or SPNEGO see references below) using the Bind LDAP Handler (for FastBind see references below).
  3. You're familiar with building CAS from source via Maven.

Prerequisite

  • If you're going to bind to AD via "ldaps://" (as opposed to "ldap://"), the JVM on your CAS server needs to trust the SSL certificate of your Active Directory server. If you're using a self-signed cert for AD, you'll need to import this into the JVM's trust store.

Summary

Within your CAS source tree, you'll need to make changes to the following files:

  • cas-server-webapp/pom.xml
  • cas-server-webapp/src/main/webapp/WEB-INF/deployerConfigContext.xml

Details

pom.xml:

Add the following within <dependencies>:

<!-- LDAP support -->
<dependency>
    <groupId>${project.groupId}</groupId>
    <artifactId>cas-server-support-ldap</artifactId>
    <version>${project.version}</version>
</dependency>

deployerConfigContext.xml:

  1. Reconfigure your Authentication Handers:

    • Look for: <property name="authenticationHandlers">. Inside this is a <list>, and inside this are (probably) two <bean ...> elements
    • Keep this one:

      <bean class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler" p:httpClient-ref="httpClient" />
      
    • The other <bean> (again, probably) corresponds to the current method of authentication you're using. (I'm not clear based upon the question, as there are several ways CAS can do this without using external services. The default is SimpleTestUsernamePasswordAuthenticationHandler, this authenticates as long as username is equal to password). Replace that <bean> with:

      <!-- LDAP bind Authentication Handler -->
      <bean class="org.jasig.cas.adaptors.ldap.BindLdapAuthenticationHandler">
      <property name="filter" value="uid=%u" />
          <property name="searchBase" value="{your LDAP search path, e.g.: cn=users,dc=example,dc=com}" />
          <property name="contextSource" ref="LDAPcontextSource" />
          <property name="ignorePartialResultException" value="yes" /> <!-- fix because of how AD returns results -->
      </bean>
      
    • Modify the "searchBase" property according to your AD configuration.

  2. Create a Context Source for LDAP:

    • Add this somewhere within the root <beans> element:

      <bean id="LDAPcontextSource" class="org.springframework.ldap.core.support.LdapContextSource">
          <property name="pooled" value="false"/>
          <property name="urls">
              <list>
                  <value>{URL of your AD server, e.g.: ldaps://ad.example.com}/</value>
              </list>
          </property>
          <property name="userDn" value="{your account that has permission to bind to AD, e.g.: uid=someuser, dc=example, dc=com}"/>
          <property name="password" value="{your password for bind}"/>
          <property name="baseEnvironmentProperties">
              <map>
                  <entry>
                      <key>
                          <value>java.naming.security.authentication</value>
                      </key>
                      <value>simple</value>
                  </entry>
              </map>
          </property>
      </bean>
      
    • Modify "urls", "userDn" and "password" accordingly.

Rebuild cas-server-webapp and try it.

References: