簡體   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

我想從我們的 Domino LDAP 的一個大位置獲取所有用戶,總共大約 2000 個用戶。 由於 .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);
}

它打印了很多條目,但不是全部。 count = 1000我收到了Size Limit Exceeded異常。 我想這是因為我需要使用某種分頁,因此並非所有條目都將在單個請求中返回。 有像這樣這樣的不同問題。 在 Java 中,.NET Core API 似乎有些不同。

方法一:嘗試了解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);

我試圖弄清楚如何在 .NET Core 中使用 Java 示例。 這看起來不錯,但是我不知道如何獲取 LDAP 條目。 我只得到一個消息 ID。 通過查看來源,我似乎走在正確的道路上,但他們使用的是MessageAgent ,由於它是internal sealed ,因此不能在外部使用。 這大概是為什么在源代碼中搜索LdapRearchRequest沒有給出很多結果的原因。

方法 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);

這會引發Unavaliable Cricital Extension異常。 首先我認為這是.NET端口的問題,它可能還不支持原始Java庫的所有功能。 它看起來很完整,根據進一步的研究,它看起來像是一個 LDAP 錯誤代碼。 所以這必須是服務器必須支持的東西,但 Domino 不支持。

我無法使這些方法中的至少一種起作用,但找到了另一種方法: 在 .NET 5 中添加了對System.DirectoryServices.Protocols命名空間的跨平台支持。 這在 .NET Core 中缺失了很長時間,我想這就是像Novell.Directory.Ldap.NETStandard這樣的庫被移植到 .NET Core 的主要原因——在 .NET Core 1.x 時代,這是唯一的方法我發現對 LDAP 進行身份驗證也適用於 Linux。

在深入了解System.DirectoryServices.Protocols ,它開箱即用,即使對於大約 2k 用戶也是如此。 我的基本 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];
    }
}

用法示例:

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

但正如標題所說,它沒有用Novell.Directory.Ldap.NETStandard解決

正如標題所建議的那樣,這並不能解決我的Novell.Directory.Ldap.NETStandard庫問題,是的。 但是由於System.DirectoryServices.Protocols是由 Microsoft 和 .NET 基金會維護的官方 .NET 包,這對我來說似乎是更好的方法。 該基金會將注意保持其維護並與進一步的 .NET 版本兼容。 當我寫這個問題時,我不知道現在添加了 Linux 支持。

不要誤會我的意思,我不想說第三個包在設計上很糟糕——那是完全錯誤的。 但是,當我在官方包和第三方包之間進行選擇時,我認為更喜歡官方包是有道理的。 除非有一個很好的理由反對——這里不是這樣:官方包(過去不存在)比第三方包更能解決這個問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM