简体   繁体   English

如何使用 Novell.Directory.Ldap.NETStandard 和简单分页结果控件在 Ldap 服务器上进行分页搜索?

[英]How to do a paged search on an Ldap server using Novell.Directory.Ldap.NETStandard and Simple Paged Results control?

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 ).我正在尝试使用 Novell.Directory.Ldap.NETStandard ( https://github.com/dsbenghe/Novell.Directory.Ldap.NETStandard )和简单分页结果控件( Z5E056C500A1C4B6A7110B50D807BADE )在 Active Directory 中进行分页搜索ldapwiki.com/wiki/Simple%20Paged%20Results%20Control )。

First page works fine but the second one throws "Unavailable Critical Extension" on the searchResult.next() line.第一页工作正常,但第二页在 searchResult.next() 行上抛出“不可用的关键扩展”。 When looking in the event log for ActiveDirectory I found:在查看 ActiveDirectory 的事件日志时,我发现:

00000057: LdapErr: DSID-0C090809, comment: Error processing control, data 0, v23f0 0000208D: NameErr: DSID-03100213, problem 2001 (NO_OBJECT), data 0, best match of: 00000057:LdapErr:DSID-0C090809,注释:错误处理控制,数据 0,v23f0 0000208D:NameErr:DSID-03100213,问题 2001 (NO_OBJECT),数据 0,最佳匹配:

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?我们也尝试了 LdapVirtualListControl,但遇到了不同的问题,请参阅如何使用 Novell.Directory.Ldap.NETStandard 在具有 > 10000 个条目的 Ldap 服务器上进行分页搜索?

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根据RFC Simple Paged Results Control 编码为

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). realSearchControlValue::= SEQUENCE { size INTEGER (0..maxInt), -- requested page size from client -- result set size estimate from server cookie OCTET STRING }在下一个屏幕截图中可以清楚地看到(取自 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).当客户端向请求添加控制时,大小设置为页面中所需的元素数量, cookie是来自先前服务器响应的不透明结构(第一个请求为空)。

When you try to construct control in your request, you mistakenly add the whole control value instead of cookie (pageControl.getValue()):当您尝试在请求中构造控件时,您错误地添加了整个控件值而不是 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 .看看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.在来自 Active Directory 的 100 000 多个条目的情况下,对我来说工作得很好。

The test application shows basic usage.测试应用程序显示基本用法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用 Novell.Directory.Ldap.NETStandard 在具有 > 10000 个条目的 Ldap 服务器上进行分页搜索? - How to do a paged search on an Ldap server with > 10000 entries using Novell.Directory.Ldap.NETStandard? 使用 Novell.Directory.Ldap.NETStandard 在 LDAP 中获取用户组 - Getting user group in LDAP using Novell.Directory.Ldap.NETStandard "如何使用 Novell.Directory.Ldap.NETStandard 在 c#\/.NET 中更改 LDAP 的密码" - How to change password of LDAP in c#/.NET using Novell.Directory.Ldap.NETStandard 使用 .NET Core 5 和 Novell.Directory.Ldap.NETStandard 从 Domino LDAP 服务器获取 1000 多行 - Fetching more than 1000 rows from Domino LDAP server using .NET Core 5 and Novell.Directory.Ldap.NETStandard 使用 Novell.Directory.Ldap.NETStandard 库的 C# netcore ldap 身份验证 - C# netcore ldap authentication using Novell.Directory.Ldap.NETStandard library 连接失败并显示错误91(Novell.Directory.Ldap.NETStandard) - Connect fails with Error 91 (Novell.Directory.Ldap.NETStandard) 使用 Novell.Directory.Ldap.NETStandard 从 AD 读取所有用户 - Read all users from AD using Novell.Directory.Ldap.NETStandard 如何在具有很多用户的Ldap服务器上进行分页搜索? - How to do a paged search on an Ldap server with lots of users? 在带有 C# 库 Novell 的 ldap 搜索中使用全局目录 - Using global catalog in a ldap search with C# library Novell 使用Linq检索分页结果 - Retrieve paged results using Linq
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM