Modern CAS (versions 5.2+) has an ability to interrupt authentication flow after primary authentication principal trust has been established. This ability enables CAS to execute an intermediary piece of application logic before continuing to establish Web Single Sign On session and routing requests back to target applications. These intermediary interrupt components are able to implement logic, for example, to present notification messages to the user, provide options for redirects to external services, etc. A common use case deals with presenting a bulletin board during the authentication flow to present messages and announcements to select users and then optionally require the audience to complete a certain task before CAS is able to honor the authentication request and establish a session.
Out of the box, CAS server comes with interrupt implementation strategies such as per-user, statically defined JSON resources defining interrupt strategies, pluggable REST resources defining interrupt strategies, regex principal attribute resolution dictating simple interrupt strategy, as well as most flexible, custom Groovy script based implementation strategy to define interrupt logic.
In this post, we'll review a sample custom Groovy script implementation of interrupt facility.
Let's just imagine that we want to define a custom interrupt screen per target registered service with a custom announcement message for that service, before continuing to that service application. The use cases states that the interrupt message per-registered service should be optional and if not defined, the interrupt for each particular service should not occur. Also, the definition of these messages per service should be stored in the simple text-based file and should be available to CAS in real-time; that is, no CAS server restart should occur if/when new interrupt messages are added to text file containing interrupt message definitions.
To start, we'd add interrupt facility to CAS overlay (Gradle in our example):
compile "org.apereo.cas:cas-server-support-interrupt-webflow:${project.'cas.version'}"
Then, we'll use Groovy's Config Slurper format and parser to implement the per-service interrupt messages. Add the following file to /etc/cas/config/interrupt directory and name it interrupts-by-service.conf:
'https://my.service1.edu' { message='Welcome to my service 1. Important announcement message GOES HERE' } 'https://my.service2.com' { message='Welcome to my service 2. Important announcement message GOES HERE' } 'https://example.com' { //message='The message is commented out and therefore an interrupt for this service will not be triggered. Uncomment it to trigger interrupt and show this message' }
The top service URLs should match any service ids defined in your CAS services registry. Adjust as necessary for your CAS deployment. Add the following Groovy file named interrupt-inquirer.groovy to /etc/cas/config/interrupt directory:
import org.apereo.cas.interrupt.InterruptResponse def run(final Object... args) { def interrupts = new ConfigSlurper().parse(new File('/etc/cas/config/interrupt/interrupts-by-service.conf').toURI().toURL()) def service = args[2] def msg = interrupts[service].message if(msg) { return new InterruptResponse(msg) } InterruptResponse.none() }
And finally add the following property to /etc/cas/config/cas.properties:
cas.interrupt.groovy.location=file:/etc/cas/config/interrupt/interrupt-inquirer.groovy
Then sit back, relax, and observe interrupts flowing your way!