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

Her*_*des 10 .net c# active-directory directoryentry

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

if (DirectoryEntry.Exists(path)) {}
Run Code Online (Sandbox Code Playgroud)

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

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

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

Joe*_*lly 15

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


Gab*_*uci 6

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

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

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

\n

你可以像这样使用它:

\n
var ouExists = Exists("LDAP://hadoop.com/OU=Students,DC=hadoop,DC=com", "username", "password");\n
Run Code Online (Sandbox Code Playgroud)\n