如何使用凭据提供DirectoryEntry.Exists?

时间:2010-11-26 10:03:00

标签: c# .net active-directory directoryentry

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

if (DirectoryEntry.Exists(path)) {}

当然,它没有任何重载来提供凭据。因为,如果没有提供凭据,我会得到以下例外:

  

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

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

6 个答案:

答案 0 :(得分:14)

在这种情况下,你不能像你说的那样使用静态方法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; 
}

答案 1 :(得分:2)

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

DirectoryEntry.Exists Does Not Accept Credentials

答案 2 :(得分:2)

我知道这是一个古老的问题,但是source code is now available可以使您仅窃取并修改™即可创建一个接受凭据的版本:

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的方法,不能被像我们这样的凡人使用。相反,我只是得到了NativeObjectcalls Bind() for us属性。

您可以这样使用:

var ouExists = Exists("LDAP://hadoop.com/OU=Students,DC=hadoop,DC=com", "username", "password");

答案 3 :(得分:1)

答案 4 :(得分:1)

回答这个问题:不可能。

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

令人讨厌的检查,但它确实有效。太糟糕的默认.net方法DirectoryEntry.Exists没有像DirectoryEntry构造函数那样提供提供凭据的重载......

答案 5 :(得分:0)

如果运行该进程的用户无权调用DirectoryEntry.Exists,则可以使用模拟。

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

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