如何使用 Novell.Directory.Ldap.NETStandard 和 Simple Paged Results 控件在 Ldap 服务器上进行分页搜索? [英] How to do a paged search on an Ldap server using Novell.Directory.Ldap.NETStandard and Simple Paged Results control?

查看:33
本文介绍了如何使用 Novell.Directory.Ldap.NETStandard 和 Simple Paged Results 控件在 Ldap 服务器上进行分页搜索?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 Novell.Directory.Ldap.NETStandard (:

当客户端向请求添加控制时,size 设置为页面中所需的元素数量,cookie 是来自先前服务器响应的不透明结构(第一个请求为空).

当您尝试在请求中构造控件时,您错误地添加了整个控件值而不是 cookie (pageControl.getValue()):

 var request = new Asn1Sequence(2);request.add(new Asn1Integer(pageSize));request.add(pageControl == null ? new Asn1OctetString("") : new Asn1OctetString(pageControl.getValue()));

它使第一个之后的所有请求都不正确.

建议的解决方案

看看 https://github.com/metacube/PagedResultsControl.我创建了类型化的简单分页结果控制实现,它封装了解码/编码逻辑.对于来自 Active Directory 的 100 000 多个条目,对我来说效果很好.

测试应用程序显示了基本用法.

I'm trying to do a paged search in an Active Directory using Novell.Directory.Ldap.NETStandard (https://github.com/dsbenghe/Novell.Directory.Ldap.NETStandard) and Simple Paged Results control (https://ldapwiki.com/wiki/Simple%20Paged%20Results%20Control).

First page works fine but the second one throws "Unavailable Critical Extension" on the searchResult.next() line. When looking in the event log for ActiveDirectory I found:

00000057: LdapErr: DSID-0C090809, comment: Error processing control, data 0, v23f0 0000208D: NameErr: DSID-03100213, problem 2001 (NO_OBJECT), data 0, best match of:

We have also tried the LdapVirtualListControl but run into a different problem, see How to do a paged search on an Ldap server with > 10000 entries using Novell.Directory.Ldap.NETStandard?

Here are a simplified code we use to reproduce:

        // Connection
        var ldapConn = new LdapConnection()
        {
            SecureSocketLayer = true,
        };
        ldapConn.UserDefinedServerCertValidationDelegate += (sender, certificate, chain, sslPolicyErrors) => true;
        ldapConn.Connect(host, 636);
        ldapConn.Bind(username, password);

        // Constraints
        LdapSearchConstraints searchConstraints = (LdapSearchConstraints)_conn.SearchConstraints.Clone();
        int pageSize = 100, count = 0;
        bool exit = false;
        const string LDAP_SERVER_SIMPLE_PAGED_RESULT_OID = "1.2.840.113556.1.4.319";

        LdapControl pageControl = null;

        do
        {
            int inPageCount = 0;

            // Add Simple Paged Result control
            var request = new Asn1Sequence(2);
            request.add(new Asn1Integer(pageSize));
            request.add(pageControl == null ? new Asn1OctetString("") : new Asn1OctetString(pageControl.getValue()));
            searchConstraints.setControls(
                new LdapControl(LDAP_SERVER_SIMPLE_PAGED_RESULT_OID, true, request.getEncoding(new LBEREncoder()))
            );

            // Get search result
            var searchResult = (LdapSearchResults)ldapConn.Search(container, LdapConnection.SCOPE_SUB, query, null, false, searchConstraints);
            while (searchResult.hasMore())
            {

                // Detect simple paged result control
                pageControl = searchResult.ResponseControls?.Where(rc => rc.ID == LDAP_SERVER_SIMPLE_PAGED_RESULT_OID).FirstOrDefault();
                if (pageControl != null) break;

                var nextEntry = searchResult.next();
                inPageCount++;

            }
            count += inPageCount;

            // Exit if no more pages
            exit = pageControl == null;

        } while (!exit);

解决方案

Why code does not work

According to RFC Simple Paged Results Control encoded as

realSearchControlValue ::= SEQUENCE { size INTEGER (0..maxInt), -- requested page size from client -- result set size estimate from server cookie OCTET STRING } which may be clear seen on the next screenshot (taken from Wireshark).

:

When the client adds control to the request, size is set to the desired number of elements in the page and cookie is the opaque structure from the previous server response (empty for the first request).

When you try to construct control in your request, you mistakenly add the whole control value instead of cookie (pageControl.getValue()):

 var request = new Asn1Sequence(2);
 request.add(new Asn1Integer(pageSize));
 request.add(pageControl == null ? new Asn1OctetString("") : new Asn1OctetString(pageControl.getValue()));

It makes all requests after the first one incorrect.

Proposed solution

Take a look at https://github.com/metacube/PagedResultsControl. I've created typed Simple Paged Results Control implementation which encapsulates decoding/ encoding logic. Works perfectly fine for me in the case of 100 000+ entries from Active Directory.

The test application shows basic usage.

这篇关于如何使用 Novell.Directory.Ldap.NETStandard 和 Simple Paged Results 控件在 Ldap 服务器上进行分页搜索?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