简体   繁体   English

使用 .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

I want to fetch all the users from a large location of our Domino LDAP, around ~2000 users altogether.我想从我们的 Domino LDAP 的一个大位置获取所有用户,总共大约 2000 个用户。 Since .NET Core sadly doesn't have a platform independent LDAP library, I'm using Novell.Directory.Ldap.NETStandard with this POC:由于 .NET Core 很遗憾没有独立于平台的 LDAP 库,因此我在此 POC 中使用Novell.Directory.Ldap.NETStandard

var cn = new Novell.Directory.Ldap.LdapConnection();
cn.Connect("dc.internal", 389);
cn.Bind("user", "pw");
string filter = "location=MyLoc";
var result = cn.Search("", Novell.Directory.Ldap.LdapConnection.ScopeOne, filter, new string[] { Novell.Directory.Ldap.LdapConnection.AllUserAttrs }, typesOnly: false);            
int count = 0;
while (result.HasMore()) {
    var entry = result.Next();
    count++;
    Console.WriteLine(entry.Dn);
}

It prints me a lot of entries, but not all.它打印了很多条目,但不是全部。 When count = 1000 I got an Size Limit Exceeded exception.count = 1000我收到了Size Limit Exceeded异常。 I guess this is because I need to use some kind of pagination, so not all entries woult be returned in a single request.我想这是因为我需要使用某种分页,因此并非所有条目都将在单个请求中返回。 There are different questions like this or this one .有像这样这样的不同问题。 Both in Java, the .NET Core API seems somehow different.在 Java 中,.NET Core API 似乎有些不同。

Approach 1: Try to find out how LdapSearchRequest works in .NET Core方法一:尝试了解LdapSearchRequest在 .NET Core 中是如何工作的

byte[] resumeCookie = null;
LdapMessageQueue queue = null;
var searchReq = new LdapSearchRequest("", LdapConnection.ScopeOne, filter, new string[] { LdapConnection.AllUserAttrs },
LdapSearchConstraints.DerefNever, maxResults: 3000, serverTimeLimit: 0, typesOnly: false, new LdapControl[] { new SimplePagedResultsControl(size: 100, resumeCookie) });            
var searchRequest = cn.SendRequest(searchReq, queue);

I'm trying to figure out how the Java examples can be used in .NET Core.我试图弄清楚如何在 .NET Core 中使用 Java 示例。 This looks good, however I can't figure out how to fetch the LDAP entries.这看起来不错,但是我不知道如何获取 LDAP 条目。 I only get an message id.我只得到一个消息 ID。 By looking into the source it seems that I'm on the right way, but they're using MessageAgent which cannot be used outside since it's internal sealed . 通过查看来源,我似乎走在正确的道路上,但他们使用的是MessageAgent ,由于它是internal sealed ,因此不能在外部使用。 This is propably the reason why searching for LdapRearchRequest in the source code doesn't give many results.这大概是为什么在源代码中搜索LdapRearchRequest没有给出很多结果的原因。

Approach 2: Using SimplePagedResultsControlHandler方法 2:使用SimplePagedResultsControlHandler

var opts = new SearchOptions("", LdapConnection.ScopeOne, filter, new string[] { LdapConnection.AllUserAttrs });
// For testing purpose: https://github.com/dsbenghe/Novell.Directory.Ldap.NETStandard/issues/163
cn.SearchConstraints.ReferralFollowing = false;
var pageControlHandler = new SimplePagedResultsControlHandler(cn);
var rows = pageControlHandler.SearchWithSimplePaging(opts, pageSize: 100);

This throws a Unavaliable Cricital Extension exception.这会引发Unavaliable Cricital Extension异常。 First I thought that this is an issue of the .NET port, which may doesn't support all the features of the original Java library yet.首先我认为这是.NET端口的问题,它可能还不支持原始Java库的所有功能。 It seems complete and according to further researches, it looks like to be an LDAP error code.它看起来很完整,根据进一步的研究,它看起来像是一个 LDAP 错误代码。 So this must be something which has to be supported by the server, but is not supported by Domino.所以这必须是服务器必须支持的东西,但 Domino 不支持。

I couldn't make at least one of those approachs work, but found another way: Cross platform support for the System.DirectoryServices.Protocols namespace was was added in .NET 5 .我无法使这些方法中的至少一种起作用,但找到了另一种方法: 在 .NET 5 中添加了对System.DirectoryServices.Protocols命名空间的跨平台支持。 This was missing for a long time in .NET Core and I guess this is the main reason why libraries like Novell.Directory.Ldap.NETStandard were ported to .NET Core - in times of .NET Core 1.x this was the only way I found to authenticate against LDAP wich works on Linux too.这在 .NET Core 中缺失了很长时间,我想这就是像Novell.Directory.Ldap.NETStandard这样的库被移植到 .NET Core 的主要原因——在 .NET Core 1.x 时代,这是唯一的方法我发现对 LDAP 进行身份验证也适用于 Linux。

