如何使用 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?
问题描述
我正在尝试使用 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屋!