Single Sign-On (SSO) with Drupal and CAS

Posted: 1 June 2011 by Alistair Miles in Uncategorized
Tags: , , , , ,

Last year I did a user management and single sign-on (SSO) implementation for the Worldwide Anti-malarial Resistance Network (www.wwarn.org), after much clattering about with various pieces of software I settled on the following.

Drupal has built-in features for user registration and management, and we had already decided to use Drupal as the CMS for static content, so it made sense to try and re-use these capabilities. Alongside Drupal we deployed CAS, which acts as an SSO authentication server. Drupal and CAS can be made to talk to each other using the Drupal/CAS module, so we installed and configured this. This changes the behaviour of the normal login and logout links in Drupal, so you’re redirected to the CAS login/logout screens instead, and handles ticket validation after you’ve successfully logged in to CAS and been redirected back to Drupal. Rather than deploy a separate user directory or database, we used the Drupal database, i.e., we configured CAS to query the Drupal database directly via JDBC when checking user login credentials.

Any Java web applications that we wanted to integrate with the CAS SSO service were integrated using the Spring Security CAS implementation. Any other web applications could be integrated using mod_auth_cas, if running as a CGI-style application under Apache, or if running behind Apache as a reverse proxy by using the pre-authentication pattern.

The only coding needed to make this all happen was the cosmetic work needed to make the CAS login and logout screens look like part of the same website, which was fairly straightforward.

The diagram below is a bit rough around the edges, but hopefully it gives an outline of how this is all setup.

Note that there are no restrictions on where any of these components are hosted. I.e., CAS, Drupal, and the webapps could all be hosted on different servers on different networks, or all on the same computer, it doesn’t matter, as long as they can talk to each other.

For WWARN we also used Drupal to define and assign roles to users, which were then used by other applications to implement authorisation policies, but this isn’t necessary to achieve SSO authentication. To use Drupal for role management the other applications also had to query the Drupal database, however I believe this could also be achieved via SAML attribute release, which would remove the need for extra JDBC communication.

Advertisement
Comments
  1. Greg says:

    Thanks for the article. We have a similar need (i.e) where we need CAS to query against Drupal database. Can you explain on how you achieved this. We have MD5 hashed passwords.

    • Hi Greg,

      At a bare minimum, I believe you can just customise the deployerConfigContext.xml file. Here’s an example of the deployerConfigContext.xml file we use, is that what you were after? In that example the datasource is referred to via JNDI. There is also an older example where the datasource is defined inline within the spring configuration.

      The key bit of configuration magic to tell CAS how to deal with the Drupal database is:

      <bean id="authenticationManager" class="org.jasig.cas.authentication.AuthenticationManagerImpl">
      
        <!-- ... other properties ... -->
      
        <property name="authenticationHandlers">
          <list>
            <bean class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler" p:httpClient-ref="httpClient" />
            <bean class="org.jasig.cas.adaptors.jdbc.SearchModeSearchDatabaseAuthenticationHandler">
              <property name="tableUsers"><value>users</value></property>
              <property name="fieldUser"><value>name</value></property>
              <property name="fieldPassword"><value>pass</value></property>
              <property name="dataSource" ref="drupal6"/>
              <property name="passwordEncoder">
                <bean class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder">
                  <constructor-arg index="0" value="MD5" />
                </bean>
              </property>
            </bean>  
          </list>
        </property>
      
      </bean>
      

      Hope that helps.

      • Ayan says:

        Very informative article. Thank you for sharing!

        I was thinking of implementing the same but with drupal 7. Any idea about what passwordEncoder will be used? I am asking this because D7 uses sha-512 for password encryption (drupal 6 used md5) and might also be using iterations to further strengthen the password. With this in mind, could you please suggest the appropriate passwordEncoder property?

      • Hi Ayan, I’m sorry I don’t have the answer off-hand, try asking on the CAS users list.

      • Markus Döring says:

        Hi Ayan,
        as far as I can tell there is no existing password encoder in java that does the same hashing as D7. D7 uses SHA512, but also uses a configurable number of iterations, a salt, a custom prefix to store which encoding was used and last not least only stores a configurable substring of the complete 512 characters hash.

        I ended up modifying password_inc to use standard MD5 again (if you are concerned you can also use regular SHA256 or 512). That way I could use the out of the box password encoder. Mimicking the D7 encoder with all its configuration options in java seemed not a good idea.

        Good end of the story is that it worked!

      • Ayan says:

        Hi Markus,
        We did consider a similar approach as well but our drupal site already had quite a few existing users. Changing password hash mechanism would have required resetting passwords for the existing users which was not an option for us. So we ended up authenticating CAS against the magento db (was part of bigger picture that required SSO). Magento’s password hashing technique was relatively simpler to replicate in a custom password encoder (i.e salt+md5(pass):salt).

      • Ayan says:

        correction, it’s md5(salt+pass):salt

  2. Marc says:

    Thanks for taking the time to create this article: very very very helpful! In your diagram, you left out phpCAS as a client, which is the most feature rich (https://wiki.jasig.org/display/CASC/Client+Feature+Matrix). Incidentally, what tool did you use to diagram?

  3. Markus Döring says:

    Did you have to modify Drupal to also create a cas user when a new user registers? That doesn’t seem to happen for me

    • No, because CAS is configured to use the Drupal database as the database of user credentials. I.e., Drupal and CAS are both pointing at the same database of users. Does that answer your question?

      • Markus Döring says:

        The cas module for Drupal creates a second table of cas_users that needs to be populated too though, even if CAS uses directly the Drupal tables. The cas module won’t work if that other table isn’t populated – at least it doesn’t work for me. Don’t you need the cas_user table?

  4. Ted Best says:

    Excellent overview. I don’t think touching Java or Apache config will be an option for me, but I will definitely look into the CAS module for Drupal 7.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s