Apereo CAS - Extending Webflows


Collaborate
The 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.

Unlike previous versions, CAS 5 attempts to automate all required Spring Webflow changes on a per-module basis. In this new model, all one should have to do is to declare the appropriate module in the build script…and viola! CAS will take care of the rest.

If you wish to learn how that is done internally and furthermore, how you may take advantage of the same approach to extend CAS webflows and introduce your own, this is the right post for you.

This tutorial specifically requires and focuses on:

This post might equally apply to CAS 5.2.x. YMMV. To learn the same answers with CAS 5.0.x, please see this post.

Webflow Configurers

Every CAS module that needs to dynamically augment the Spring Webflow routes simply takes on the following form:

package com.example.cas;

public class SomethingWebflowConfigurer extends AbstractCasWebflowConfigurer {

    public SomethingWebflowConfigurer(final FlowBuilderServices flowBuilderServices,
                                    final FlowDefinitionRegistry loginFlowDefinitionRegistry,
                                    final ApplicationContext applicationContext,
                                    final CasConfigurationProperties casProperties) {
        super(flowBuilderServices, loginFlowDefinitionRegistry, applicationContext, casProperties);
    }

    @Override
    protected void doInitialize() throws Exception {
        final Flow flow = super.getLoginFlow();
        // Magic happens; Call 'super' to see what you have access to...
    }
}

CAS modules register their WebflowConfigurer instances in @Configuration classes:

package com.example.cas;

@Configuration("SomethingConfiguration")
public class SomethingConfiguration implements CasWebflowExecutionPlanConfigurer  {

    @Autowired
    @Qualifier("loginFlowRegistry")
    private FlowDefinitionRegistry loginFlowDefinitionRegistry;

    @Autowired
    private FlowBuilderServices flowBuilderServices;

    @Autowired
    private ApplicationContext applicationContext;

    @Autowired
    private CasConfigurationProperties casProperties;

    @ConditionalOnMissingBean(name = "somethingWebflowConfigurer")
    @Bean
    public CasWebflowConfigurer somethingWebflowConfigurer() {
        return new SomethingWebflowConfigurer(flowBuilderServices, loginFlowDefinitionRegistry,
            applicationContext, casProperties);
    }
    
    @Override
    public void configureWebflowExecutionPlan(final CasWebflowExecutionPlan plan) {
        plan.registerWebflowConfigurer(somethingWebflowConfigurer());
    }
    
}

Note that each CasWebflowConfigurer implementation may be assigned a specific order which is a numeric weight that determines its execution position once webflow auto-configuration kicks into action.

Remember
If you are looking for XML flow definitions to extend CAS, you are simply holding it wrong. While you may be creative enough to find a solution and make that approach work, it is pretty much guaranteed that your design will break quite quickly in the next upgrade.

Next, we just need to ensure that CAS is able to pick up our special configuration. To do so, create a src/main/resources/META-INF/spring.factories file and reference the configuration class in it as such:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.example.cas.SomethingConfiguration

…and that should be it.

So…

CAS itself handles Spring Webflow changes related to its first-class features by default automatically. That strategy equally applies, should you need to write your own configurers if you absolutely need to. Be sure to take extra as accidents may happen. What if you have two WebflowConfigurers who all decide to inject actions and state into the same Spring Webflow areas? What if multiple WebflowConfigurers are competing to set themselves up as starting points of the CAS webflow? Who wins, who mourns?

Indeed, these are questions you ought to be thinking about as a developer. With power comes responsibility.

Remember

  • Changes are all scoped to one technology, that is Java.
  • You have the full power of Java to dynamically augment the Spring Webflow as you see fit.
  • Your changes are all self-contained.
  • Unlike XML, your changes are now part of the CAS APIs. If you upgrade and something breaks, you will be notified immediately at build time.

That’s all.

Misagh Moayyed

Related Posts

CAS 6.0.0 RC4 Feature Release

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

Apereo CAS 6.0.x - Building CAS Feature Modules

An overview of how various CAS features modules today can be changed and tested from the perspective of a CAS contributor working on the codebase itself to handle a feature request, bug fix, etc.

CAS 6.0.x Deployment - WAR Overlays

Learn how to configure and build your own CAS deployment via the WAR overlay method, get rich quickly, stay healthy indefinitely and respect family and friends in a few very easy steps.

Apereo CAS - Jib at CAS Docker Images

Learn how you may use Jib, an open-source Java containerizer from Google, and its Gradle plugin to build CAS docker images seamlessly without stepping too deep into scripting Dockerfile commands.

Apereo CAS 6 - Administrative Endpoints & Monitoring

Gain insight into your running Apereo CAS 6 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 - SAML2 Metadata with MongoDb

CAS distributed SAML2 metadata management using MongoDB, where you learn how to store metadata documents inside MongoDB for CAS as a SAML2 identity provider and all other registered SAML2 service providers.

Apereo CAS - Slurp Configuration with Groovy

Learn how CAS configuration may be consumed via Groovy to simplify and consolidate settings for multiple deployment environments and profiles.

Apereo CAS - Configuration Management with MongoDb

CAS distributed configuration management using MongoDb, where you learn how to store and secure CAS configuration settings and properties inside MongoDb.

Apereo CAS - Integration with HashiCorp Vault

CAS distributed configuration management using HashCorp Vault, where you learn how to store and secure CAS configuration settings and properties inside Vault.

CAS 6.0.0 RC3 Feature Release

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