如何在System.DirectoryServices中的调用之间保留连接凭据?

时间:2011-02-09 18:52:42

标签: .net active-directory directoryservices

我正在尝试连接到其他林中的Active Directory域(W2K8R2 DC)。为此,我将凭据传递给以下DirectoryEntry构造函数:

DirectoryEntry(string path, string username, string password, AuthenticationTypes authenticationType)

这一切都很好。我 喜欢这样做的是以某种方式保留连接并通过我对AD的所有调用重用它,这样我就不需要重复传递凭据。这有可能吗?

谢谢!

1 个答案:

答案 0 :(得分:4)

如果您想在连接级别控制,我建议您使用System.DirectoryServices.Protocol。您可以重用LDAP连接来进行不同的LDAP查询。但是,编程范例与DirectoryEntry

非常不同

如果您需要使用DirectoryEntry,则必须在某处存储用户名和密码,然后将其传递给所有DirectoryEntry个对象。我要做的是编写方法GetDirectoryEntry(string dn)并使用此方法为我创建DirectoryEntry使用正确的用户名和密码。这看起来并不优雅,但它没有做错任何事。如果您关心以纯文本格式存储在内存中,请使用SecureString存储密码。

这没什么错,因为DirectoryEntry正在维护自己的LDAP连接池。如果您有多个DirectoryEntry具有相同的用户名和密码,那么它将足够聪明地共享LDAP连接。它与持有单个LDAP连接和执行不同的LDAP查询基本相同。对于每个DirectoryEntry对象

,它不会重新向LDAP服务器进行身份验证

如果您不想依赖DirectoryEntry中的黑匣子功能,以下建议的解决方法可能会让您感觉更好。

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();
    }
}

您只需要使用用户名和密码绑定到根对象。然后,您可以将根对象保留为静态变量或任何您喜欢的变量。然后,通过将DirectoryEntry设置为根对象的LDAP查询,获得另一个SearchRoot对象。返回的DirectoryEntry仍将使用root用户名和密码。同样,这并不是简单地将用户名和密码传递给DirectoryEntry。事实上,在性能方面,情况更糟,因为我们需要再做一次LDAP查询来获取DirectoryEntry