如何在具有很多用户的Ldap服务器上进行分页搜索?

编程入门 行业动态 更新时间:2024-10-25 21:15:30
本文介绍了如何在具有很多用户的Ldap服务器上进行分页搜索?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我需要创建一个使用.NET Core在Linux上运行的LDAP客户端.我搜寻了遍历Internet的网站,唯一支持.Net Standard的库是Novell.Directory.Ldap(开源,即iei- github/dsbenghe/Novell.Directory.Ldap.NETStandard ).目录服务库在.Net Core for Linux中不支持,仅在Windows上.

我查看了文档并成功创建了一个基本的Ldap客户端应用程序.

现在出现问题::我需要同步很多用户(10.000、200.000用户),默认情况下,我的ldap服务器的最大页面大小为1000(并且我不想更改它) ).我使用VirtualListControl来创建页面,它对于10k用户正常工作.

对于200k用户,它崩溃并显示错误53-不愿意对LdapSortControl响应执行. Novell库需要一个LdapSortControl来执行分页操作(用于索引),我认为我的ldap无法排序200k.我使用的代码:

int startIndex = 1; int contentCount = 0; int afterIndex = 10; int count = 0; do { LdapVirtualListControl ctrl = new LdapVirtualListControl(startIndex, 0, afterIndex, contentCount); LdapSortKey[] keys = new LdapSortKey[1]; keys[0] = new LdapSortKey("sn"); LdapSortControl sort = new LdapSortControl(keys, true); LdapSearchConstraints constraints = _ldapConnection.SearchConstraints; constraints.setControls(new LdapControl[] { ctrl, sort}); _ldapConnection.Constraints = constraints; LdapSearchResults lsc = _ldapConnection.Search(searchBase, searchScope, searchFilter, attributes, typesOnly, cons); while (lsc.HasMore()) { try { LdapEntry nextEntry = lsc.Next(); Console.WriteLine( nextEntry.DN); } catch (LdapException e) { Console.WriteLine($"Error: {e.LdapErrorMessage}"); //Exception is thrown, go for next entry continue; } } LdapControl[] controls = lsc.ResponseControls; if (controls == null) { Console.Out.WriteLine("No controls returned"); } else { foreach (LdapControl control in controls) { if (control.ID == "2.16.840.1.113730.3.4.10") { LdapVirtualListResponse response = new LdapVirtualListResponse(control.ID, control.Critical, control.getValue()); startIndex += afterIndex + 1; contentCount = response.ContentCount; count += afterIndex; } } } Console.WriteLine(i); } while (count <= contentCount);

文档很小,没有足够的信息,我也不知道如何使用Novell库以更好的方式进行分页. 这里有人使用Novell Ldap库并且有分页经验并且可以帮助我吗?我分散了

谢谢

解决方案

要使用Novell.Directory.Ldap进行分页查询,必须将LdapVirtualListControl用作请求"控件.

LdapVirtualListControl遵循Ldap排序请求控件:VLV(虚拟列表视图)的参数,

before:after:index:content_count

其中"之前"是您要在索引之前返回的项目数,"之后"是要在索引之后返回的项目数索引和" content_count "是服务器中预期的项目总数.如果您不知道,则必须使用0作为值.

如果您想通过"ldapsearch" cli返回前5个元素,则必须在随后的5个元素中使用"0:4:1:0"和"0:4:5:0".

LdapVirtualListControl拥有一个带有相同参数但顺序不同的构造函数:

LdapVirtualListControl(int startIndex, int beforeCount, int afterCount, int contentCount)

我个人使用此功能正确设置参数:

public static LdapSearchConstraints AddPagination(this LdapSearchConstraints constraints, int page, int pageSize) { int startIndex = (page - 1) * pageSize; startIndex++; int beforeCount = 0; int afterCount = pageSize - 1; int contentCount = 0; //0 means that i don't know the total count var lvlc = new LdapVirtualListControl(startIndex, beforeCount, afterCount, contentCount); constraints.setControls(lvlc); return constraints; }

此后,另一个问题需要引起您的注意:如果您要请求一组位于数据集末尾的数据,则会收到数据集的第一项.

说明:

ldap中存在的数据示例: | 1 | 2 | 3 | 4 | 如果我们要一套 ________ | 3 | 4 | 5 | <-5不存在 Ldap返回: ________ | 3 | 4 | 1 | <-它从头开始

要解决此问题,我将在返回前删除超出的元素:

var lastIndex = (page * pageSize); if (lastIndex > result.Total) { var itemsToReturn = (int) (result.Total - (lastIndex - pageSize)); if (itemsToReturn < 1) { items = new List<LdapQueryItem>(); } else { items = items.Take(itemsToReturn).ToList(); } }

最后,获得总数的函数(在searchResults.HasMore()方法之后执行)

protected int? GetTotal(LdapSearchResults searchResult) { if (searchResult == null) { throw new ArgumentNullException(nameof(searchResult)); } if (searchResult.ResponseControls != null && searchResult.ResponseControls.Any()) { foreach (LdapControl control in searchResult.ResponseControls) { if (control.ID == "2.16.840.1.113730.3.4.10") // the id of the response control { LdapVirtualListResponse response = new LdapVirtualListResponse(control.ID, control.Critical, control.getValue()); return response.ContentCount; } } } return null; }

您可以在这本书上获得更多的见解和信息: >

I need to create a LDAP client that works on linux using .NET Core. I searched trought the internet and the only library that support .Net Standard is Novell.Directory.Ldap (open source, iei - github/dsbenghe/Novell.Directory.Ldap.NETStandard). Directory Service library does not have support in .Net Core for Linux, only on Windows.

I looked to the documentation and succeded to create a basic Ldap client application.

Now the problem: I need to synchronize a lot of users (10.000, 200.000 users) and by default my ldap server has a maximum size page 1000 (and I don't want to change it). I used a VirtualListControl in order to create pages and it works ok for 10k users.

For 200k user it crashes with error 53 - unwilling to perform on the LdapSortControl response. The Novell library need a LdapSortControl in order to perform paging operation (for index) and I think that my ldap is not able to sort 200k. The code that I used:

int startIndex = 1; int contentCount = 0; int afterIndex = 10; int count = 0; do { LdapVirtualListControl ctrl = new LdapVirtualListControl(startIndex, 0, afterIndex, contentCount); LdapSortKey[] keys = new LdapSortKey[1]; keys[0] = new LdapSortKey("sn"); LdapSortControl sort = new LdapSortControl(keys, true); LdapSearchConstraints constraints = _ldapConnection.SearchConstraints; constraints.setControls(new LdapControl[] { ctrl, sort}); _ldapConnection.Constraints = constraints; LdapSearchResults lsc = _ldapConnection.Search(searchBase, searchScope, searchFilter, attributes, typesOnly, cons); while (lsc.HasMore()) { try { LdapEntry nextEntry = lsc.Next(); Console.WriteLine( nextEntry.DN); } catch (LdapException e) { Console.WriteLine($"Error: {e.LdapErrorMessage}"); //Exception is thrown, go for next entry continue; } } LdapControl[] controls = lsc.ResponseControls; if (controls == null) { Console.Out.WriteLine("No controls returned"); } else { foreach (LdapControl control in controls) { if (control.ID == "2.16.840.1.113730.3.4.10") { LdapVirtualListResponse response = new LdapVirtualListResponse(control.ID, control.Critical, control.getValue()); startIndex += afterIndex + 1; contentCount = response.ContentCount; count += afterIndex; } } } Console.WriteLine(i); } while (count <= contentCount);

The documentation is small and does not have enough information and I have no idea how to use Novell library for paging in a better way. Is anybody here that use Novell Ldap library and have any experience with paging and also can help me? I'm disperate

Thank you

解决方案

To make a paged query with Novell.Directory.Ldap you have to use LdapVirtualListControl as "Request" Control.

LdapVirtualListControl respects the arguments of the Ldap Sorting Request Control: VLV (Virtual List View) that are:

before:after:index:content_count

where "before" is the number of items that you want to be returned BEFORE the index, "after" the number of items that you want to be returned AFTER the index and "content_count" is the expected total count of items in the server. In case you do not know it, you have to use 0 as value.

If you want to return the first 5 elements via "ldapsearch" cli, you have to use: '0:4:1:0' and '0:4:5:0' for the subsequent five ones.

The LdapVirtualListControl owns a constructor with the same arguments but with a different order:

LdapVirtualListControl(int startIndex, int beforeCount, int afterCount, int contentCount)

Personally, I use this function to set the arguments correctly:

public static LdapSearchConstraints AddPagination(this LdapSearchConstraints constraints, int page, int pageSize) { int startIndex = (page - 1) * pageSize; startIndex++; int beforeCount = 0; int afterCount = pageSize - 1; int contentCount = 0; //0 means that i don't know the total count var lvlc = new LdapVirtualListControl(startIndex, beforeCount, afterCount, contentCount); constraints.setControls(lvlc); return constraints; }

After that, another issue needs your attention: if you ask for a set of data, which are positioned after the end of the data-set, you will receive back the first items of the dataset.

Explanation:

Example of data present in ldap: | 1 | 2 | 3 | 4 | if we ask for the set ________| 3 | 4 | 5 | <- 5 does not exists Ldap returns: ________| 3 | 4 | 1 | <- it starts over from the beginning

To fix this issue, I remove the exceeded elements before return:

var lastIndex = (page * pageSize); if (lastIndex > result.Total) { var itemsToReturn = (int) (result.Total - (lastIndex - pageSize)); if (itemsToReturn < 1) { items = new List<LdapQueryItem>(); } else { items = items.Take(itemsToReturn).ToList(); } }

Finally, the function to get the totals (to execute AFTER the searchResults.HasMore() method)

protected int? GetTotal(LdapSearchResults searchResult) { if (searchResult == null) { throw new ArgumentNullException(nameof(searchResult)); } if (searchResult.ResponseControls != null && searchResult.ResponseControls.Any()) { foreach (LdapControl control in searchResult.ResponseControls) { if (control.ID == "2.16.840.1.113730.3.4.10") // the id of the response control { LdapVirtualListResponse response = new LdapVirtualListResponse(control.ID, control.Critical, control.getValue()); return response.ContentCount; } } } return null; }

You can get further insights and info on this book: Understanding and Deploying LDAP Directory Services

更多推荐

如何在具有很多用户的Ldap服务器上进行分页搜索?

本文发布于:2023-11-17 02:55:04,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1608546.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:分页   器上   用户   如何在   Ldap

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!