使用DirectoryServices进行跨域身份验证



我需要为我的intranet web应用程序创建一个方法,该方法将使用DirectoryServices对用户进行身份验证,无论是针对默认域还是用户指定的域。

在我的登录表单上,用户可以以"username""password"或"domainusername""password"的形式提供凭据第一种情况可以在用户与Web服务器位于同一域并且非常直接的情况下使用。我使用的代码是:

 string domain = "";
 // Code to check if the username is in form of "domainuser" or "user"
 string username = ParseUsername(username, out domain);
 if(domain == "")
    domain = defaultDomain;
 PrincipalContext context = new PrincipalContext(ContextType.Domain, domain, username, password); 
 bool IsAuthenticated = context.ValidateCredentials(username, password)

我将用户名和密码传递给PrincipalContext构造函数,以便在尝试访问另一个域时绑定调用。

对于本地域,代码运行良好。然而,当我试图检查通过用户名指定的另一个域时,我会收到一个"无法联系服务器"的错误。

我还尝试使用不同的ContextOptions,如ContextOptions.SimpleBindContextOptions.Negotiate,但似乎总是得到相同的结果。

我需要实现这一点,因为应用程序正通过单域或多域环境交付给各种客户。在"远程"域的情况下,我还应该指定其他内容吗?代码需要灵活,因为它将部署在各种环境中。

感谢

EDIT:我必须指出,我更喜欢使用DirectoryServices.AccountManagementPrincipalContext进行编辑,以便利用它提供的其他功能。

此外,我必须提到,对于我的测试,我的Dev机器在10.0.0.*网络上,我测试的第二个域在10.0.1.*网络上。我有一个路由和所有的,我可以使用ldap客户端成功连接,所以问题是为什么我不能通过asp.net应用程序连接到域。

我已经想出了这个问题的解决方案。

为了支持多个域,无论是在信任关系中,还是在隔离网络中,首先我在web.config中添加了一个NameValueCollection,以列出域及其域控制器。

  <domains>
    <add key="domain1" value="10.0.0.1"/>
    <add key="domain2" value="10.0.1.11"/>
  </domains>

(在这个问题中添加配置的更多信息)

然后下一步是按照我在问题中提到的方式从用户的凭据中读取域。获得域后,我尝试从配置值中查找相应的域控制器,以便获得正确的LDAP连接字符串。所以我的方法是:

private string GetLDAPConnection(string a_Domain, string a_Username, string a_Password)
{
    // Get the domain controller server for the specified domain
    NameValueCollection domains = (NameValueCollection)ConfigurationManager.GetSection("domains");
    string domainController = domains[a_Domain.ToLower()];
    string ldapConn = string.Format("LDAP://{0}/rootDSE", domainController);
    DirectoryEntry root = new DirectoryEntry(ldapConn, a_Username, a_Password);
    string serverName = root.Properties["defaultNamingContext"].Value.ToString();
    return string.Format("LDAP://{0}/{1}", domainController, serverName);
}

一旦我得到正确的连接字符串,我就会进行一个新的调用,以便通过寻址正确的LDAP 来验证用户

    ...
    string ldapConn = GetLDAPConnection(domain, username, a_Password);                             
    DirectoryEntry entry = new DirectoryEntry(ldapConn, username, a_Password);        
    try
    {
        try
        {
            object obj = entry.NativeObject;
        }
        catch(DirectoryServicesCOMException comExc)
        {
            LogException(comExc);
            return false;
        }
        DirectorySearcher search = new DirectorySearcher(entry);
        search.Filter = string.Format("(SAMAccountName={0})", username);
        search.PropertiesToLoad.Add("cn");
        SearchResult result = search.FindOne();

从这一点开始,我还可以执行我想要的所有其他查询,例如用户的组成员资格等。

由于对远程域的调用需要绑定到用户;呼叫";用户凭据。通过这种方式,用户可以获得身份验证,并且调用绑定到特定用户。此外,我指定一个";默认";域,用于用户在不指定域的情况下提供凭据的情况。

然而,我并没有按照自己的意愿使用PrincipalContext来实现这一点,但从好的方面来看,该解决方案也适用于较旧的.NET 2.0应用程序。

我不确定这是否是解决这个问题的最佳方案,但它似乎在我们迄今为止进行的测试中起作用。

我不知道为什么我被否决了,但我认为这可能是错误的,您代码所在的服务器/域与您试图联系的域之间的信任级别可能无法建立。我无法向你解释为什么会发生这种情况。

[EnvironmentPermissionAttribute(SecurityAction.LinkDemand, Unrestricted = true)]

你可以尝试在你的功能上添加这个,看看它是否能帮助你完成,但除此之外,我不明白为什么在WinNT域上搜索所有可能的用户是错误的。希望这能帮助

相关内容

  • 没有找到相关文章

最新更新