Search code examples
javatimeoutblockingnonblocking

Set method timeout on Ldap search


private Authentication authenticateUserPassword(UsernamePasswordAuthenticationToken token) throws NamingException {
    Object login = login(token);
    LOGGER.debug("Starting authentication login='{}'", login);
    Object password = token.getCredentials();

    LdapContext ctx = createLdapCtx(login, password);
    SearchControls ctrls = createSearchControls();
    String filter = String.format(this.filter, login);

    NamingEnumeration<SearchResult> ne = ctx.search(dn, filter, ctrls);
    ....

I have the folowing method to login user. It depends on LDAP. Sometimes it hangs on last row. I don't know why. It reproduces sometimes on performance tests.

Is there way to wait some time and if method didn't respond - return some predefined value ?

P.S.

private LdapContext createLdapCtx(Object login, Object password) throws NamingException {
    Hashtable<String, String> props = new Hashtable<String, String>();
    props.put(Context.INITIAL_CONTEXT_FACTORY, factory);
    props.put(Context.PROVIDER_URL, url);
    props.put(Context.SECURITY_AUTHENTICATION, "simple");
    props.put(Context.SECURITY_PRINCIPAL, String.format(domain, login));
    props.put(Context.SECURITY_CREDENTIALS, password.toString());

    return new InitialLdapContext(props, null);
}

Solution

  • You can set a time-out for all Ldap operations:

    The new environment property: com.sun.jndi.ldap.read.timeout can be used to specify the read timeout for an LDAP operation. The value of this property is the string representation of an integer representing the read timeout in milliseconds for LDAP operations.

    As such, you just need to update your createLdapCtx method to specify that environment variable to the value of your choice:

    props.put("com.sun.jndi.ldap.read.timeout", "1000"); // 1 second of timeout here
    

    This will cause the LDAP service provider to abort the read attempt if the server does not respond within 1 second. If the time-out is reached, a NamingException will be trown.


    Note that from this Stack Overflow post, you can't use the method SearchControls.setTimeLimit for this because this paramater does not apply for read timeouts.