Reputation: 1013
I am using spring-security-ldap-3.2.9, spring-ldap-core-1.3.2.
Intermittently we face ldap hangups where it takes more than 2 minutes. Implementing without spring framework has no issues.
Is this a known issue or some configuration that I am missing.
Upvotes: 0
Views: 1756
Reputation: 104
I experienced almost exactly this issue. The solution was to remove referral follow from the LdapContextSource. Fixed XML config is shown at the end of the answer.
Watching the code in VisualVM most of the execution time was spent in AbstractLdapNamingEnumeration.hasMore(). This led me to NamingEnumeration hasMoreElements method takes a lot of time when returning false for LDAP and I realized it was trying to follow referrals but I didn't need that. Turning it off got rid of the pauses.
<bean id="ldapContextSource"
class="org.springframework.ldap.core.support.LdapContextSource">
<property name="url" value="$ad{ldap.protocol}://$ad{ldap.server}:$ad{ldap.port}" />
<property name="base" value="${ldap.base}" />
<property name="userDn" value="$ldap{user}" />
<property name="password" value="$ldap{password}"/>
<!-- <property name="referral" value="follow" /> -->
<property name="baseEnvironmentProperties">
<map>
<entry key="java.naming.ldap.attributes.binary">
<value>objectSid</value>
</entry>
</map>
</property>
</bean>
Upvotes: 1
Reputation: 1013
I really could not find the reason behind as this was happening inside the framework and I could not edit any code.
Finally i switched my implementation back to plain LDAP implementation with Java without spring and it works fine so far.
Upvotes: 1
Reputation: 355
It sounds like an issue with connection pooling. Assuming your service has a dedicated principal that uses a persistent connection (e.g. for user lookups), then it may be attempting to perform queries on a stale connection. If a pool has not been configured to routinely validate those connections, then it may be relying solely on timeouts to determine that a connection needs to be reestablished.
Spring LDAP supports the Apache Commons Pool which has built-in connection validation and maintenance configuration options (see section 9.1 in the reference docs). Enabling the testOnBorrow
and testWhileIdle
options on the pooled ContextSource tend to do a good job of evicting stale connections with minimal configuration. If you are using pooling then consider updating to spring ldap 2.1+ if possible, which introduces support for Apache Commons Pool 2.
The LDAP server will also have its own timeout settings in which it drops its end of the connection after a certain idle duration. Any connections created by your service should have an idle timeout that is less than the idle timeout on the LDAP server side. This will preemptively drop idle connections before hitting the LDAP server timeout, forcing a new connection to be established the next time the respective principal needs to communicate with the LDAP server.
Upvotes: 1