Apereo CAS - Have you been pawned?


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.

Have I been pwned is an online service that tracks security breaches and other datalogs on the internet, allowing you to check if your passwords linked to an email have been compromised. This is a very simple method and does not guarantee that your stuff is safe, or will continue to be safe. It does, however, allow you to have an idea of when data linked to your accounts might have been exposed, and whether you changed (or not) your passwords since that point.

A CAS deployment, as an entity that can support username/password credentials, can be integrated with this service such that after the user logs in with a valid password, CAS may check it against the service API and present a page to the user notifying them if their password has been pwned suggesting they should change it, but allow them to continue.

This sort of thing is fairly simple to do in CAS and while there are a variety of ways to tap into the authentication flow, in this post we shall take advantage of the CAS authenticator post-processors supported by a Groovy script. Our starting position is based on the following:

Configuration

First, we are going to teach CAS about the Groovy script that is to contact the relevant APIs and check for a pawned password:

cas.authn.engine.groovyPostProcessor.location=file:/etc/cas/config/GroovyPostProcessor.groovy

Our script itself may look like this:

import org.apereo.cas.*
import org.apereo.cas.authentication.*
import org.apereo.cas.authentication.credential.*
import java.net.*

def run(Object[] args) {
    def builder = args[0]
    def transaction = args[1]
    def logger = args[2]

    def credential = transaction.getPrimaryCredential().get()
    def password = credential.password
    def passwordSha1 = password.digest('SHA-1').toUpperCase()
    
    /*
        Contact the API using the SHA-1 digest of the credential password.
        Parse through the results, check for matches and produce a warning 
        where appropriate.
     */

    if (passwordHasBeenPawned()) {
        builder.addWarning(new DefaultMessageDescriptor("password.pawned"))  
    }
}

def supports(Object[] args) {
    def credential = args[0]
    def logger = args[1]
    credential instanceof UsernamePasswordCredential
}

Of course, the CAS message/language bundle (typically custom_messages.properties file) should also contain the text for the warning code password.pawned:

password.pawned=Your password is commonly used. Go <a href="https://example.org">here</a> to change it.

Note that the script itself is automatically monitored and cached for changes, so feel free to tweak and update as often as needed to test your changes without restarting the CAS server environment.

Finale

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.

Misagh Moayyed

Related Posts

CAS 6.1.0 RC5 Feature Release

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

Apereo CAS - Handling Authentication Webflow Errors with Grace

Learn how to modify Apereo CAS to customize exception handling and produce localized error messages for your deployment.

Apereo CAS - Are We Logged In Yet?

Learn how to modify and extend a CAS deployment to determine whether an SSO session is still valid and tied to a user authentication session.

Apereo CAS - REST API Integrations

Learn how to integrate with CAS using its REST API to authenticate, exchange tickets and get access to user profiles and attributes.

CAS 6.1.0 RC4 Feature Release

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

Apereo CAS - Multifactor Provider Selection

Learn how to configure CAS to integrate with and use multiple multifactor providers at the same time. This post also reveals a few super secret and yet open-source strategies one may use to select appropriate providers for authentication attempts, whether automatically or based on a menu.

Apereo CAS - Dockerized Hazelcast Deployments

Learn how to run CAS backed by a Hazelcast cluster in Docker containers and take advantage of the Hazelcast management center to monitor and observer cluster members.

Apereo CAS - Configuration Security w/ Jasypt

Learn how to secure CAS configuration settings and properties with Jasypt.

CAS 6.1.0 RC3 Feature Release

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

Apereo CAS - Webflow Decorations

Learn how you may decorate the Apereo CAS login webflow to inject data pieces and objects into the processing engine for display purposes, peace on earth and prosperity of all mankind, etc. Mainly, etc.