I'm trying to work out if I've found a bug in Ldaptive or CAS5's use of it.
We use CAS security which uses Ldaptive and it's configured to use a BlockingConnectionPool and validate connections on checkout.
To log a user in, Ldaptive first validates the connection using a SearchValidator and ends up calling JndiConnection.simpleBind(). That sets a username and password on the connection's context by calling context.addToEnvironment().
The next time we log in using the same connection from the pool, it goes through the same process. However this time the SearchValidator fails, it seems, because the connection still has the credentials from the previous failed simpleBind attempt in its environment map and so it can't connect to LDAP.
It fails at the LdapContext.search() call in JndiConnection$JndiSearchIterator.search().
It seems like JndiConnection.simpleBind() should restore the previous credentials because the rest of the code isn't expecting that to change. The anonymouseBind() method would be affected too.
public static PoolConfig newPoolConfig(final AbstractLdapProperties l) {
final PoolConfig pc = new PoolConfig();
pc.setMinPoolSize(l.getMinPoolSize());
pc.setMaxPoolSize(l.getMaxPoolSize());
pc.setValidateOnCheckOut(l.isValidateOnCheckout());
pc.setValidatePeriodically(l.isValidatePeriodically());
pc.setValidatePeriod(newDuration(l.getValidatePeriod()));
return pc;
}
public static ConnectionPool newBlockingConnectionPool(final AbstractLdapProperties l) {
final DefaultConnectionFactory bindCf = newConnectionFactory(l);
final PoolConfig pc = newPoolConfig(l);
final BlockingConnectionPool cp = new BlockingConnectionPool(pc, bindCf);
cp.setBlockWaitTime(newDuration(l.getBlockWaitTime()));
cp.setPoolConfig(pc);
final IdlePruneStrategy strategy = new IdlePruneStrategy();
strategy.setIdleTime(newDuration(l.getIdleTime()));
strategy.setPrunePeriod(newDuration(l.getPrunePeriod()));
cp.setPruneStrategy(strategy);
cp.setValidator(new SearchValidator());
cp.setFailFastInitialize(l.isFailFast());
LOGGER.debug("Initializing ldap connection pool for {} and bindDn {}", l.getLdapUrl(), l.getBindDn());
cp.initialize();
return cp;
}
and here's the top of the stacktrace of the error :
org.ldaptive.pool.ValidationException: Validation of connection failed
at org.ldaptive.pool.AbstractConnectionPool.activateAndValidateConnection(AbstractConnectionPool.java:633) ~[ldaptive-1.2.0.jar:?]
at org.ldaptive.pool.BlockingConnectionPool.getConnection(BlockingConnectionPool.java:151) ~[ldaptive-1.2.0.jar:?]
at org.ldaptive.pool.PooledConnectionFactory.getConnection(PooledConnectionFactory.java:68) ~[ldaptive-1.2.0.jar:?]
at org.ldaptive.auth.PooledBindAuthenticationHandler.getConnection(PooledBindAuthenticationHandler.java:61) ~[ldaptive-1.2.0.jar:?]
at org.ldaptive.auth.AbstractAuthenticationHandler.authenticate(AbstractAuthenticationHandler.java:54) ~[ldaptive-1.2.0.jar:?]
at org.ldaptive.auth.Authenticator.authenticate(Authenticator.java:257) ~[ldaptive-1.2.0.jar:?]