Apereo CAS - Simple Multifactor Authentication

Posted by Misagh Moayyed on January 31, 2022 · 9 mins read ·


The Apereo CAS portfolio presents support for an impressive number of multifactor authentication providers out of the box. One such option is to remove dependencies to an external vendor integration and let the CAS server itself become a provider. This is a rather simplified multifactor authentication solution where after primary authentication, CAS begins to issue time-sensitive tokens to end-users via pre-defined communication channels such as email or text messages.

In this tutorial, we are going to briefly review the steps required to turn on Simple Multifactor Authentication.

Our starting position is based on:


Prepare your CAS overlay with the correct auto-configuration module. Next, we will first instruct CAS to trigger simple mfa for all requests and applications:


Why All?
This is done to keep things simple for purposes of this blog post. You are of course welcome to choose any multifactor trigger that works best for you. It should work all the same.

Then, let’s choose email as our preferred communication mechanism for sharing tokens. To do so, let’s teach CAS about our email server:

Why Spring?
Settings and properties that are directly controlled by the CAS platform always begin with the prefix cas. All other settings are controlled and provided to CAS via other underlying frameworks and may have their schemas, syntax and validation rules. In this case, the presence of the above settings will instruct Spring Boot to create the required components internally for sending an email and make them available to CAS.

Then, let’s instruct CAS to share tokens via email:


cas.authn.mfa.simple.mail.subject=CAS MFA Token
cas.authn.mfa.simple.mail.text=Hello! Your requested CAS token is %s


A few things to note:

  • The %s acts as a placeholder for the generated token in the body of the message.
  • The expiration of the generated token is set to 30 seconds.
  • User email addresses are expected to be found under a mail attribute. In this example, this is done as a static attribute via the stub attribute repository configuration.

At this point, we should be ready to test.


Once you build and bring up the deployment, let’s simulate an authentication attempt from a made-up application, https://app.example.org, by submitting the following request:


After authentication, you should see the following entries in the CAS log:

- <Added ticket [CASMFA-004291] to registry.>
- <Successfully submitted token via SMS and/or email to [misagh]>

The screen should ask for the token:

image If you check your email, you should have received a token:


Submit the generated token CASMFA-004291 back to CAS and you should be allowed to proceed.

Token Generation

To control the length of the generated token, use:

# cas.authn.mfa.simple.token-length=6

You can take direct control of the token generation logic by designing your own configuration component with the following bean in place:

public UniqueTicketIdGenerator casSimpleMultifactorAuthenticationUniqueTicketIdGenerator() {
    return new MyUniqueTicketIdGenerator();

Implement the MyUniqueTicketIdGenerator as you see fit or better yet, use the GroovyUniqueTicketIdGenerator instead to hand off the implementation to an external Groovy script with the following body:

def run(Object... args) {
    def prefix = args[0]
    def logger = args[1]
    return ...

You can also control the token validation logic by supplying the following bean that should respond to credentials of type CasSimpleMultifactorTokenCredential:

public AuthenticationHandler casSimpleMultifactorAuthenticationHandler() {
    return ...

Rate Limiting

By default, if the user keeps asking for tokens without actually using them, CAS will continue to send the same unused token to the user so long as the token continues to be valid. This provides a useful defensive measure against too many token requests, but you may want to control the rate of the submitted requests as well. This can be done by forming a rate-limiting configuration plan to limit the number of requests:




We are allowed to define multiple rate-limting plans. For example, the above configuration handles requests in blocking mode, which means the client request will be blocked until resources eventually become available. Our plan allows for 100 requests per minute, but not no more often than 60 tokens per 5 seconds.

Specifying multiple bandwidths and configuration plans may be a very useful technique in protecting against clever attacks. For example, Bucket4j documentation provides the following scenario:

Suppose that you start with a limit of 10000 tokens / per 1 hour per user. A malicious attacker may send 9999 request within 10 seconds. This would correspond to 100 request per second which could seriously impact the system. A skilled attacker could stop at 9999 request per hour, and repeat every hour, which would make this attack impossible to detect because the limit would not be reached. For additional details, please visit the Bucket4j reference documentation.

Need Help?

If you have questions about the contents and the topic of this blog post, or if you need additional guidance and support, feel free to send us a note and ask about consulting and support services.


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