Apereo CAS - Handling Multiple Logout URLs


Collaborate
This blog is managed and hosted on GitHub. If you wish to update the contents of this post or if you have found an inaccuracy and wish to make corrections, we recommend that you please submit a pull request to this repository.

Overview

CAS has had support for single logout for quite a while. This feature basically means that CAS is able to invalidate client application sessions in addition to its own SSO session, assuming client applications are ready to honor and accept logout requests with special configuration. When a CAS session ends, it notifies each of the services that the SSO session is no longer valid, and that relying parties need to invalidate their own session by processing a special logout request. Remember that the callback submitted to each CAS-protected application is simply a notification; nothing more. It is the responsibility of the application to intercept that notification and properly destroy the user authentication session, either manually, via a specific endpoint or more commonly via a CAS client library that supports SLO.

By default, applications are contacted by CAS using their original URL to receive the logout notification; which is simply the purified service URL used when an authentication request on behalf of the application is submitted to CAS. This tutorial focuses on ways one can customize the logout URL in more dynamic ways.

This tutorial deals with:

Single Logout URL

In dealing with single logout operations, the URL endpoint to receive the logout notification can be customized on a per-application basis:

{
  "@class" : "org.apereo.cas.services.RegexRegisteredService",
  "serviceId" : "https://\\w+.example.org",
  "name" : "Our Example Domain",
  "id" : 1,
  "description" : "The example domain provides examples in examplish ways",
  "logoutUrl" : "https://logout.example.org"
}

This is, of course, the simplest option and means that if CAS has established sessions with one or more applications that qualify for the above definition, those applications will receive logout notifications at the specified URL above when the logout engine in CAS begins to process records.

Many Logout URLs

One should note that the logoutUrl above not only static but also singular. With configuration only, there is not a way for one to specify more than one URL in cases where that might be needed. While the service configuration above presents a rather simplified version of the feature, CAS itself provides the internal mechanics to recognize and handle a collection of logout URLs for a given application. Our task here would be to extend the configuration slightly to implement this scenario and inject the behavior into the runtime.

We can start by preparing CAS with a customized configuration component that would house our customizations for this use case. Once that is done, take note of the following bean definition posted in CasCoreLogoutConfiguration.java today:

@ConditionalOnMissingBean(name = "singleLogoutServiceLogoutUrlBuilder")
@Bean
public SingleLogoutServiceLogoutUrlBuilder singleLogoutServiceLogoutUrlBuilder() {
    return new DefaultSingleLogoutServiceLogoutUrlBuilder(this.urlValidator);
}

Note how the bean is marked as conditional, meaning it will only be used by CAS if an alternative definition by the same is not found. So, in order for CAS to pick up our own alternative implementation, we are going to provide that bean definition in our own configuration class as such:

@Bean
public SingleLogoutServiceLogoutUrlBuilder singleLogoutServiceLogoutUrlBuilder() {
    return new CustomSingleLogoutServiceLogoutUrlBuilder(this.urlValidator);
}
Compile Dependencies
Note that in order for the CAS overlay build to compile our changes and put them to good use, the overlay must be prepared with the required module used during the compilation phase. Otherwise, there will be errors complaining about missing symbols, etc.

Now, it’s time to actually design our very own CustomSingleLogoutServiceLogoutUrlBuilder. Here is a modest example:

public class CustomSingleLogoutServiceLogoutUrlBuilder extends DefaultSingleLogoutServiceLogoutUrlBuilder {

    ...
    public Collection<URL> determineLogoutUrl(RegisteredService registeredService, WebApplicationService service) {

        /*
            Stuff happens to determine the collection of the logout URLs
            given the provided service and its registered definition in the registry.
        */
    }

}

That should do it. The very next time you build and deploy the changes, CAS should pick up our own bean definition and accompanying implementation class. It should be obvious that inside the class above, you have options to calculate the logout URLs as you wish since the builder object is expected to return a collection of URLs. To fully make this behavior dynamic, you may want to invest time researching service custom properties and externalize the logout function with special tags designed as properties that would then be consumed and processed in the above component.

So…

I hope this review was of some help to you and I am sure that both this post as well as the functionality it attempts to explain can be improved in any number of ways. Please feel free to engage and contribute as best as you can.

Happy Coding,

Misagh Moayyed

Related Posts

CAS 6.1.0 RC5 Feature Release

...in which I present an overview of CAS 6.1.0 RC5 release.

Apereo CAS - Are We Logged In Yet?

Learn how to modify and extend a CAS deployment to determine whether an SSO session is still valid and tied to a user authentication session.

Apereo CAS - REST API Integrations

Learn how to integrate with CAS using its REST API to authenticate, exchange tickets and get access to user profiles and attributes.

CAS 6.1.0 RC4 Feature Release

...in which I present an overview of CAS 6.1.0 RC4 release.

Apereo CAS - Multifactor Provider Selection

Learn how to configure CAS to integrate with and use multiple multifactor providers at the same time. This post also reveals a few super secret and yet open-source strategies one may use to select appropriate providers for authentication attempts, whether automatically or based on a menu.

Apereo CAS - Dockerized Hazelcast Deployments

Learn how to run CAS backed by a Hazelcast cluster in Docker containers and take advantage of the Hazelcast management center to monitor and observer cluster members.

Apereo CAS - Configuration Security w/ Jasypt

Learn how to secure CAS configuration settings and properties with Jasypt.

CAS 6.1.0 RC3 Feature Release

...in which I present an overview of CAS 6.1.0 RC3 release.

Apereo CAS - Webflow Decorations

Learn how you may decorate the Apereo CAS login webflow to inject data pieces and objects into the processing engine for display purposes, peace on earth and prosperity of all mankind, etc. Mainly, etc.

Apereo CAS - SAML2 Metadata Query Protocol

Learn how you may configure Apereo CAS to fetch and validate SAML2 metadata for service providers from InCommon's MDQ server using the metadata query protocol.