使用DirectoryServices.Protocols缓慢的LDAP搜索缓慢、DirectoryServices、Protocols、LDAP

2023-09-09 21:39:12 作者:身中ゝ剧毒ヾ

我们正在使用System.DirectoryServices.DirectorySearcher做sAMAccountName赋查找。此查询某广告,我们怀疑是相当大的,当工作得很好,只是,搜索经常超时。做了一些研究之后,我发现使用System.DirectoryServices.Protocols对搜索广告大片查询时可以更快。我想我们所使用的协议,看看是否将与超时任何区别重建。这是什么目前有:

We are using System.DirectoryServices.DirectorySearcher to do sAMAccountName lookups. This works fine except that when querying a certain AD, which we suspect is quite large, the search often times out. After doing a bit of research, I found out that searches using System.DirectoryServices.Protocols can be faster when querying against a large AD. I am trying to recreate what we have using Protocols to see if that will make any difference with the timeouts. This is what's currently there:

Dim Entry As New DirectoryEntry(anLDAPURL, aDomainUserName, aPassword)

Dim obj As Object = Entry.NativeObject 'Force Authentication on Active Directory Server

Dim Filter As String = String.Format("(sAMAccountName={0})", aDomainUserName)

Dim Search As New DirectorySearcher(Entry, Filter)
Search.PropertiesToLoad.Add(SID)
Search.PropertiesToLoad.Add(ACCOUNTISLOCKEDOUT)
Search.PropertiesToLoad.Add(ACCOUNTISDISABLED)

Dim Results As SearchResult = Search.FindOne()

这工作得很好,是非常快的(除了在上述情况下,它超时提到)。而这正是我试图将其更改为,这样我可以测试出来:

This works fine and is very fast (except in the case mentioned above where it times out). And this is what I'm trying to change it to so that I can test it out:

Dim credentials As New System.Net.NetworkCredential(aDomainUserName, aPassword)
Dim directoryIdentifier As New System.DirectoryServices.Protocols.LdapDirectoryIdentifier("ldap-ad.example.org")

Using connection As New System.DirectoryServices.Protocols.LdapConnection(directoryIdentifier, credentials, Protocols.AuthType.Basic)
    Dim attributes() As String = {SID, ACCOUNTISLOCKEDOUT, ACCOUNTISDISABLED}

    Dim search As New System.DirectoryServices.Protocols.SearchRequest(
    "dc=example,dc=org",
    String.Format("(sAMAccountName={0})", aDomainUserName),
    Protocols.SearchScope.Subtree,
    attributes)

    Dim response As System.DirectoryServices.Protocols.SearchResponse = DirectCast(connection.SendRequest(search), System.DirectoryServices.Protocols.SearchResponse)
End Using

上面code工作,在它返回一个结果,但是比原来慢得多。我怀疑,我想查询的方式是低效的,但我不是太肯定的,我应该怎么设置它,以便它的速度更快。

The above code works, in that it returns a result, but is much slower than the original. I suspect that the way I'm trying to query is inefficient but I'm not too sure on how I should set it up so that it's faster.

推荐答案

我跑进这最终是由于在返回的结果中引用跟踪同样的问题在 System.DirectoryServices.Protocols .LdapConnection.SendRequest 方法。这是由于假域名corp.org一个没有任何DNS条目(所以 sendRequest将被浪费了大量的时间做DNS查询的结果)。要禁用引用跟踪:

I ran into the same problem which ended up being due to "referral chasing" in the returned results in the System.DirectoryServices.Protocols.LdapConnection.SendRequest method. This was due to a "fake" domain name "corp.org" that didn't have any DNS entries (so SendRequest was wasting lots of time doing DNS lookups on the results). To disable referral chasing:

var conn = new LdapConnection(...);
conn.SessionOptions.ReferralChasing = ReferralChasingOptions.None;