How can I retain connection credentials across calls in System.DirectoryServices?

别来无恙 提交于 2020-02-02 16:35:35

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!