LDAP Password Policy Enforcement (LPPE)

New CAS documentation site

CAS documentation has moved over to jasig.github.io/cas, starting with CAS version 4.x. The wiki will no longer be maintained. For the most recent version of the documentation, please refer to the aforementioned link.

Password Management

 LPPE is not about password management and self-service account maintenance. If you are looking for that sort of capability integrating with CAS, you might be interested in this project instead.

Background

The purpose of the LPPE module is to detect a number of scenarios that would otherwise prevent user authentication, specifically using an Ldap instance as the primary source of user accounts.

These scenarios are currently supported by the module:

Ldap Error CodeLdap Error DescriptionCAS Authentication Behavior
530Invalid login timeDisplays a message upon authentication that the user cannot login at the current time
533Account is disabledDisplays a message upon authentication that the account has been disabled and user would need to contact an administrator.
773Must change passwordDisplays a message upon authentication that the account password must be changed and provides a link to a self-service password management application.
775Account is lockedDisplays a message upon authentication that the account has been disabled and user would need to contact an administrator.
531Invalid workstationDisplays a message upon authentication that the user cannot login from the current workstation
701 OR 532Password has expired

Displays a message upon authentication that the account password has expired and provides a link to a self-service password management application.

Without LPPE in place, the above scenarios would be considered as errors that will prevent authentication in a very generic way through the normal CAS login flow. LPPE intercepts the authentication flow,
detecting the above standard error codes (that are returned as part of the Ldap response payload) . Error codes are then translated into proper messages in the CAS login flow and would allow the user
to take proper action, fully explaining the nature of the problem. 
In addition, LPPE is also able to warn the user when the account is about to expire. The expiration policy is determined through pre-configured Ldap attributes with default values in place.
The "Configuration" section below provides additional options in better detail. 

 

ActiveDirectory vs. OpenLdap

Though the above table lists standard ldap error codes, LPPE has only been extensively tested against Active Directory. The functionality has yet to be tested and validated against an Open Ldap instance.

 

Source

The LPPE module ships with CAS by default as of CAS v3.5. The code is mostly a part of the Ldap module with additional configuration merged inside the CAS webapps module.

Configuration

LPPE is turned off by default. In order to configure the module with your account policy, please follow the below steps:

Maven Overlay

The instructions below assume you're using the Maven Overlay approach to build CAS.

 

  • In your POM.xml file, add the following dependencies:
<dependency>
     <groupId>org.jasig.cas</groupId>
     <artifactId>cas-server-support-ldap</artifactId>
     <version>${cas.version}</version>
</dependency>
 
<dependency>
     <groupId>commons-pool</groupId>
     <artifactId>commons-pool</artifactId>
     <version>${apache.commons.pool.version}</version>
</dependency> 

 

<bean class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" />

With this:

<ref bean="lppeEnabledLdapAuthenticationHandler" />

 

  • Download the correct lppe-configuration.xml file for the CAS version you're building and place it in the src/main/webapp/WEB-INF/spring-configuration directory of your maven overlay.
  • In the lppe-configuration.xml file, modify the "ldapErrorDefinitions" property to comment out the cases you are not interested in.
<property name="ldapErrorDefinitions">
         <list>
            <bean class="org.jasig.cas.adaptors.ldap.LdapErrorDefinition"
	             p:ldapPattern="data 530"
	             p:type="badHours" />
             <bean class="org.jasig.cas.adaptors.ldap.LdapErrorDefinition"
                 p:ldapPattern="data 533"
                 p:type="accountDisabled" />
             <bean class="org.jasig.cas.adaptors.ldap.LdapErrorDefinition"
                 p:ldapPattern="data 773"
                 p:type="mustChangePassword" />
             <bean class="org.jasig.cas.adaptors.ldap.LdapErrorDefinition"
                 p:ldapPattern="data 775"
                 p:type="accountLocked" />
             <bean class="org.jasig.cas.adaptors.ldap.LdapErrorDefinition"
                 p:ldapPattern="data 531"
                 p:type="badWorkstation" />
             <bean class="org.jasig.cas.adaptors.ldap.LdapErrorDefinition"
                 p:ldapPattern="data (701|532)"
                 p:type="passwordExpired" />
         </list>
</property>

 

  • Merge cas.properties.example from the LDAP module with the your maven overlay's cas.properties file and adjust the Ldap authentication settings. Specifically, configure your Ldap connection settings for the authentication handler through the properties below:
# == LDAP Authentication settings ==

#Example: sAMAccountName=%u
ldap.authentication.filter=sAMAccountName=%u

#Comma-separated list of server urls (i.e. ldap://1.2.3.4)
ldap.authentication.server.urls=ldaps://1.1.1.1

#Ldap Base DNs based on the context for query execution (i.e.
ldap.authentication.basedn=cn=users,dc=school,dc=edu

#Manager credentials to bind (i.e. cn=manager,cn=users,dc=school,dc=edu/password)
ldap.authentication.manager.userdn=
ldap.authentication.manager.password=

 

  • Specify your policy around password expiration behavior through the properties below, in the same file:
# ======================================================
# == LDAP Password Policy Enforcement (LPPE) settings ==
# ======================================================

#Warn all users of expiration date regardless of warningDays value
ldap.authentication.lppe.warnAll=false

#Date format for value from dateAttribute see http://java.sun.com/j2se/1.4.2/docs/api/java/text/SimpleDateFormat.html
#Change value to 'ActiveDirectory' or 'AD' when using AD
#ldap.authentication.lppe.dateFormat=yyyyMMddHHmmss'Z'
ldap.authentication.lppe.dateFormat=AD

#LDAP attribute that stores the last password change time
#Change value to 'pwdlastset' or 'lastlogon' when using AD
#ldap.authentication.lppe.dateAttribute=passwordchangedtime
ldap.authentication.lppe.dateAttribute=accountExpires

#The attribute that contains the data that will determine if password warning is skipped
ldap.authentication.lppe.noWarnAttribute=

#The list of values that will cause password warning to be bypassed
#If the value retrieved for the attribute above matches the elements defined below, password warning will be bypassed.
#LPPE automatically checks for 'never' used by ActiveDirectory
ldap.authentication.lppe.noWarnValues=

#LDAP attribute that stores the user's personal setting for the number of days to warn before expiration
ldap.authentication.lppe.warningDaysAttribute=passwordwarningdays

#LDAP attribute that stores the custom setting for the number of days a password is valid
#ldap.authentication.lppe.validDaysAttribute=passwordexpiredays
ldap.authentication.lppe.validDaysAttribute=maxPwdAge

#Default value used if warningDaysAttribute is not found
ldap.authentication.lppe.warningDays=30

#Default value used if validDaysAttribute is not found
ldap.authentication.lppe.validDays=90

#Url to which the user will be redirected to change the password
ldap.authentication.lppe.password.url=https://password.example.edu/change

 

<transition on="success" to="sendTicketGrantingTicket" />

With:

<transition on="success" to="passwordPolicyCheck" />

You may also want to do the same for the 'warn' state.

Test

To exercise the LPPE features, attempt to login to CAS using an account with an expired password, or one whose password is about to expire based on your policy settings. The login flow should switch you to a proper state indicating the nature of the problem. 

JIRA Issues

type key summary assignee reporter priority status resolution created updated due

Unable to locate Jira server for this macro. It may be due to Application Link configuration.