0

我使用 Apache Directory API 从 Active Directory 加载用户数据。它类似于 'oers' 在这个 stackoverflow 问题中找到的示例代码:Apache Directory LDAP - Paged search

我的一些区别是:

  • 我正在用 Nashorn 编码(在 Java 中运行的 Javascript)
  • 我正在使用 PagedResultsImpl 类而不是 PagedResultsDecorator
  • 我通过使用 byte[] cookie 的 Base64 编码将 cookie 保存为调用之间的字符串。
  • 我正在使用具有以下 Maven 导入的 Apache Directory API:

    <dependency> <groupId>org.apache.directory.api</groupId> <artifactId>api-all</artifactId> <version>1.0.3</version> </dependency>

以下是一些重要的部分:

...
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());
}

当针对Active Directory运行时,我可以很好地分页所有用户。当我将连接更改为指向OpenLDAP目录时,我可以很好地搜索用户,除非我使用pageCursor的非空值设置页面控制 cookie(我从 base 64 编码前一个调用的 cookie )。基本上,我无法从 OpenLDAP 获得分页结果。我没有得到任何结果,也没有例外。

  • 为了让 OpenLDAP 正确分页需要什么?
  • 在 Apache Directory 中设置页面控制时我是否遗漏了什么?
  • 我需要打开 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 的解决方法?
4

0 回答 0