• Skip to primary navigation
  • Skip to main content
  • Skip to primary sidebar
  • Skip to footer

Mister PKI

SSL Certificates * SSL Tools * Certificate Decoder

  • PKI Training
  • OpenSSL
  • Keytool
  • PKI Tools
    • Apereo CAS
    • SAML
    • OpenID Connect
  • Get expert help

Apereo CAS Custom Password Policy

January 15, 2025 by Mister PKI Leave a Comment

This article will demonstrate how to create a custom password policy in the Apereo CAS Identity Provider (IDP). This is their official documentation: https://apereo.github.io/cas/7.1.x/installation/Password-Policy-Enforcement.html. This article will not regurgitate the default password policy enforcement options provided in that documentation but rather demonstrate how to customize a unique password policy with a groovy script.

Authentication Handler properties

This section presumes you already have an authentication handler defined. In our example we are using an ldap authentication handler against Active Directory (AD). This example also uses a cas.groovy file instead of cas.properties so you will need to adjust your property syntax to fit your property file type.

cas.authn.ldap["0"].passwordPolicy.enabled="true"
cas.authn.ldap["0"].passwordPolicy.strategy="GROOVY"
cas.authn.ldap["0"].passwordPolicy.groovy.location="file:/etc/cas/config/groovy/password-policy.groovy"

The script we will write below makes use of the pwdLastSet attribute. CAS doesn’t treat this attribute as a principal attribute so it must be configured as an additional attribute.

cas.authn.ldap["0"].additionalAttributes="pwdLastSet"

Then, the additional attributes must be merged.

cas.authn.attributeRepository.core.merger="ADD"

Password Policy Groovy Script

The script blends Java with Groovy and should be modified to fit your specific use case. Please leave us a comment with improvements to the script. Note that its location should be the same as what was set in the previous section with the passwordPolicy.groovy.location property.

If you want to inspect the attributes being returned by your ldap authentication handler you can log or debug the response.ldapEntry object. This object is part of the ldaptive library.

Some key customizations of this script are as follows:

  • Use the pwdLastSet AD attribute and convert to a java Date
  • Compare this Date with the current date
  • Show an expiration warning after a user successfully logs in
    • DefaultMessageDescriptor returns the simple message screen
    • PasswordExpiringWarningMessageDescriptor is used to return a message with a days remaining variable
import java.util.*
import java.text.*
import java.time.ZoneId
import java.time.ZonedDateTime
import java.time.temporal.ChronoUnit
import org.ldaptive.auth.*
import org.apereo.cas.*
import org.apereo.cas.authentication.*
import org.apereo.cas.authentication.support.*
import org.apereo.cas.authentication.support.password.*
List<MessageDescriptor> run(final Object... args) {
    def (response,configuration,logger,applicationContext) = args
    logger.info("Handling password policy [{}] via ${configuration.getAccountStateHandler()}", response)
    def pwdLastSet = response.ldapEntry.getAttribute('pwdLastSet').getStringValue()
    long pwdSetDate = java.lang.Long.parseLong(pwdLastSet)
    long timeAdjust = 11644473600000L  // adjust factor for converting it to java
    Date pwdSet = new Date((pwdSetDate / 10000 - timeAdjust).toLong())
    now = ZonedDateTime.now()
    expirationDate = ZonedDateTime.ofInstant(pwdSet.toInstant(), ZoneId.systemDefault()).plusDays(365)
    days = ChronoUnit.DAYS.between(now.toLocalDate(), expirationDate.toLocalDate())
    if (now.toInstant().isAfter(expirationDate.toInstant())) {
        return [new DefaultMessageDescriptor("cas.custom.change.password")] as List<MessageDescriptor>
    } else if (now.toInstant().isAfter(expirationDate.minusDays(14).toInstant())) {
        return [new PasswordExpiringWarningMessageDescriptor("", days)] as List<MessageDescriptor>
    }
    def accountStateHandler = configuration.getAccountStateHandler()
    return accountStateHandler.handle(response, configuration)
}

Two custom messages are configured in src/main/resources/custom_messages.properties in your cas-overlay. Note that {0} is a variable and will be replaced with the number of days computed in the groovy script.

password.expiration.warning=Your password expires in {0} day(s). Please <a href="https://password.example.com">change your password</a> now or click Continue to proceed to the service you are logging in to.
cas.custom.change.password=<br/>Your password has expired. You must change your password now.

Conclusion – Apereo CAS Custom Password Policy

This article has demonstrated how to create a custom password policy to be enforced in Apereo CAS. Leave us a comment with any feedback or questions. If you found this article helpful, see more of our Apereo CAS articles.

Apereo CAS,  Identity Management

Reader Interactions

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Primary Sidebar

Popular Posts

PKCS12

openssl s_client

Keytool

Keytool list

ECDSA vs RSA

OpenSSL

PKCS7

Certificate Decoder

PKI for DevOps Engineers – Free Training Series

PKI for DevOps Training Hub

Lesson 1 – How TLS and PKI Work

Lesson 2 – Understanding X.509 Certificates

Lesson 3 – Certificate Chains Explained

Lesson 4 – Debug TLS with OpenSSL

Lesson 5 – Verify Certificate Chains

Lesson 6 – Creating CSRs with OpenSSL

Lesson 7 – Working with PKCS12 Certificates

Lesson 8 – Java Keystores and keytool

Lesson 9 – Certificate Expiration Monitoring

Lesson 10 – Automating Certificate Renewal

Lesson 11 – Common TLS Errors

Lesson 12 – PKI Architecture for DevOps

Recent Posts

  • Apache mod_auth_cas: Protect Web Applications with Apereo CAS and Docker
  • Apache mod_auth_mellon: Configure SAML SSO & Docker
  • Configure OpenID Connect (OIDC) in Apereo CAS 7.3 and 8
  • Certificate Ownership Is an Operating Model Problem, Not a Tooling Problem
  • OpenSSL dgst: Create Checksums and Verify Digital Signatures

Footer

  • Twitter
  • YouTube
Mister PKI

Practical security engineering for the systems that establish trust.

Learn OpenSSL Keytool Free training
Work together PKI consulting CAS consulting Sponsored contributions
Site About Support Mister PKI Cookie policy Search
© 2026 Mister PKI Secure systems. Clear guidance.