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.0.0 RC1 Feature Release

...in which I present an overview of CAS 6.0.0 RC1 release.

Get Productive with Shell Aliases

A collection of useful shell aliases, gathered over the years to help increase one's productivity and developer happiness.

feat(conventional_commits): signal breaking changes in commit titles

In which I suggest Conventional Commits should be enhanced to reflect the breakingness of commits in their commit message titles.

uPortal annual report, June 2018 edition

Ecoysystem. Releases. Community. Fiscal responsibility.

One Can Only Hope in Buchistan

A true story inspired by real events. Seriously. Bryan Cranston has been approached for the role of "Some".

Apereo CAS - Extending Webflows

Learn and master extending CAS 5 Spring Webflow definitions.

Apereo CAS - Administrative Endpoints & Monitoring

Gain insight into your running Apereo CAS deployment in production. Learn how to monitor and manage the server by using HTTP endpoints and gather metrics to diagnose issues and improve performance.

Apereo CAS - Custom Authentication & Attribute Sources

Master writing custom authentication handlers/schemes in CAS and learn how to design custom data sources that can produce user claims and attributes.

Apereo CAS - User Interface Customizations

A short tutorial on Apereo CAS user interface customizations, including themes, localization and dynamic views for all those who enjoy front-end development and suffer from instant gratification.

CAS Multifactor Authentication with Google Authenticator

A short walkthrough to demonstrate how one might turn on multifactor authentication with CAS using Google Authenticator, leveraging a variety of triggers.