问题
I am trying to connect to an Active Directory domain (W2K8R2 DC) in a different forest. To that end, I pass the credentials into the following DirectoryEntry constructor:
DirectoryEntry(string path, string username, string password, AuthenticationTypes authenticationType)
This is all good and well. What I would like to do though is retain the connection somehow and reuse it through all my calls to the AD so that I do not need to pass the credentials repeatedly. Is this possible somehow?
Thanks!
回答1:
If you want the control at the connection level, I recommend you to use System.DirectoryServices.Protocol. You can reuse your LDAP connection to make different LDAP queries. However, the programming paradigm is very different from DirectoryEntry
If you need to use DirectoryEntry
, you have to store the username and password somewhere and then pass them to all the DirectoryEntry
objects. What I would do is to write a method GetDirectoryEntry(string dn)
and have this method create the DirectoryEntry
for me with the correct username and password. This doesn't look elegant but it doesn't do anything wrong. If you care password being stored in memory in plain text, use SecureString to store the password.
This is nothing wrong because DirectoryEntry
is maintaining its own LDAP connection pool. If you have multiple DirectoryEntry
with the same username and password, it will be smart enough to share the LDAP connection. It's basically the same as holding a single LDAP connection and doing different LDAP queries. It's not going to re-authenticate to LDAP server for each of the DirectoryEntry
objects
If you don't like to rely on the black box feature from DirectoryEntry
, the following suggested workaround may make you feel better.
static DirectoryEntry GetObject(DirectoryEntry root, string dn)
{
using (DirectorySearcher searcher = new DirectorySearcher(root))
{
searcher.Filter = "(distinguishedName=" + dn + ")";
searcher.SearchScope = SearchScope.Subtree;
SearchResult result = searcher.FindOne();
if (result == null) return null;
return result.GetDirectoryEntry();
}
}
You just need to bind to a root object with username and password. Then, you can keep the root object as a static variable or whatever you like. Then, you get another DirectoryEntry
object by doing a LDAP query with the SearchRoot
set to your root object. The returned DirectoryEntry
will still use the username and password from root. Again, this is not doing anything better than simply passing in username and password to DirectoryEntry
. Indeed, performance-wise, it's worse because we need to do one more LDAP query to get the DirectoryEntry
来源:https://stackoverflow.com/questions/4949152/how-can-i-retain-connection-credentials-across-calls-in-system-directoryservices