12

今天早上我发现了一个很好的方法(DirectoryEntry.Exists),它应该能够检查服务器上是否存在 Active Directory 对象。所以我尝试了一个简单的:

if (DirectoryEntry.Exists(path)) {}

当然,它没有任何重载来提供凭据。因为,如果未提供凭据,我会收到此异常:

登录失败:未知用户名或密码错误。(System.DirectoryServices.DirectoryServicesCOMException)

是否有任何其他选项可以让我在 AD 服务器上验证我的代码?或者检查对象的存在?

4

6 回答 6

17

在这种情况下,您不能使用您所说的静态方法 Exists :

DirectoryEntry directoryEntry = new DirectoryEntry(path);
directoryEntry.Username = "username";
directoryEntry.Password = "password";

bool exists = false;
// Validate with Guid
try
{
    var tmp = directoryEntry.Guid;
    exists = true;
}
catch (COMException)
{
   exists = false; 
}
于 2010-11-26T13:30:23.847 回答
3

我知道这是一个老问题,但现在可以使用源代码,因此您可以窃取和修改™ 来制作一个接受凭据的版本:

public static bool Exists(string path, string username, string password)
{
    DirectoryEntry entry = new DirectoryEntry(path, username, password);
    try
    {
        _ = entry.NativeObject;       // throws exceptions (possibly can break applications)
        return true;
    }
    catch (System.Runtime.InteropServices.COMException e)
    {
        if (e.ErrorCode == unchecked((int)0x80072030) ||
             e.ErrorCode == unchecked((int)0x80070003) ||   // ERROR_DS_NO_SUCH_OBJECT and path not found (not found in strict sense)
             e.ErrorCode == unchecked((int)0x800708AC))     // Group name could not be found
            return false;
        throw;
    }
    finally
    {
        entry.Dispose();
    }
}

你必须做的一个改变是改变使用Bind,因为这是一种internal方法,不能被像我们这样的凡人使用。相反,我只是得到了需要我们NativeObject的财产。Bind()

你可以像这样使用它:

var ouExists = Exists("LDAP://hadoop.com/OU=Students,DC=hadoop,DC=com", "username", "password");
于 2020-01-08T17:42:05.097 回答
2

没有办法做到这一点,我已经写了一个连接问题,希望能解决它。

DirectoryEntry.Exists 不接受凭据

于 2014-03-20T16:36:36.990 回答
1

在这里您可以阅读有关 C# 中的模拟的信息:

于 2010-11-26T11:29:44.777 回答
1

所以回答这个问题:不可能。

最后编写一个自己的方法来通过可分辨名称获取 DirectoryEntry,并指定凭据。在存在/不存在的两种情况下,我都得到了 DirectoryEntry 的一个实例。为了检查它是否是返回的有效对象,我做了一个简单的 try...catch 来查看它是否会导致异常。如果是,则无效。

讨厌的检查,但它的工作原理。太糟糕了,默认的 .net 方法 DirectoryEntry.Exists 没有提供重载来提供凭据,就像 DirectoryEntry 构造函数一样......

于 2010-11-26T12:42:58.627 回答
0

如果运行该进程的用户没有调用 DirectoryEntry.Exists 的权限,那么您可以使用模拟。

这可能会有所帮助(讨论 AD 上下文中的模拟): http: //www.codeproject.com/KB/system/everythingInAD.aspx

顺便说一句,如果您已经拥有可以访问您需要的所有内容的用户的凭据,为什么不只使用该用户的进程(例如 /runas)?

于 2010-11-26T10:07:40.380 回答