java ldap 搜索很慢
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14136091/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ldap search is very slow
提问by Mahmoud Saleh
I am using JNDI to connect to the LDAP active directory, and I want to search for users where the name contains the search string, so my search method is as follows:
我使用JNDI连接LDAP活动目录,我想搜索名称中包含搜索字符串的用户,所以我的搜索方法如下:
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;
}
}
and here is how I am making the connection to LDAP:
这是我如何连接到 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;
}
}
The LDAP credentials are as follows:
LDAP 凭证如下:
provider.url=ldap://dc.fabrikam.com:389
security.principal=CN=administrator,CN=Users,DC=fabrikam,DC=com
security.credentials=password
search.base=dc=fabrikam,dc=com
Why does the search take so much time to retrieve the data? Is there any change that I can do to make the search faster, since I have only 285 contacts in the AD?
为什么搜索需要这么多时间来检索数据?由于我在 AD 中只有 285 个联系人,所以我可以做任何更改来加快搜索速度吗?
回答by Mahmoud Saleh
Solution was to change ldapEnv.put(Context.REFERRAL, "follow");
to ldapEnv.put(Context.REFERRAL, "ignore");
解决方案是更改ldapEnv.put(Context.REFERRAL, "follow");
为ldapEnv.put(Context.REFERRAL, "ignore");
回答by jwilleke
Your filter:
您的过滤器:
"(&(ObjectCategory=person)(cn=*" + name + "*))"
May be an issue.
可能是个问题。
I would recommend that you download a known LDAP utility (Apache Directory Studio Browser as an example) and try different search filters until you find one that works.
我建议您下载一个已知的 LDAP 实用程序(例如 Apache Directory Studio Browser)并尝试不同的搜索过滤器,直到找到一个有效的过滤器。
To Start, try
要开始,请尝试
"(&(ObjectCategory=person)(cn= + name ))"
回答by mertaksu
You're right,
你说得对,
ldapEnv.put(Context.REFERRAL, "ignore")
didn't get exception about connection timed out. But when I first try I get a partialexception. After I changed my LDAP configuration port from 389 to 3268 I didn't get any exception, build successfully. 3268 port about global catalog of LDAP. For example Outlook clients query the global catalog to locate Address Book information. You can try global catalog if you get an exception referral type setting.
没有得到关于连接超时的异常。但是当我第一次尝试时,我得到了一个部分异常。在我将 LDAP 配置端口从 389 更改为 3268 后,我没有遇到任何异常,构建成功。LDAP 全局目录的 3268 端口。例如,Outlook 客户端查询全局编录以定位通讯簿信息。如果您获得异常引用类型设置,则可以尝试全局编录。