【发布时间】:2018-08-16 13:23:34
【问题描述】:
我正在尝试从 Java 枚举我们的 Active Directory 中的所有组。有很多,所以我在 1000 个结果后得到一个SizeLimitExceededException。我正在尝试使用PagedResultsControl,我的代码非常接近网络上的所有示例,并且它可以正常工作,因为它不再抛出SizeLimitExceededException,并返回许多匹配的结果指定的页面大小(前提是不大于 1000)。
但是,下一步是从响应中获取cookie并使用它来获取下一页,而我的问题是在调用@987654326之后上下文中没有PagedResultsResponseControl @。事实上getResponseControls() 返回null。
我进行了广泛搜索,似乎找不到其他人报告此问题,我几乎被困在这里。那么我做错了什么?为什么我没有PagedResultsResponseControl?
我们的域在 Windows Server 2016 上运行,我已将代码缩减为以下测试用例:
public class PagingTest {
public static void main(String[] args) throws Exception {
Hashtable<String, String> env = new Hashtable<>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.SECURITY_PRINCIPAL, "username");
env.put(Context.SECURITY_CREDENTIALS, "password");
env.put(Context.PROVIDER_URL, "ldap://campus.uni.ac.uk/DC=campus,DC=uni,DC=ac,DC=uk");
LdapContext adContext = new InitialLdapContext(env, null);
// Set up search controls.
SearchControls searchControl = new SearchControls();
searchControl.setSearchScope(SearchControls.SUBTREE_SCOPE);
String[] attributesToFetch = {"cn"};
searchControl.setReturningAttributes(attributesToFetch);
// Set up a paged search.
final int pageSize = 500;
byte[] cookie = null;
adContext.setRequestControls(new Control[]{
new PagedResultsControl(pageSize, Control.CRITICAL)
});
// Do the search.
int count = 0;
boolean finished = false;
while (!finished) {
NamingEnumeration<SearchResult> records
= adContext.search("OU=Groups", "objectClass=group", searchControl);
// Examine the page's results control response and act accordingly.
Control[] controls = adContext.getResponseControls();
if (controls != null) {
for (int i = 0; i < controls.length; ++i) {
if (controls[i] instanceof PagedResultsResponseControl) {
PagedResultsResponseControl prrc =
(PagedResultsResponseControl) controls[i];
cookie = prrc.getCookie();
if (cookie == null) {
finished = true;
}
}
}
} else {
cookie = null;
finished = true;
}
// Process the page of results.
while (records != null && records.hasMore()) {
SearchResult sr = records.next();
Attributes attribs = sr.getAttributes();
BasicAttribute ba = (BasicAttribute) attribs.get("cn");
String cn = (String) ba.get();
System.out.println(cn);
++count;
}
// Re-activate paged results with the new cookie.
adContext.setRequestControls(new Control[]{
new PagedResultsControl(pageSize, cookie, Control.CRITICAL)
});
}
System.out.println("Found " + count + " groups");
}
}
【问题讨论】:
-
@jwilleke 我的代码非常基于此代码以及其他 Oracle 教程页面。您认为我在改编它时是否犯了特定错误?
-
也许你根本没有得到任何结果,所以它不会费心返回控件。先尝试打印你的记录,看看你有什么。
-
@squarewav 查询返回了近 9,000 个组,正如我在问题中所述,服务器正在返回适合请求的页面大小的结果数量(在本例中为 500),并且测试代码正在打印出来。
-
我遇到了同样的问题并找到了答案:docs.microsoft.com/en-us/troubleshoot/windows-server/identity/… 上面的文档与我在 .NET 中看到的 LDAP 行为相匹配,并且还抛出了
error code 12 - 00000057日志并导致问题一个Java应用程序。切换到全局目录端口3269为 java 应用程序修复了它,但我还测试了在非根 OU 上禁用 ReferralChasing 和搜索(例如 OU=Users,DC=domain,DC=com 而不是 DC=domain,DC =com) 在 .NET 中也有效。
标签: java active-directory ldap jndi