After having a deeper look into System.DirectoryServices.Protocols , it works well out of the box, even for ~2k users.在深入了解System.DirectoryServices.Protocols ,它开箱即用,即使对于大约 2k 用户也是如此。 My basic POC class looks like this:我的基本 POC 类如下所示:

public class DominoLdapManager {
    LdapConnection cn = null;
    public DominoLdapManager(string ldapHost, int ldapPort, string ldapBindUser, string ldapBindPassword) {
        var server = new LdapDirectoryIdentifier(ldapHost, ldapPort);
        var credentials = new NetworkCredential(ldapBindUser, ldapBindPassword);

        cn = new LdapConnection(server);
        cn.AuthType = AuthType.Basic;
        cn.Bind(credentials);
    }
    public IEnumerable<DominoUser> Search(string filter, string searchBase = "") {
        string[] attributes = { "cn", "mail", "companyname", "location" };
        var req = new SearchRequest(searchBase, filter, SearchScope.Subtree, attributes);
        var resp = (SearchResponse)cn.SendRequest(req);

        foreach (SearchResultEntry entry in resp.Entries) {
            var user = new DominoUser() {
                Name = GetStringAttribute(entry, "cn"),
                Mail = GetStringAttribute(entry, "mail"),
                Company = GetStringAttribute(entry, "companyname"),
                Location = GetStringAttribute(entry, "location")
            };
            yield return user;
        }
        yield break;
    }
    string GetStringAttribute(SearchResultEntry entry, string key) {
        if (!entry.Attributes.Contains(key)) {
            return string.Empty;
        }
        string[] rawVal = (string[])entry.Attributes[key].GetValues(typeof(string));
        return rawVal[0];
    }
}

Example usage:用法示例:

var ldapManager = new DominoLdapManager("ldap.host", 389, "binduser", "pw");
var users = ldapManager.Search("objectClass=person");

But it's not solved with Novell.Directory.Ldap.NETStandard as the title said但正如标题所说,它没有用Novell.Directory.Ldap.NETStandard解决

This doesn't solve my problem with the Novell.Directory.Ldap.NETStandard library as the title suggested, yes.正如标题所建议的那样,这并不能解决我的Novell.Directory.Ldap.NETStandard库问题,是的。 But since System.DirectoryServices.Protocols is a official .NET package maintained by Microsoft and the .NET foundation, this seems the better aproach for me.但是由于System.DirectoryServices.Protocols是由 Microsoft 和 .NET 基金会维护的官方 .NET 包,这对我来说似乎是更好的方法。 The foundation will take care to keep it maintained and compatible with further .NET releases.该基金会将注意保持其维护并与进一步的 .NET 版本兼容。 When I wrote the question, I was not aware of the fact that Linux support is added now.当我写这个问题时,我不知道现在添加了 Linux 支持。

Don't get me wrong, I don't want to say that third packages are bad by design - that would be completely wrong.不要误会我的意思,我不想说第三个包在设计上很糟糕——那是完全错误的。 However, when I have the choice between a official package and a third party one, I think it makes sense to prefer the official one.但是,当我在官方包和第三方包之间进行选择时,我认为更喜欢官方包是有道理的。 Except there would be a good reason against that - which is not the case here: The official package (which doesn't exist in the past) works better to solve this issue than the third party one.除非有一个很好的理由反对——这里不是这样:官方包(过去不存在)比第三方包更能解决这个问题。

暂无
暂无

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

相关问题 使用 Novell.Directory.Ldap.NETStandard 在 LDAP 中获取用户组 - Getting user group in LDAP using Novell.Directory.Ldap.NETStandard 如何使用 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? "如何使用 Novell.Directory.Ldap.NETStandard 在 c#\/.NET 中更改 LDAP 的密码" - How to change password of LDAP in c#/.NET using Novell.Directory.Ldap.NETStandard 如何使用 Novell.Directory.Ldap.NETStandard 在具有 &gt; 10000 个条目的 Ldap 服务器上进行分页搜索? - How to do a paged search on an Ldap server with > 10000 entries using Novell.Directory.Ldap.NETStandard? 使用 Novell.Directory.Ldap.NETStandard 从 AD 读取所有用户 - Read all users from AD using 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 LDAP对.NET Core中的AD进行页面LDAP查询 - Page LDAP query against AD in .NET Core using Novell LDAP 如何在C#中使用LDAP从Domino服务器列出邮箱 - How to list mailbox from Domino Server using LDAP in C# Novell LDAP C# - Novell.Directory.Ldap - 有没有人让它工作? - Novell LDAP C# - Novell.Directory.Ldap - Has anybody made it work?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM