Expired Password Integration

A password usually expires in a set period of time. For this example lets say my password will expire on April 1st 2007.

When I login using CAS during the last week of March, I would like to see a warning page informing me that my password will expire in the next seven days. If I choose I can click on a link that will bring me into my Account Management System ( AMS ). Here I can change my password. Or I can just go to the service I requested.

If I login on April 1st 2007, I am forced to change my password in the AMS. I will not be granted any access to any system until I do so.

It is possible that an account gets locked for some reason, abuse of service or violation of Terms of Use. When a user account is locked, I would like to provide a page informing them to contact the Administrator and receive their punishment.

---------------------------------------------------- 

Use case for attached classes (by Velpi):

There 5 distinct states for an account and one error status that may occur while processing (defined by the Spring action that is configured in the webflow). 

  • activate: every account is in the activate status at first. This means the user still needs to activate its account at the AMS. At this point the user cannot log in yet. Since the user is unable to authenticate itself using a password at this point, this status may be obsolete to the login system. However x509 logins may be allowed (company policy). Activation is usually done using a special one-time activation code that the user physically receives at the administration of the organisation. (this procedure can be done again at any time, which is useful when the user loses its password). An activation code should be seen as a random initial password that can only be used to activate the account. The main reason for this state is so the user can create its own password without anyone else ever having to know its (temporary or initial) password.
  • active: normal account state. User can just pass the login system without any further interaction.
  • changepwd: user is near to account expiry. He should be bothered with a warning screen (preferably once, at initial login) that contains a link to the AMS-changepwd. The user can choose to follow the link or ignore the message for now and continue.
  • locked: the user account's password has expired since he did not change its password on time. In order to use the system the password needs to be changed immediately (or re-activate the account; depending on company policy). So there should be a warning screen that cannot be bypassed. The screen will inform the user what to do next (probably contains some links).
  • blocked: the user has been detected with illegal/unwanted behaviour. All further access is blocked immediately. He/she can only re-activate its account after visiting the administration office which will ask the user for an explanation of its conduct.
  • error: an error occurred while looking up the account status. Access should probably be blocked, depending on company policy.

If this check is implemented as a Spring action, then the login-webflow can easily be configured so redirecting/blocking behaves according to company policy.

The status information of the account may be one of the following (implementation of an AccountStatusGetter):

  • direct attribute from a data-store (eg: SimpleLDAPAccountStatusGetter: information is pushed from external source)
  • calculation based on a (combination of) attributes from data-store, eg: AD accountExpiry (and...)
  • a (combination of) locally calculated/retrieved attributes, eg: client IP, time-of-day, ...

    

-------------------------

Questions asked by Chris Roffler 

  • Q:It is not clear to me if you are going to provide the screens to change the password ?
    (Velpi) Forms to actually change the password should be a separate project, most campuses have such a page at the moment so it is less urgent.
  • Q: If I understand this right, you will base the error conditions on an attribute in LDAP ?
    (Velpi) Using error conditions may be a good, standard implementation strategy. However it prevents authenticating the user before fetching THIS user's attributes and using them for the correct response.
  • Q: Are you going to let me set the LdapAccountStatusGetter like you do with the authenticationHandler and how do you guys plan to use this StatusGetter class within CAS ?
    For example, I am using Sun One Directory Server, I can set all those parameters ( Password expiration, length, reuse etc )system wide and when I try to authenticate on the connection I get an error. from there I could map the error to the cas pre defined errors.
    (Velpi) The interpreter needs to be configurable. But I'm not sure it is wise to connect it to the authenticationHandler. This would also limit its use only at authentication time and to the same backend.

-------------------------

Questions and remarks added by marc-antoine garrigue

We had (nearly) the same requirements :

  • We needed to deal with and distinguishes account and password status
    • Account locked, disabled
    • Password expired, must change.
  • We needed to handle and distinguishes both Active Directory and SUNOne LDAP as authentication source
  • We do not need to provide 'near expiration date' status
  • We need to redirect to a request password webflow when password expiration status arrise from the LDAP source (but not from AD)

But our implementation strategy was very different :

  • We customize our ldap authentication handler in order to get the backend exception during the bind or search.
  • We develop custom exception handlers for AD and SUNOne
  • We customize the login web flow in oder to deal with our ExpiredPasswordException extending AuthenticationException

Questions :

  • How do the AccountStatusGetter integrate in the login flow : before or after the authentication?
    (Velpi) The AccountStatusAction is a standard Spring action that can be configured anywhere in the login flow. It seems reasonable to put it right AFTER authentication but before setting the TGT cookie. Else you could start "mining" account statusses. Optionally you may want to configure this action to be triggered also when a user passes by while having a TGT.
    Please also consider multiple authentication sources, eg: LDAP and x509 at the same time. Both sources need to result in the account being checked for validity (though x509 does not require a password  expiry check, it may need the blocked check). Spring webflow makes this all possible.
  • Wouldn't it be groovy to add the AccountStatusGetter as a service available in the AuthenticationHandler?
    (Velpi) It may limit its flexibility. The PrincipalResolver is also separate from the AuthenticationHandler, and it works great.

 My2c

  • Adding an AccountStatusGetter to the AuthenticationHandler may provide the benefit of re-using connections. However

-------------------------

Summary so far (please edit this!):

Common:

  • account statusses: active, locked, must change
  • configurable backend, preferrably depending on the authN (all LDAP clones up to now, SQL may be interesting to)
  • optional, forced redirection to a password change form OR showing page that has a link to such a page [can both be implemented as a view]
    Mentioned specific functionality:
  • statusses: activation, near to expiration date, blocked
    Implementation strategies:
  • direct access to a predefined status identifier as attribute
  • interpreting exceptions returned when authenticating to AD or SUNOne LDAP as the user (=connecting it to the authenticationHandler)
  • calculated from a list of attributes

