【发布时间】:2018-05-03 15:31:02
【问题描述】:
我正在编写一个在Win 7 客户端机器上运行的程序(WinForms、C#)。它从用户那里获取凭据(用户 ID、密码和子域名),并使用它们向程序远程连接的其他服务器进行身份验证(通过Active Directory)。其他服务器所在的域与Win 7 客户端计算机所在的域不同。
使用 NetworkCredential、LdapDirectoryIdentifier 和 LdapConnection 类,我可以使用不超过用户 ID、密码和子域名的凭据来测试凭据(请参阅 S.O.Why does Active Directory validate last password? 的答案)。
例如,对于用户帐户ssmith@xyz.gov,我只需提供ssmith(用户ID)、ssmith 的密码和xyz(subdomain)。我不需要提供top-level domain name(在这种情况下为gov)。
现在,我想以编程方式获取此用户帐户的top-level domain name(在本例中为gov)。我检查了NetworkCredential、LdapDirectoryIdentifier 和LdapConnection 类的属性和方法。我查看了System.DirectoryServices.Protocols Namespace 中的其他类。我没有看到以编程方式获取top-level domain name 的方法。
给定user id、password 和subdomain 名称,我如何获取用户帐户的top-level domain name?
这是我的代码。给定 ssmith@xyz.gov 的用户帐户,我的调用如下所示(星号表示 SecureString 密码)
bool result = ValidateCredentials("ssmith","******", "xyz");
这是我的方法代码。
private const int ERROR_LOGON_FAILURE = 0x31;
private bool ValidateCredentials(string username, SecureString ssPassword, string domain)
{
//suports secure string
NetworkCredential credentials = new NetworkCredential(username, ssPassword, domain);
LdapDirectoryIdentifier id = new LdapDirectoryIdentifier(domain);
using (LdapConnection connection = new LdapConnection(id, credentials, AuthType.Kerberos))
{
connection.SessionOptions.Sealing = true;
connection.SessionOptions.Signing = true;
try
{
// The only way to test credentials on a LDAP connection seems to be to attempt a
// Bind operation, which will throw an exception if the credentials are bad
connection.Bind();
}
catch (LdapException lEx)
{
credentials = null;
id = null;
if (ERROR_LOGON_FAILURE == lEx.ErrorCode)
{
return false;
}
throw;
}
}
credentials = null;
id = null;
return true;
}
【问题讨论】:
-
如果您还不知道域,您的
LdapDirectoryIdentifier对象声明是什么样的? -
@GabrielLuci:我为调用我的方法和方法添加了代码。请看上面。用户将知道子域
xyz,但可能不知道顶级域gov。而且,LdapDirectoryIdentifier在这种情况下显然不需要顶级域 -
那么
domain变量不是已经包含顶级域的名称了吗? -
没有。只是子域名。详细信息在我的问题中
-
我明白了。您正在使用域的简称。
标签: c# winforms active-directory ldap domain-name