给定用户名、密码和子域名,如何获取用户账户的顶级域名?

Given user id, password, and a subdomain name, how can I obtain the top-level domain name for a user account?

我正在编写一个在 Win 7 客户机上运行的程序(WinFormsC#)。它从用户那里获取凭据(用户 ID、密码和子域名),并使用它们对程序远程连接到的其他服务器进行身份验证(通过 Active Directory)。其他服务器所在的域与 Win 7 客户端计算机所在的域不同。

使用 NetworkCredentialLdapDirectoryIdentifierLdapConnection 类,我可以使用不超过用户 ID、密码和子域名 (请参阅 S.O 的答案。Why does Active Directory validate last password?)。

例如,对于用户帐户 ssmith@xyz.gov,我只需要提供 ssmith(用户 ID)、ssmith 的密码和 xyzsubdomain).我不需要提供 top-level domain name(在本例中为 gov)。

现在,我想以编程方式获取此用户帐户的 top-level domain name(在本例中为 gov)。我检查了 NetworkCredentialLdapDirectoryIdentifierLdapConnection 类 的属性和方法。我查看了 System.DirectoryServices.Protocols Namespace 中的其他 类。我看不到以编程方式获取 top-level domain name.

的方法

给定 user idpasswordsubdomain 名称,如何获取用户帐户的 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;
}

绑定成功后,域的完整 DNS 名称将在 LdapConnection 对象中:

var domain = connection.SessionOptions.DomainName;

在这种情况下,那将是 "xyz.gov"。如果你只需要 "gov",那么你可以只取最后一个点之后的所有内容:

var tld = domain.Substring(domain.LastIndexOf('.') + 1);