development icon

Implementing CAS Single Sign-On in Drupal 8

Daniel Sasser, Developer
#Development | Posted

When organizations provide omni-channel solutions tailored to individual users, managing multiple authentication portals and authorization stores can be tricky. Users have to sign into multiple interfaces and remember credentials for those applications. These in turn are managed by an IT team with the responsibility of ensuring systems not only function but are secure. This task becomes exponentially more difficult and expensive as services are added to the platform.

The answer for this problem is a single sign-on (SSO) solution that allows a user to sign in once to a central authentication provider, which automatically authenticates the user to other services in the ecosystem. SSO options range from custom solutions to proprietary and open source technologies. If you’re working in academia, however, a common choice is Central Authentication Service (CAS).

CAS is a SSO service that can either be integrated into or replace your web application authentication. It is an open source project with roots at Yale University and exits today as a widely used protocol for SSO in the educational space. CAS itself isn’t involved in storing credentials. It serves as a common interface for a number of available authentication handlers, including databases, LDAP, RADIUS, OAuth, OpenID and more.

How CAS Works

The process starts when a user visits a CAS client (aka a web application configured to work with CAS). When a user wants to login to the client app, they are redirected to the CAS login endpoint where they must authenticate. Upon successful authentication, the user is redirected back to the client app with what is known as a CAS Ticket Granting Ticket (CASTGT) and a Service Ticket (ST). The client app then sends a second request to CAS to validate the tickets. CAS sends a reply to the client with the user ID and a success message. With this information, the client app logs the user in.

If some of the logic in the workflow looks familiar, it might be because CAS is modeled after the Kerberos protocol.

CAS Architecture

There are several pre-packed CAS client libraries for various programming languages you can leverage within your client app. Packages exist for .NETJavaApachePHP and more.

CAS in Drupal 8

For those working in Drupal, we are fortunate not to have to build the toolset to communicate with CAS by hand or try to leverage the phpCAS library. Instead, we have the CAS module. Out of the box the CAS module gives us everything we need to get a user authenticated to our Drupal site with CAS as the authentication portal. Today I’ll be talking specifically about how to get CAS going in Drupal 8 – but never fear, there is a Drupal 7 version of the module too!

Step 1: Install CAS

Download the 8.x-1.x-dev version of the CAS module from https://drupal.org/project/cas, unless there is a tagged D8 release, in which case use that instead. Install the module.

Step 2: Configure CAS

Once the CAS module is installed, head to /admin/config/people/cas to configure it. This configuration form can seem overwhelming at first given the amount of options, so let’s cover each of them a briefly.

  • Version: This is the version of the CAS protocol that your site will use to communicate with the CAS endpoint. Use the one that matches your CAS server configuration.
  • Hostname: The hostname of your CAS server
  • Port: The port your CAS server is listening on
  • URI: The path on the server that represents your primary CAS endpoint, typically “/cas”
  • SSL Verification: Options for dealing with SSL verification. If your CAS server is using a self-signed certificate you will need to choose the “Do not verify CAS server” option, but be aware that this weakens your security.
  • Gateway: Logs a user into Drupal if they are already logged into CAS. The CAS server will not “paint” the user logon screen but seamlessly log the user in using their existing CASTGT.
  • Forced Login: Unlike the Gateway service which checks if you are logged in, forced login will ensure that you are. We can limit the conditions to pages much like a block can.
  • Auto Register Users: Automatically creates Drupal users for CAS authenticated users if they don’t already have an account
  • Drupal Logout Triggers CAS Logout: When you logout of Drupal, you log out of CAS as well. The site will send CAS your logout request and you will be logged out of Drupal at the same time.
  • Enable single log out: When you logout in CAS, you logout of Drupal. This is not a recommended setting since it allows your session to be stored un-hashed.
  • Proxy: Leverages the proxy features in CAS
  • Debugging: Logs debugging information to Drupal watchdog. It is very handy when developing but should be enabled on an as-needed basis in production due to the log spam it can create.

Step 3: Login with CAS

Lets assume for the sake of this discussion that we have configured our Drupal site as such:

  • Gateway: disabled
  • Forced Login: disabled
  • Auto register users: disabled

As an anonymous user, visit your Drupal site and try to login with the above settings. You will be presented with the core Drupal login form. So why aren’t we being redirected to CAS for authentication? To find that answer we need to understand a bit more how the CAS module works to in D8.

How the CAS Module Works

Recall that our configuration has the forced login and gateway options disabled, so CAS won’t be invoked on a user by force. But by visiting the /user/login path you might expect to be redirected to the CAS server endpoint. However, the CAS module doesn’t work that way. It provides its own path to trigger a CAS authentication workflow.

Instead of modifying the /user/login route path, the CAS module provides a new route at /caslogin. The controller for this route is responsible for creating the redirect to CAS. The redirect specifies the location of the CAS server as well as the url of the client app that CAS should send the user to after authenticating. To accomplish this the HTTP response includes a query string parameter, service, appended to the location value of the header.

└╼ curl -I http://example.com/caslogin

HTTP/1.1 302 Found

Server: Apache/2.4.16 (Unix) PHP/5.5.31 OpenSSL/0.9.8zg

Cache-Control: must-revalidate, no-cache, private

Location: https://cas.example.com:443/cas/login?service=http%3A//example.com/cass…

Content-language: en

Content-Type: text/html; charset=UTF-8

CAS SERVICE

The CAS module exposes another route at /casservice. This route controller is responsible sending the CASTGT and ST tickets to CAS for validation and logging in the user to Drupal. With a successful authentication response from the CAS server, the module determines if the now-authenticated CAS user should be logged into Drupal. When doing so, the module maps the user ID from CAS as the Drupal user name. So if CAS returns a user ID of xyz123 along with the success message, that name is used as the Drupal user name during processing. In our case, the Drupal user xyz123 would need to exist in order to be logged in. To have xyz123 be automatically logged in as a new user, we would have to enable the auto register users option in the CAS configuration form.

To make the forced login and gateway features work, the CAS module adds an event listener to every page request. In the event handler, CAS triggers the gateway and forced login condition checks and returns a redirect response if the user needs to be sent to CAS for authentication:

$event->setResponse(new CasRedirectResponse($cas_login_url));

CAS EVENTS

The CAS module adds its own events that other modules can subscribe to that “hook” into it’s workflow:

  • CasPreAuthEvent: Allows modules to change data received from CAS before attempting to load a Drupal user
  • CasUserLoadEvent: Modules can prevent users from logging in or can modify user attributes before they are saved to the Drupal account

Conclusion

As we have seen, CAS is a versatile SSO solution that works with authorization stores like LDAP or Oauth to provide a common portal for integrated touch points. And CAS client apps can interact with the CAS service using existing libraries like phpCAS, or leverage the CAS module if working in Drupal. We looked at how to configure the CAS module to work in Drupal 8 without writing a single line of code. Hopefully you now have enough knowledge to pursue your own CAS project, whether it be in Drupal or any other web application.

 

Daniel Sasser

Developer