I updated the code to invalidate the cache before calling super and I am still 
seeing the same behavior.  It looks like on the second login the authentication 
interceptor is not getting called.  



First Login

INFO   | jvm 1    | 2017/12/10 08:55:11 | [08:55:11] INFO 
[com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
Intercepting bind operation
INFO   | jvm 1    | 2017/12/10 08:55:11 | [08:55:11] INFO 
[com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
Attempting to invalidate the cache for uid=admin,ou=system
INFO   | jvm 1    | 2017/12/10 08:55:11 | [08:55:11] INFO 
[com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
Executing parent level bind events first
INFO   | jvm 1    | 2017/12/10 08:55:11 | [08:55:11] INFO 
[com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
Executing custom bind events
INFO   | jvm 1    | 2017/12/10 08:55:11 | [08:55:11] INFO 
[com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - Done 
with custom bind action, calling next operation
INFO   | jvm 1    | 2017/12/10 08:55:11 | [08:55:11] INFO 
[com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
Intercepting bind operation
INFO   | jvm 1    | 2017/12/10 08:55:11 | [08:55:11] INFO 
[com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
Attempting to invalidate the cache for 
uid=justin.isenh...@compass-usa.com,ou=CommittedMembers,ou=people,dc=test,dc=com
INFO   | jvm 1    | 2017/12/10 08:55:11 | [08:55:11] INFO 
[com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
Executing parent level bind events first
INFO   | jvm 1    | 2017/12/10 08:55:11 | [08:55:11] INFO 
[com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
Executing custom bind events
INFO   | jvm 1    | 2017/12/10 08:55:11 | [08:55:11] INFO 
[com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
Attempting to validate status attribute for uId justin.isenh...@compass-usa.com
INFO   | jvm 1    | 2017/12/10 08:55:11 | [08:55:11] INFO 
[com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
Status for justin.isenh...@compass-usa.com is active
INFO   | jvm 1    | 2017/12/10 08:55:11 | [08:55:11] INFO 
[com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
Attempting to validate pwdResetattribute for uId justin.isenh...@compass-usa.com
INFO   | jvm 1    | 2017/12/10 08:55:11 | [08:55:11] INFO 
[com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
pwdReset for justin.isenh...@compass-usa.com is FALSE
INFO   | jvm 1    | 2017/12/10 08:55:11 | [08:55:11] INFO 
[com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
Attempting to invalidate the cache for 
uid=justin.isenh...@compass-usa.com,ou=CommittedMembers,ou=people,dc=test,dc=com
INFO   | jvm 1    | 2017/12/10 08:55:11 | [08:55:11] INFO 
[com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
Attempting to set lastLogon attribute for uId justin.isenh...@compass-usa.com
INFO   | jvm 1    | 2017/12/10 08:55:11 | [08:55:11] INFO 
[com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
lastLogon should be set now
INFO   | jvm 1    | 2017/12/10 08:55:11 | [08:55:11] INFO 
[com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - Done 
with custom bind action, calling next operation
INFO   | jvm 1    | 2017/12/10 08:55:11 | [08:55:11] INFO 
[com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
Intercepting bind operation
INFO   | jvm 1    | 2017/12/10 08:55:11 | [08:55:11] INFO 
[com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
Attempting to invalidate the cache for uid=admin,ou=system
INFO   | jvm 1    | 2017/12/10 08:55:11 | [08:55:11] INFO 
[com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
Executing parent level bind events first
INFO   | jvm 1    | 2017/12/10 08:55:11 | [08:55:11] INFO 
[com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
Executing custom bind events
INFO   | jvm 1    | 2017/12/10 08:55:11 | [08:55:11] INFO 
[com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - Done 
with custom bind action, calling next operation
INFO   | jvm 1    | 2017/12/10 08:55:11 | [08:55:11] WARN 
[org.apache.directory.server.core.api.interceptor.context.FilteringOperationContext]
 - Requested attribute pwdLastSet does not exist in the schema, it will be 
ignored
INFO   | jvm 1    | 2017/12/10 08:55:11 | [08:55:11] WARN 
[org.apache.directory.server.core.api.interceptor.context.FilteringOperationContext]
 - Requested attribute pwdLastSet does not exist in the schema, it will be 
ignored


Modify status

INFO   | jvm 1    | 2017/12/10 08:55:35 | [08:55:35] INFO 
[com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
Intercepting bind operation
INFO   | jvm 1    | 2017/12/10 08:55:35 | [08:55:35] INFO 
[com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
Attempting to invalidate the cache for uid=admin,ou=system
INFO   | jvm 1    | 2017/12/10 08:55:35 | [08:55:35] INFO 
[com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
Executing parent level bind events first
INFO   | jvm 1    | 2017/12/10 08:55:35 | [08:55:35] INFO 
[com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
Executing custom bind events
INFO   | jvm 1    | 2017/12/10 08:55:35 | [08:55:35] INFO 
[com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - Done 
with custom bind action, calling next operation
INFO   | jvm 1    | 2017/12/10 08:55:42 | [08:55:42] INFO 
[com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
Intercepting bind operation
INFO   | jvm 1    | 2017/12/10 08:55:42 | [08:55:42] INFO 
[com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
Attempting to invalidate the cache for uid=admin,ou=system
INFO   | jvm 1    | 2017/12/10 08:55:42 | [08:55:42] INFO 
[com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
Executing parent level bind events first
INFO   | jvm 1    | 2017/12/10 08:55:42 | [08:55:42] INFO 
[com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
Executing custom bind events
INFO   | jvm 1    | 2017/12/10 08:55:42 | [08:55:42] INFO 
[com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - Done 
with custom bind action, calling next operation
INFO   | jvm 1    | 2017/12/10 08:55:46 | [08:55:46] INFO 
[com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
Intercepting modify operation
INFO   | jvm 1    | 2017/12/10 08:55:46 | [08:55:46] INFO 
[com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
Attempting to invalidate the cache for 
uid=justin.isenh...@compass-usa.com,ou=CommittedMembers,ou=people,dc=test,dc=com
INFO   | jvm 1    | 2017/12/10 08:55:46 | [08:55:46] INFO 
[com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
Executing parent level modify events first
INFO   | jvm 1    | 2017/12/10 08:55:46 | [08:55:46] INFO 
[com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
Executing custom modify events
INFO   | jvm 1    | 2017/12/10 08:55:46 | [08:55:46] INFO 
[com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
Attempting to invalidate the cache for 
uid=justin.isenh...@compass-usa.com,ou=CommittedMembers,ou=people,dc=test,dc=com


Second Login

INFO   | jvm 1    | 2017/12/10 08:56:47 | [08:56:47] INFO 
[com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
Intercepting bind operation
INFO   | jvm 1    | 2017/12/10 08:56:47 | [08:56:47] INFO 
[com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
Attempting to invalidate the cache for uid=admin,ou=system
INFO   | jvm 1    | 2017/12/10 08:56:47 | [08:56:47] INFO 
[com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
Executing parent level bind events first
INFO   | jvm 1    | 2017/12/10 08:56:47 | [08:56:47] INFO 
[com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
Executing custom bind events
INFO   | jvm 1    | 2017/12/10 08:56:47 | [08:56:47] INFO 
[com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - Done 
with custom bind action, calling next operation
INFO   | jvm 1    | 2017/12/10 08:56:47 | [08:56:47] WARN 
[org.apache.directory.server.core.api.interceptor.context.FilteringOperationContext]
 - Requested attribute pwdLastSet does not exist in the schema, it will be 
ignored
INFO   | jvm 1    | 2017/12/10 08:56:47 | [08:56:47] WARN 
[org.apache.directory.server.core.api.interceptor.context.FilteringOperationContext]
 - Requested attribute pwdLastSet does not exist in the schema, it will be 
ignored






Justin Isenhour | Lead Developer, Systems and Technology Group | Compass Group 
USA |  2400 Yorkmont Road | Charlotte, NC 28217 | 704.328.5804 | 
justin.isenh...@compass-usa.com




-----Original Message-----
From: Emmanuel Lécharny [mailto:elecha...@gmail.com] 
Sent: Friday, December 8, 2017 1:53 PM
To: users@directory.apache.org
Subject: Re: [Ext] Re: [ApacheDS] How to clear cached authentication on change 
of custom attribute

In the attached code, you invalidate the cache *after* the super.bind() call. 
That won't work. Invalidate the cache before.

Le 08/12/2017 à 19:32, Isenhour, Justin a écrit :
> Emmanuel,
> 
> I tried this but it doesn't seem to work.  I added the code you recommended, 
> when I login the first time I see the log statements showing the attempt to 
> invalidate the cache but when I try to login a second time my custom 
> authenticator is never invoked.  I also tried adding the modify event in an 
> attempt to invalidate the cache when the account is modified, I again see the 
> log entries showing the attempt to invalidate the cache but again when I try 
> to login I do not see my code getting called at all.  Any other suggestions.  
> Log entries below, updated code attached.
> 
> First Login
> 
> INFO   | jvm 1    | 2017/12/08 13:18:06 | [13:18:05] INFO 
> [com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
> Intercepting bind operation
> INFO   | jvm 1    | 2017/12/08 13:18:06 | [13:18:05] INFO 
> [com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
> Executing parent level bind events first
> INFO   | jvm 1    | 2017/12/08 13:18:06 | [13:18:05] INFO 
> [com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
> Executing custom bind events
> INFO   | jvm 1    | 2017/12/08 13:18:06 | [13:18:05] INFO 
> [com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
> Attempting to validate status attribute for uId 
> justin.isenh...@compass-usa.com
> INFO   | jvm 1    | 2017/12/08 13:18:06 | [13:18:05] INFO 
> [com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
> Status for justin.isenh...@compass-usa.com is active
> INFO   | jvm 1    | 2017/12/08 13:18:06 | [13:18:05] INFO 
> [com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
> Attempting to validate pwdReset attribute for uId 
> justin.isenh...@compass-usa.com
> INFO   | jvm 1    | 2017/12/08 13:18:06 | [13:18:05] INFO 
> [com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
> pwdReset for justin.isenh...@compass-usa.com is FALSE
> INFO   | jvm 1    | 2017/12/08 13:18:06 | [13:18:05] INFO 
> [com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
> Attempting to invalidate the cache for 
> uid=justin.isenh...@compass-usa.com,ou=CommittedMembers,ou=people,dc=test,dc=com
> INFO   | jvm 1    | 2017/12/08 13:18:06 | [13:18:05] INFO 
> [com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
> Attempting to set lastLogon attribute for uId justin.isenh...@compass-usa.com
> INFO   | jvm 1    | 2017/12/08 13:18:06 | [13:18:05] INFO 
> [com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
> lastLogon should be set now
> INFO   | jvm 1    | 2017/12/08 13:18:06 | [13:18:05] INFO 
> [com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
> Done with custom bind action, calling next operation
> INFO   | jvm 1    | 2017/12/08 13:18:06 | [13:18:06] INFO 
> [com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
> Intercepting bind operation
> INFO   | jvm 1    | 2017/12/08 13:18:06 | [13:18:06] INFO 
> [com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
> Executing parent level bind events first
> INFO   | jvm 1    | 2017/12/08 13:18:06 | [13:18:06] INFO 
> [com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
> Executing custom bind events
> INFO   | jvm 1    | 2017/12/08 13:18:06 | [13:18:06] INFO 
> [com.cga.aaims.ldap.apacheds.interceptor.AAIMSAuthenticationInterceptor] - 
> Done with custom bind action, calling next operation
> INFO   | jvm 1    | 2017/12/08 13:18:06 | [13:18:06] WARN 
> [org.apache.directory.server.core.api.interceptor.context.FilteringOperationContext]
>  - Requested attribute pwdLastSet does not exist in the schema, it will be 
> ignored
> INFO   | jvm 1    | 2017/12/08 13:18:06 | [13:18:06] WARN 
> [org.apache.directory.server.core.api.interceptor.context.FilteringOperationContext]
>  - Requested attribute pwdLastSet does not exist in the schema, it will be 
> ignored
> 
> 
> Second Login
> 
> INFO   | jvm 1    | 2017/12/08 13:19:00 | [13:19:00] WARN 
> [org.apache.directory.server.core.api.interceptor.context.FilteringOperationContext]
>  - Requested attribute pwdLastSet does not exist in the schema, it will be 
> ignored
> INFO   | jvm 1    | 2017/12/08 13:19:00 | [13:19:00] WARN 
> [org.apache.directory.server.core.api.interceptor.context.FilteringOperationContext]
>  - Requested attribute pwdLastSet does not exist in the schema, it will be 
> ignored
> 
> 
> Thanks,
> Justin Isenhour | Lead Developer, Systems and Technology Group | 
> Compass Group USA |  2400 Yorkmont Road | Charlotte, NC 28217 | 
> 704.328.5804 | justin.isenh...@compass-usa.com
> 
> 
> 
> 
> -----Original Message-----
> From: Emmanuel Lécharny [mailto:elecha...@gmail.com]
> Sent: Thursday, December 7, 2017 5:35 PM
> To: users@directory.apache.org
> Subject: Re: [Ext] Re: [ApacheDS] How to clear cached authentication 
> on change of custom attribute
> 
> 
> 
> Le 07/12/2017 à 22:34, Isenhour, Justin a écrit :
>> A couple of things I have noticed.  I am not able to access the 
>> authenticator, my custom interceptor extends AuthenticationInterceptor which 
>> has a collection of authenticators but that collection is private.  The 
>> other thing I have noticed is that if the user account in question is 
>> already cached then my custom bind event is never called, so changes made 
>> here would have no impact.  Thoughts?
> 
> Ah, right, my proposal was not crrect because you would have to have access 
> to an authenticator beforehand.
> 
> But you can somehow fetch one using the getAuthenticators() method, which is 
> public in the AuthenticationInterceptor parent class, iterate on each 
> authenticator and call the invalidateCache() method on each one.
> That should work (yeah, I know, kind of a hack...)
> 
> 
> --
> Emmanuel Lecharny
> 
> Symas.com
> directory.apache.org
> 

--
Emmanuel Lecharny

Symas.com
directory.apache.org

package com.cga.aaims.ldap.apacheds.interceptor;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.SimpleTimeZone;

import org.apache.directory.api.ldap.model.constants.SchemaConstants;
import org.apache.directory.api.ldap.model.entry.Attribute;
import org.apache.directory.api.ldap.model.entry.DefaultAttribute;
import org.apache.directory.api.ldap.model.entry.DefaultModification;
import org.apache.directory.api.ldap.model.entry.Entry;
import org.apache.directory.api.ldap.model.entry.Modification;
import org.apache.directory.api.ldap.model.entry.ModificationOperation;
import 
org.apache.directory.api.ldap.model.exception.LdapAuthenticationException;
import org.apache.directory.api.ldap.model.exception.LdapException;
import org.apache.directory.api.ldap.model.name.Dn;
import org.apache.directory.api.ldap.model.schema.AttributeType;
import org.apache.directory.server.core.api.CoreSession;
import org.apache.directory.server.core.api.DirectoryService;
import org.apache.directory.server.core.api.entry.ClonedServerEntry;
import 
org.apache.directory.server.core.api.interceptor.context.AddOperationContext;
import 
org.apache.directory.server.core.api.interceptor.context.BindOperationContext;
import 
org.apache.directory.server.core.api.interceptor.context.ModifyOperationContext;
import org.apache.directory.server.core.authn.AuthenticationInterceptor;
import org.apache.directory.server.core.authn.Authenticator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.cga.aaims.ldap.apacheds.AAIMSSchemaConstants;
import com.cga.aaims.ldap.apacheds.Status;


/**
 * Custom ApacheDS interceptor designed to bridge the gaps between the 
out-of-the-box 
 * features/functionality of ApacheDS and the business requirements of AAIMS.
 * 
 * <br><br>
 * 
 * <b>Add Operation:</b><br>
 * On add we will check to see if the user object already has the status 
attribute,
 * if not then we will add it with the default value of active.
 * If it does exist then we will leave it as is and move on.
 * 
 * <br><br>
 * 
 * <b>Bind Operation:</b><br>
 * On bind we will perform 3 different customs actions:<br>
 * <ol>
 * <li> 
 * <b>Check User Status:</b><br> 
 * Look for the status attribute and check to see if it is active or not. 
 * If active the user will be allowed, if not active then we will throw an 
LdapAuthenticationException. 
 * </li>
 * <li>
 * <b>Check Must Change Password Flag:</b><br>
 * Check the pwdReset attribute to see if the user is required to reset their 
password or not.
 * A value of true will force the user to go through the password reset process 
before they can 
 * successfully authenticate again. 
 * </li>
 * <li>
 * <b>Update Last Login Date:</b><br>
 * Set the lastLogonDate attribute for the user to the current time.  This 
attribute can then be used in 
 * audit process to disable user accounts that are not used within a certain 
time frame.
 * </li>
 * </ol>
 * 
 * 
 * @author Justin Isenhour
 *
 */
public class AAIMSAuthenticationInterceptor extends AuthenticationInterceptor {
        
        private static final Logger LOGGER = 
LoggerFactory.getLogger(AAIMSAuthenticationInterceptor.class);
        
        /** Admin session used for making modifications to the entry during 
authentication **/
        private CoreSession adminSession;
        
        
        
        /**
     * Initialize the interceptor and sets up an admin session that can be used 
in other 
     * event handlers to make modification to the entry. 
     */
        @Override
    public void init( DirectoryService directoryService ) throws LdapException {
        adminSession = directoryService.getAdminSession();
        super.init( directoryService );
    }
    

        /**
     * Intercepts the add operation in order to add the status attribute if it 
doesn't already exist.
     */
        @Override
        public void add(AddOperationContext addContext) throws LdapException {
                LOGGER.debug("Intercepting add operation");
                
                ClonedServerEntry entry = (ClonedServerEntry) 
addContext.getEntry();
                
                Attribute uIdAT = entry.get(SchemaConstants.UID_AT);
                boolean isStgBasicAccountObject = 
entry.hasObjectClass(AAIMSSchemaConstants.STG_BASIC_ACCOUNT_OBJECT_CLASS);
                if (isStgBasicAccountObject && null != uIdAT) {
                        String uId = uIdAT.getString();
                        
                        //set the status attribute value if needed
                        setStatusAttribute(uId, entry);
                        
                } else {
                        LOGGER.debug("This is not a user object or not one that 
extends stgBasicAccount, ignoring");
                }
                
                super.add(addContext);
        }
        
        
        /**
         * 
         * 
         * @param uId
         * @param entry
         * @throws LdapException
         */
        private void setStatusAttribute(String uId, ClonedServerEntry entry) 
throws LdapException {
                LOGGER.debug("Attempting to add status attribute to uId {}", 
uId);
                
                AttributeType statusAT;
                Attribute statusAttribute;
                
                statusAT = 
schemaManager.lookupAttributeTypeRegistry(AAIMSSchemaConstants.STATUS_AT);
                if (entry.get(statusAT) == null) {
                        LOGGER.debug("Status was null, defaulting to active");
                        statusAttribute = new DefaultAttribute(statusAT);
                        statusAttribute.add(Status.ACTIVE.status());
                        entry.add(statusAttribute);
                } else {
                        statusAttribute = entry.get(statusAT);
                        String status = statusAttribute.getString();
                        LOGGER.debug("Status attribute for {} has already been 
set to {}, leaving it alone", uId, status);
                }
        }
        
        
        /**
         * Intercepts the bind operation to check to see if the users account 
status it active or not.
         */
        @Override
        public void bind(BindOperationContext bindContext) throws LdapException 
{
                LOGGER.info("Intercepting bind operation");
                
                invalidateCache(bindContext.getDn());
                
                LOGGER.info("Executing parent level bind events first");
                super.bind(bindContext);
                
                LOGGER.info("Executing custom bind events");
                
                Entry entry = bindContext.getEntry();
                Attribute uIdAT = entry.get(SchemaConstants.UID_AT);
                String uId = uIdAT.getString();
                
                boolean isStgBasicAccountObject = 
entry.hasObjectClass(AAIMSSchemaConstants.STG_BASIC_ACCOUNT_OBJECT_CLASS);
                if (isStgBasicAccountObject && null != uIdAT) {
                        checkUserStatus(uId, entry);
                        checkMustChangePasswordFlag(uId, entry);
                        invalidateCache(bindContext.getDn());
                        
                        try {
                                setLastLogonAttribute(bindContext, uId, entry);
                        } catch (Exception e) {
                                LOGGER.error("Error setting last logon time for 
{}", uId, e);
                        }
                }
                
                
                LOGGER.info("Done with custom bind action, calling next 
operation");
                next(bindContext);
        }
        
        
        /**
         * Will attempt to get the status attribute for the LDAP object. 
         * If the attribute is not present then this logic will be ignored. 
         * If it is present and the value of it is anything other than active
         * then we will throw and LdapExecption.
         * 
         * @param uId - user id of the LDAP account
         * @param entry - LDAP entry object being evaluated
         * @throws LdapException Account is not active
         */
        private void checkUserStatus(String uId, Entry entry) throws 
LdapException {
                LOGGER.info("Attempting to validate status attribute for uId 
{}", uId);
                
                AttributeType statusAT;
                Attribute statusAttribute;
                
                statusAT = 
schemaManager.lookupAttributeTypeRegistry(AAIMSSchemaConstants.STATUS_AT);
                if (entry.get(statusAT) != null) {
                        statusAttribute = entry.get(statusAT);
                        String status = statusAttribute.getString();
                        
                        LOGGER.info("Status for {} is {}", uId, status);
                        
                        if (!Status.ACTIVE.status().equalsIgnoreCase(status)) {
                                throw new LdapAuthenticationException("Account 
is not active");
                        }
                        
                } else {
                        LOGGER.info("No status attribute was found for {}, 
continuing", uId);
                }
        }
        
        
        /**
         * Will attempt to get the pwdReset attribute for the LDAP object. 
         * If the attribute is not present then this logic will be ignored. 
         * If it is present and the value of it is true then we will throw 
         * an LdapExecption.
         * 
         * @param uId - user id of the LDAP account
         * @param entry - LDAP entry object being evaluated
         * @throws LdapException User must change password
         */
        private void checkMustChangePasswordFlag(String uId, Entry entry) 
throws LdapException {
                LOGGER.info("Attempting to validate pwdReset attribute for uId 
{}", uId);
                
                AttributeType pwdResetAT;
                Attribute pwdResetAttribute;
                
                pwdResetAT = 
schemaManager.lookupAttributeTypeRegistry(SchemaConstants.PWD_RESET_AT);
                if (entry.get(pwdResetAT) != null) {
                        pwdResetAttribute = entry.get(pwdResetAT);
                        String pwdReset = pwdResetAttribute.getString();
                        
                        LOGGER.info("pwdReset for {} is {}", uId, pwdReset);
                        
                        if (Boolean.valueOf(pwdReset)) {
                                throw new LdapAuthenticationException("User 
must change password");
                        }
                        
                } else {
                        LOGGER.info("No pwdReset attribute was found for {}, 
continuing", uId);
                }
        }
        
        
        /**
         * Will attempt to set the lastLogon attribute for the user to the 
current time
         * 
         * @param uId
         * @param entry
         * @throws Exception 
         */
        private void setLastLogonAttribute(BindOperationContext bindContext, 
String uId, Entry entry) throws Exception {
                LOGGER.info("Attempting to set lastLogon attribute for uId {}", 
uId);
                
                Dn bindDn = bindContext.getDn();
                List<Modification> mods = new ArrayList<Modification>();
                
                AttributeType lastLogonAT;
                Attribute lastLogonAttribute;
                SimpleDateFormat dateFormat = new 
SimpleDateFormat(AAIMSSchemaConstants.DATE_FORMAT);
                dateFormat.setTimeZone(new 
SimpleTimeZone(SimpleTimeZone.UTC_TIME, "UTC"));
                String currentTime = dateFormat.format(new Date());
                
                lastLogonAT = 
schemaManager.lookupAttributeTypeRegistry(AAIMSSchemaConstants.LAST_LOGON_AT);
                lastLogonAttribute = new DefaultAttribute(lastLogonAT);
                lastLogonAttribute.add(currentTime);
                
                Modification lastLogonTimeMod = new 
DefaultModification(ModificationOperation.REPLACE_ATTRIBUTE, lastLogonAT, 
currentTime);
        mods.add(lastLogonTimeMod);
                
        
        Attribute attrMods = lastLogonTimeMod.getAttribute();
        attrMods.getAttributeType();
        
                ModifyOperationContext bindModCtx = new 
ModifyOperationContext(adminSession);
        bindModCtx.setDn(bindDn);
        bindModCtx.setEntry(entry);
        bindModCtx.setModItems(mods);
        bindModCtx.setPushToEvtInterceptor(true);

        directoryService.getPartitionNexus().modify(bindModCtx);
                
                LOGGER.info("lastLogon should be set now");
        }
        
        
        
        public void modify( ModifyOperationContext modifyContext ) throws 
LdapException {
                LOGGER.info("Intercepting modify operation");
                
                invalidateCache(modifyContext.getDn());
                
                LOGGER.info("Executing parent level modify events first");
                super.modify(modifyContext);
                
                LOGGER.info("Executing custom modify events");
                invalidateCache(modifyContext.getDn());
        }
        
        
        
        private void invalidateCache(Dn dn) {
                LOGGER.info("Attempting to invalidate the cache for {}", 
dn.getName());
                for ( Authenticator authenticator : this.getAuthenticators() ) {
                        authenticator.invalidateCache(dn);
                }
        }
        
}

Reply via email to