Problem- I am using JNDI to connect to ldap active directory, and i want to search for users with the name contains the search string,. Its very slow.
my search method is as follows:
public static List<LDAPUser> searchContactsByName( ExtendedDirContext extendedDirContext, String name) { try { LdapContext ldapContext = extendedDirContext.getLdapContext(); String searchBaseStr = extendedDirContext.getSearchBase(); String sortKey = LDAPAttributes.NAME; ldapContext.setRequestControls(new Control[] { new SortControl( sortKey, Control.CRITICAL) }); SearchControls searchCtls = new SearchControls(); searchCtls.setTimeLimit(1000 * 10); String returnedAtts[] = { LDAPAttributes.USER_NAME, LDAPAttributes.NAME }; searchCtls.setReturningAttributes(returnedAtts); searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE); String searchFilter = "(&(ObjectCategory=person)(cn=*" + name + "*))"; NamingEnumeration<SearchResult> results = ldapContext.search( searchBaseStr, searchFilter, searchCtls); List<LDAPUser> users = new ArrayList<LDAPUser>(0); while (results.hasMoreElements()) { SearchResult sr = (SearchResult) results.next(); Attributes attrs = sr.getAttributes(); LDAPUser user = new LDAPUser(); user.setName(attrs.get(LDAPAttributes.NAME).toString() .replace("cn: ", "")); user.setUserName(attrs.get(LDAPAttributes.USER_NAME).toString() .replace("sAMAccountName: ", "")); users.add(user); } return users; } catch (Exception e) { e.printStackTrace(); return null; } }
connection to ldap:
public static ExtendedDirContext connectToLdap(MessageSource messageSource) { try { log.debug("connectToLdap"); String providerUrl = messageSource.getMessage("provider.url", null, null); String securityPrincipal = messageSource.getMessage( "security.principal", null, null); String securityCredentials = messageSource.getMessage( "security.credentials", null, null); String searchBase = messageSource.getMessage("search.base", null, null); boolean ssl = Boolean.parseBoolean(messageSource.getMessage("ssl", null, null)); LdapContext ldapContext; Hashtable<String, String> ldapEnv = new Hashtable<String, String>( 11); ldapEnv.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); ldapEnv.put(Context.PROVIDER_URL, providerUrl); ldapEnv.put(Context.SECURITY_AUTHENTICATION, "simple"); ldapEnv.put(Context.SECURITY_PRINCIPAL, securityPrincipal); ldapEnv.put(Context.SECURITY_CREDENTIALS, securityCredentials); if (ssl) ldapEnv.put(Context.SECURITY_PROTOCOL, "ssl"); // To get rid of the PartialResultException when using Active // Directory ldapEnv.put(Context.REFERRAL, "follow"); ldapContext = new InitialLdapContext(ldapEnv, null); ExtendedDirContext extendedDirContext = new ExtendedDirContext(); extendedDirContext.setLdapContext(ldapContext); extendedDirContext.setSearchBase(searchBase); log.debug("success connection to ldap"); return extendedDirContext; } catch (Exception e) { e.printStackTrace(); return null; } }
ldap credentials:
provider.url=ldap://abc.techartifact.com:389 security.principal=CN=administrator,CN=Users,DC=techartifact,DC=com security.credentials=password search.base=dc=techartifact,dc=com
its very difficult to understand why the search takes too much time to retrieve the data.
Solution -To change
ldapEnv.put(Context.REFERRAL, "follow"); to ldapEnv.put(Context.REFERRAL, "ignore");
Happy coding with Vinay in techartifact…