-------------------------------------------------------------------------------

24-03-2009

By Bart Ophelders & Johan Peeters

We worked out the password expiration problem, starting from the code Jan van der Velpen wrote a few years back.

There are 5 different states, calculated from a pwLastChanged value (yyyy-MM-dd) fetched out of LDAP:

  • activate --> set pwLastChanged to 1900-01-01
  • active
  • changepwd --> warning page displayed a configurable amount of time before the password expiration date
  • locked --> expiration date has passed
  • blocked --> set pwLastChanged to a date before 1950

The activate and blocked states are defined in this way for convenience, but you can easily adapt the code to check i.e. for another value in LDAP.

The expiration check happens after the creation of the TGT but before the setting of the TGT cookie. (Thus after the action-state submit and before the action-state sendTicketGrantingTicket)

To use the code, add the following beans to deployerConfigContext.xml: 

deployerConfigContext.xml
<bean
                id="accountStatusAction"
                class="org.jasig.cas.web.flow.AccountStatusAction"
                p:accountStatusGetter-ref="accountStatusGetter"
        />
       
  <bean
                id="accountStatusGetter"
                class="org.jasig.cas.web.support.ExtendedLdapAccountStatusGetter"
                p:filter="cn=%u"
                p:statusAttributeName="description"
                p:searchBase="ou=People,dc=example,dc=be"
                p:contextSource-ref="contextSource"
                p:daysTillLocked="365"
                p:warningDays="30"
        />
                
<bean
                id="contextSource"
                class="org.jasig.cas.adaptors.ldap.util.AuthenticatedLdapContextSource"
                p:url="ldap://test.example.be:389"
                p:userDn="cn=IDP,dc=example,dc=be"
                p:password="secret">
                <property name="baseEnvironmentProperties">
                        <map>
                                <entry>
                                        <key>
                                                <value>java.naming.security.authentication</value>
                                        </key>
                                        <value>simple</value>
                                </entry>
                        </map>
                </property>
        </bean>
        <bean
                id="chooseChangepwdViaFormAction"
                class="org.jasig.cas.web.flow.ChooseChangepwdViaFormAction"
                />
</beans>


The code and login-webflow is added as an attachement.

Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.
  1. Jan 10, 2007

    Jan Van der Velpen says:

    I added some of the classes I am now working with as attachments.Note that the c...

    I added some of the classes I am now working with as attachments.Note that the classes contain a lot of mappings to make different implementation easy.

    This implementation just grabs the information from an LDAP. The simple implementation can be used if the LDAP is populated with an attribute that defines the account status information. A more advanced implementation may calculate the status by using multiple attributes (eg when x days before the date in the "expiry" attribute and not blocked => show warning screen to change pwd).

    Note that the abstract base class fixes the status types... 

    disclaimer: this is initial code that is not meant for production

  2. Jan 22, 2007

    Vladimir Gleiberman says:

    I always advocated a point that CAS should provide full login/password maintenan...

    I always advocated a point that CAS should provide full login/password maintenance.

    So, when "password expired" situation is detected, "Change Password" screen should be provided by CAS.

    And as soon as this screen and functionality is available we can easily implement "I want to change my password" service as well.

  3. Feb 05, 2007

    Stephen More says:

    What steps do we need to take to move forward with implementing this ?

    What steps do we need to take to move forward with implementing this ?

  4. Apr 24, 2007

    Chris Roffler says:

    I would like to bring this one alive again \! &nbsp;Is there a plan for this iss...

    I would like to bring this one alive again !

     Is there a plan for this issue ?

  5. Sep 06, 2007

    Dan Biondi says:

    Has there been any further activity regarding this issue?

    Has there been any further activity regarding this issue?

  6. Nov 07, 2007

    Amir Kibbar says:

    I would like to know if anyone is advancing this issue? I'd very much like to us...

    I would like to know if anyone is advancing this issue? I'd very much like to use all the features described here

    1. Mar 23

      Bart Ophelders says:

      We are working on this issue for our master thesis. Updates will follow soon.

      We are working on this issue for our master thesis. Updates will follow soon.

      1. Mar 23

        Scott Battaglia says:

        If you're looking at this issue, it may help to look into what we've been doing ...

        If you're looking at this issue, it may help to look into what we've been doing in CAS4.

        1. Mar 24

          Jan Van der Velpen says:

          I (Velpi) am guiding these students for their master thesis. They have done a ni...

          I (Velpi) am guiding these students for their master thesis. They have done a nice job implementing this for CAS3. Their goal in the paper is to compare this to what should be present in CAS4. (the paper will be in Dutch, unfortunately)

          Unfortunately there is no time left to actually implement CAS4 in the same way as they did with CAS3.

          Maybe some of the concepts of their implementation can still be useful for CAS4? In any case, these classes are easy to 'plug in' with minor patches on a CAS3 system. Depending on how fast CAS4 will be production-level code, I would be very happy to see this included in the JA-SIG CAS3 packages. Note that this implementation contains an abstract class that can easily have several different pluggable implementations.

  7. Jul 15, 2008

    Florent Lartet says:

    Hello, I'm not sure password management should be made by CAS Server but in my m...

    Hello,
    I'm not sure password management should be made by CAS Server but in my mind, CAS should be able to understand more than
    "Yes I know this guy, take a ticket" ; "No, I don't know him"
    It should be able to redirect users according to user's password state.

    In this way, why don't follow the ppolicy overlay provided by OpenLDAP ? I think it will become a standard in the LDAP world.