Apereo CAS - Multifactor Provider Selection

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.


Sometimes, it takes more than one multifactor provider to change a lightbulb. With CAS, it is certainly possible to configure more than one provider integration at the same time. The trick, however, is to decide the appropriate provider, should more than one qualify for the same transaction. Imagine you have an application registered with CAS whose multifactor authentication policy is equally deserving of, let’s say, Duo Security as well as Google Authenticator. How would you go about choosing one that makes the most sense?

Our starting position is based on:


So, let’s pretend that our application is registered with CAS as such:

  "@class": "org.apereo.cas.services.RegexRegisteredService",
  "serviceId": "^(https|imaps)://.*",
  "name": "Example",
  "id": 1,
  "description": "This service definition defines a service.",
  "evaluationOrder": 1,
  "multifactorPolicy" : {
    "@class" : "org.apereo.cas.services.DefaultRegisteredServiceMultifactorPolicy",
    "multifactorAuthenticationProviders" : [ "java.util.LinkedHashSet", [ "mfa-duo", "mfa-gauth" ] ]

Provider Rankings

The first and default strategy is to assign ranks to each provider. Ranking of authentication methods is done per provider via specific properties for each in CAS settings. Note that the higher the rank value is, the higher on the security scale it remains. A provider that ranks higher with a larger weight value override others with a lower value.

In practice, this would be:


When CAS sees that the application policy allows for both mfa-duo and mfa-gauth, it evaluates the rank for each and picks the one that outranks the other. In the above example, Google Authenticator will be chosen over Duo Security. If ranks are equal, that would be the equivalent of I am feeling lucky behavior, which is to say unspecified.

Ranking strategies are fine if you are willing to make a decision on behalf of all users. This is CAS, forming an opinion based on pre-defined configuration without taking into account user choice.

Selection Menu

Another option is to put the power back into people’s hands and let them decide. CAS may also be configured to present a menu of qualifying multifactor provider integrations for the authentication attempt, asking the user to choose one that makes the most sense. To enable the selection menu and remove ranking strategies, one would do this:


…which may result into this:


Selection Script

Sometimes, you need more control over the selection process; to account for external system behavior, other variables, etc. In situations like this, CAS allows you to script the selection logic via the magic of Groovy:


…and the script would be as:

import java.util.*

class SampleGroovyProviderSelection {
  String run(final Object... args) {
      def service = args[0]
      def principal = args[1]
      def providers = args[2]
      def logger = args[3]

      logger.info("Selecting a provider for ${principal} from ${providers}")
        Work out the selection process...
        Here, we are taking the easy route to return
        the very first provider available to us.
        You should do better.
      return providers.iterator().next().id


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 know that all other use cases, scenarios, features, and theories certainly are possible as well. Feel free to engage and contribute as best as you can.

Happy Coding,

Misagh Moayyed

Related Posts

CAS Vulnerability Disclosure

Disclosure of a security issue with the CAS software.

CAS Release Notes Moved

CAS Release Notes are moved to the CAS site.

CAS 6.2.0 RC5 Feature Release

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

CAS 6.2.0 RC4 Feature Release

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

CAS 6.2.0 RC3 Feature Release

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

Apereo CAS - Bootiful CAS Client

Easy to use CAS Client

CAS Vulnerability Disclosure

Disclosure of a security issue with the CAS software.

Checking Out Pull Requests Locally

Check out GitHub pull requests as local branches using a simple bash function.

CAS 6.2.0 RC2 Feature Release

...in which I present an overview of CAS 6.2.0 RC2 release.

Apereo CAS - Authentication Handler Resolution

Learn how to resolve and select authentication handlers based on configurable and flexible filtering criteria.