LDAP Password Policy Enforcement

Table of Contents
Home
Overall Architecture
Authentication
Authentication Managers
Security Policy
TicketRegistry
Testing
Protocols
Advanced Features
Tutorials and HOWTOs
Troubleshooting
Services Management
Extensions
New Release
2/10/2010 – cas-server-support-ldap-pwd-expiration-3.3.5
  • Support for CAS 3.3.5
  • Added ability to calculate expiration date from last password change date
  • Active Directory support
  • Configuration moved from deployerConfigContext.xml to separate file in spring-configuration

There has been some discussion about password expiration, but the offered solutions so far haven't taken advantage of the password policy features built into modern LDAP servers (see draft-behera-ldap-password-policy-09)

These are the 4 scenarios I wanted to handle in CAS:

  • Password Warning – Display a warning message to users after login, but before redirect, that their password will expire in X days
  • Password Expired – The password has expired. Display a error message to the user and allow them to go the password reset system (the actual password reset mechanism is out-of-scope)
  • Account Disabled – The account has been disabled by an admin. Display error. The user must contact an admin to regain access.
  • Account Locked – The account has been locked automatically due to too many authentication failures. The user must wait a certain amoutn of time before attempting to login again.

Using Sun Directory Server or AD, 3 of the 4 can be detected via the error codes in the AuthenticationException and handled by the spring web-flow.

Scenario LDAP Code AD Sub Error Code(s) Description Additional Info
Password Expired 49 532 Invalid credentials password expired!
Account Disabled 53 533 701 Server is unwilling to perform Account inactivated. Contact system administrator.
Account Locked 19 775 Constraint violation Exceed password retry limit. Account locked.

The remaining scenario is a bit harder. The authentication succeeds, but we need to get extra information about the account. According to the draft policy, the LDAP server should send these in the LDAP control codes with the authentication. Since getting to those codes would likely mean changes to Spring-LDAP, I decided to build off of the code that Bart Ophelders & Johan Peeters did [here].

The code determines the user's expiration Date/Time (either by searching LDAP for that value or calculating it by adding the maximum password age to the the user's last password time) and searches LDAP for the number of days warning to give them (or uses a default value) If the time difference between now and the expiration time is less than the warning period, the Spring web-flow is interrupted and a warning message is shown.

Installation

(These instructions assume you are using a Maven 2 Overlay for your customizations.

  1. Download the latest CAS source from SVN
  2. Download cas-server-support-ldap-pwd-expiration-3.3.5.tar.gz
  3. Extract the tarball and put it in the CAS directory
  4. Go into cas-server-support-ldap-pwd-expiration and run `mvn pacakge install`
  5. edit your pom.xml and add the following dependancy:
    <!-- LDAP password expiration -->
            <dependency>
                <groupId>ldap-pwd-expiration</groupId>
                <artifactId>cas-server-support-ldap-pwd-expiration</artifactId>
                <version>3.3.5</version>
                <type>war</type>
            </dependency>
  6. Edit spring-configuration/passwordWarningcheck.xml for your site:
    <bean id="PasswordWarningCheckAction" class="org.jasig.cas.web.flow.PasswordWarningCheckAction">
    		<property name="passwordWarningCheck" ref="passwordWarningCheck" />
    	</bean>
    
    	<bean id="passwordWarningCheck" class="org.jasig.cas.adaptors.ldap.LdapPasswordWarningCheck">
    		<property name="searchBase" value="ou=People,DC=example,DC=edu" />
    		<property name="contextSource" ref="pwdCheckContextSource" />
    		<property name="filter" value="uid=%u" />
    		
    		<!-- Warn all users of expiration date regardless of warningDays value -->
    		<property name="warnAll" value="false" />
    		
    <!-- Date format for value from dateAttribute see http://java.sun.com/j2se/1.4.2/docs/api/java/text/SimpleDateFormat.html -->
    		<property name="dateFormat" value="yyyyMMddHHmmss'Z'" />
    		
    		<!-- Calculate expiration time based on the last password change time -->
    		<property name="warningCheckType" value="change" />
    		<!-- LDAP attribute that stores the last password change time -->
    		<property name="dateAttribute" value="passwordchangedtime" />
    		<!-- LDAP attribute that stores the user's personal setting for the number of days to warn before expiration -->
    		<property name="warningDaysAttribute" value="passwordwarningdays" />
    		<!-- LDAP attribute that stores the custom setting for the number of days a password is valid -->
    		<property name="validDaysAttribute" value="passwordexpiredays" />
    		
    		<!--  Use expiration time/date from LDAP server -->
    			<!--  <property name="warningCheckType" value="expire" /> -->
    			<!--  <property name="dateAttribute" value="passwordexpirationtime" /> -->
    			<!--  <property name="warningDaysAttribute" value="passwordwarningdays" /> --> 
    			
    		<!-- Typical ActiveDirectory Config options
    			<property name="contextSource" ref="pwdCheckContextSource" />
    			<property name="searchBase" value="ou=Accounts,DC=example,DC=edu" />
    			<property name="filter" value="samaccountname=%u" />
    			<property name="warnAll" value="false" />
    			<property name="dateFormat" value="ActiveDirectory" />	
    			<property name="warningCheckType" value="change" />
    			<property name="dateAttribute" value="pwdlastset" />
    			<property name="validDaysAttribute" value="maxPwdAge" />
    			<property name="warningDaysAttribute" value="passwordwarningdays" />
    			
    		 -->
    		
    		<!-- These values are used if warningDaysAttribute or validDaysAttribute are not found -->
    		<property name="warningDays" value="30" />
    		<property name="validDays" value="180" />
    </bean>
  7. if you've modified any of these files, make sure to compare the version include with this package to yours:
    • cas-servlet.xml
    • login-webflow.xml
    • messages.properties
    • protocol_views.properties
  8. Make sure that the following pages are added to your theme (and update their look to match your theme):
    • casAccountDisabledView.jsp
    • casAccountLockedView.jsp
    • casExpiredPassView.jsp
    • casWarnPassView.jsp
Testing

Just going to $SERVER/cas/login and authenticating is a valid test for expired passwords, disabled accounts and account lockout - however, that will not work for password expiration warnings. To test the warning, you need to request a Service Ticket. The Warning will pop up after the TGT is created, but before the ST is.

Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.