问题
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
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.
回答1:
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;
回答2:
Based on your LDAP path in the SearchRequest
constructor ("dc=example,dc=org"
), it looks like you're specifying a server in the LdapDirectoryIdentifier
constructor (ldap-ad.example.org
). Have you tried just specifying the domain instead of the server (example.org
)?
I don't really see how the two methods should be different when you're searching on an indexed property that will only return either 0 or 1 results.
来源:https://stackoverflow.com/questions/16890091/ldap-search-using-directoryservices-protocols-slow