我使用了Apache Directory API从Active Directory加载用户数据。它类似于这个stackoverflow问题中“oers”的示例代码:
Apache Directory LDAP - Paged searches
我有一些不同之处:
我用Nashorn(Javascript在Java中运行)编写它
我使用的是PagedResultSimp类而不是PagedResultsDecorator
通过使用byte[]cookie的Base64编码,我将cookie保存为调用之间的字符串。
我正在使用Apache目录API和以下maven导入:
org.apache.directory.api
api-all
1.0.3
以下是一些重要的方面:
...
var pageCursor = ""; /** or some Base64 encoded byte[] cookie if I'm trying to start from where i left off last time. */
...
pagedSearchControl = new PagedResultsImpl();
pagedSearchControl.setSize(pageSize);
pagedSearchControl.setCookie(Base64.getEncoder().encodeToString(pageCursor.getBytes()));
...
var searchRequest = new SearchRequestImpl();
...
searchRequest.addControl(pagedSearchControl);
...
var cursor = new EntryCursorImpl(connection.search(searchRequest));
...
pagingResults = cursor.getSearchResultDone().getControl(PagedResults.OID);
if (pagingResults != null){
nextPageCursor = Base64.getEncoder().encodeToString(pagingResults.getCookie());
}
当遇到
活动目录
我可以呼叫所有用户
很好
. 当我将连接改为指向
OpenLDAP
我可以搜索用户的目录
很好
,
除了
因为当我使用pageCursor的非空值设置页控件cookie时(我从base 64获得的值,该值编码前一个调用的cookie)。基本上,
我无法从OpenLDAP获取页面结果
. 我没有结果,也没有例外。
需要什么才能使OpenLDAP正确地分页?
在Apache目录中设置页面控件时是否遗漏了一些内容?
我需要打开OpenLDAP中的分页设置吗?
[更新]
我在Nashorn之外将代码移植到Java中,现在我可以看到这是因为分页cookie似乎是
仅在同一连接内有效
对于OpenLDAP,但是对于Active Directory,它可以是不同的连接。你可以看到下面的代码
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Base64;
import java.util.Iterator;
import java.util.Properties;
import java.util.StringJoiner;
import javax.naming.ConfigurationException;
//imports for json
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
//imports for LDAP
import org.apache.directory.api.ldap.model.cursor.EntryCursor;
import org.apache.directory.api.ldap.model.entry.Attribute;
import org.apache.directory.api.ldap.model.entry.DefaultEntry;
import org.apache.directory.api.ldap.model.entry.Entry;
import org.apache.directory.api.ldap.model.entry.Value;
import org.apache.directory.api.ldap.model.exception.LdapException;
import org.apache.directory.api.ldap.model.exception.LdapInvalidAttributeValueException;
import org.apache.directory.api.ldap.model.message.Control;
import org.apache.directory.api.ldap.model.message.ResultCodeEnum;
import org.apache.directory.api.ldap.model.message.SearchRequest;
import org.apache.directory.api.ldap.model.message.SearchRequestImpl;
import org.apache.directory.api.ldap.model.message.SearchResultDone;
import org.apache.directory.api.ldap.model.message.SearchScope;
import org.apache.directory.api.ldap.model.message.controls.AbstractControl;
import org.apache.directory.api.ldap.model.message.controls.PagedResults;
import org.apache.directory.api.ldap.model.message.controls.PagedResultsImpl;
import org.apache.directory.api.ldap.model.name.Dn;
import org.apache.directory.ldap.client.api.EntryCursorImpl;
import org.apache.directory.ldap.client.api.LdapConnection;
import org.apache.directory.ldap.client.api.LdapNetworkConnection;
//Nashorn
import delight.nashornsandbox.NashornSandbox;
import delight.nashornsandbox.NashornSandboxes;
public class Executor
{
public static void main( String[] args )
{
pagingTest();
}
private static void pagingTest(){
//ENTER YOUR CREDENTIALS
String server = "";
int port = 0;
String loginId = "";
String loginPassword = "";
String usersBaseDN = "";
String userObjectClass = "";
String base64cookie = null;
LdapNetworkConnection connection = new LdapNetworkConnection(server, port, true );
try{
connection.setTimeOut( 300 );
connection.bind(loginId,loginPassword);
/*First Pass*/
PagedResultsImpl pagedSearchControl = new PagedResultsImpl();
pagedSearchControl.setSize(5);
pagedSearchControl.setCookie(Base64.getDecoder().decode(""));
SearchRequestImpl searchRequest = new SearchRequestImpl();
searchRequest.setBase(new Dn(usersBaseDN));
searchRequest.setFilter("(objectClass=" + userObjectClass +")");
searchRequest.setScope(SearchScope.SUBTREE);
searchRequest.addAttributes("*");
searchRequest.addControl(pagedSearchControl);
EntryCursorImpl cursor = new EntryCursorImpl(connection.search(searchRequest));
while (cursor.next()) {
System.out.println("First Pass User: " + cursor.get().getDn());
}
PagedResults pagingResults = (PagedResults)cursor.getSearchResultDone().getControl(PagedResults.OID);
if (pagingResults != null){
byte[] cookie = pagingResults.getCookie();
if (cookie != null && cookie.length > 0) {
base64cookie = Base64.getEncoder().encodeToString(cookie);
System.out.println("First Pass Cookie: " + cookie);
}
}
cursor.close();
}catch(Exception e){
System.out.println(e);
}
finally {
//COMMENT THIS CODE BLOCK TO SEE IT WORKING (IT WILL USE THE SAME CONNECTION)
try {
connection.unBind();
connection.close();
} catch (Exception e) {
System.out.println(e);
}
connection = new LdapNetworkConnection( server, port, true );
}
try{
connection.setTimeOut( 300 );
connection.bind(loginId,loginPassword);
/*Second Pass*/
PagedResultsImpl secondPagedSearchControl = new PagedResultsImpl();
secondPagedSearchControl.setSize(5);
secondPagedSearchControl.setCookie(Base64.getDecoder().decode(base64cookie));
SearchRequestImpl secondSearchRequest = new SearchRequestImpl();
secondSearchRequest.setBase(new Dn(usersBaseDN));
secondSearchRequest.setFilter("(objectClass=" + userObjectClass +")");
secondSearchRequest.setScope(SearchScope.SUBTREE);
secondSearchRequest.addAttributes("*");
secondSearchRequest.addControl(secondPagedSearchControl);
EntryCursorImpl secondCursor = new EntryCursorImpl(connection.search(secondSearchRequest));
while (secondCursor.next()) {
System.out.println("Second Pass User: " + secondCursor.get().getDn());
}
secondCursor.close();
}catch(Exception e){
System.out.println(e);
}
finally {
try {
connection.unBind();
connection.close();
} catch (Exception e) {
System.out.println(e);
}
}
}
}
所以我想我的新问题是:
是否有人知道允许OpenLDAP接受
从以前的连接分页cookie?