使用的DirectoryServices跨域认证 [英] Cross Domain Authentication using DirectoryServices

查看:310
本文介绍了使用的DirectoryServices跨域认证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要为我的Intranet Web应用程序的方法将使用的DirectoryServices 用户进行身份验证,无论是对一个默认域,或用户指定的一个。

I need to create a method for my intranet web application that will authenticate a user using DirectoryServices, either against a default domain, or a user specified one.

在我的登录表单,用户将能够要么会给那里的凭据用户名密码域\\用户名密码
当用户在相同的域中的网络服务器,是相当straightfoward第一情况下,可以使用。在code我用的是:

On my login form the user will be able to either give there credentials in the form of "username" and "password" or "domain\username" and "password" The first case can be used when the user is in the same domain as the webserver and is quite straightfoward. The code I use is:

 string domain = "";
 // Code to check if the username is in form of "domain\user" 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构造的用户名和密码才能在我尝试访问另一个域情况下,调用绑定。

I pass the username and password to the PrincipalContext constructor in order to bind the call in cases where I try to access another domain.

有关本地域中code正常工作。然而,当我尝试检查针对正在通过用户名指定的另一个域,然后我得到一个服务器无法联系的错误。

For the local domain the code works fine. However when I try to check against another domain that is being specified through the username, then I get a "Server could not be contacted" error.

我也使用不同的尝试 ContextOptions ContextOptions.SimpleBind ContextOptions.Negotiate 但我似乎总是会得到相同的结果。

I also tried using different ContextOptions such as ContextOptions.SimpleBind or ContextOptions.Negotiatebut I always seem to be getting the same result.

我要实现这一点,因为应用程序被运到不同客户,采用单域或多个域环境。
有没有别的东西,我应该在远程域案件指定?的code需要灵活,因为这将在各种环境中部署。

I need to implement this, since the application is being shipped to various customers, with either single domain or multiple domain environments. Is there something else I should specify in cases of "remote" domains? The code needs to be flexible since this will be deployed in various environments.

感谢

修改:我必须指出,我preFER用做 DirectoryServices.AccountManagement PrincipalContext 以利用其他功能,它提供了为好。

EDIT: I must point out, that I prefer to do it using DirectoryServices.AccountManagement and PrincipalContext in order to take advantage of other functionality it provides as well.

另外,不得不提的就是对我的测试中,我的开发机器上10.0.0。*网络和I测试对第二区域是在10.0.1。*。我有一个路线,同时,我可以使用LDAP客户端连接succesfuly,所以问题是,为什么我无法通过我的asp.net应用程序连接到域。

Also, I must mention that for my tests, my Dev machine is on a 10.0.0.* network and the second domain I test against is on a 10.0.1.*. I have a route and all, and I can succesfuly connect using an ldap client, so the question is why I cannot connect to the domain via my asp.net application.

推荐答案

我想出了这个解决问题的办法。

I have come up with this solution to the problem.

为了支持多个域,无论是在信任关系,甚至在隔离的网络,首先我在web.config中列出域和域控制器增加了一个NameValueCollection中。

In order to support multiple domains, either in trust relationships or even in isolated networks, first of all I added a NameValueCollection in my web.config to list the domains and their domain controllers.

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

(上的配置除了在<一个更多信息href=\"http://stackoverflow.com/questions/338242/how-do-i-store-a-dictionary-object-in-my-web-config-file\">this所以问题)

然后下一步是读取用户的凭据域在我的问题提了道路。我们已经有了我试着查找从配置值,根据域控制器的域名,以获得正确的LDAP连接字符串。所以,我的方法是这样的:

Then the next step was to read the domain from the User's credentials in the way I mention in the question. Having gotten the domain I try to lookup the according domain controller from the configuration values, in order to get the proper LDAP connection string. So my method is this:

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

Once I get back the proper connection string I make a new call in order to authenticate the user, by addressing the proper 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();

从这点上我也可以执行所有其他疑问我想,如用户的组成员等。

From this point on I can also perform all the other queries I want such as the user's group membership etc.

由于调用远程域需要绑定到用户,我用的是呼唤的用户凭据。通过这种方式获取用户的身份验证,并呼叫被绑定到特定的用户。此外,我指定一个默认的域,让用户提供他们的凭据,而无需指定域的情况。

Since the call to the remote domains needs to be bound to a user, I use the "calling" users credentials. This way the user get's authenticated and the Call is bound to the specific user. Furthermore, I specify a "default" domain, for cases where users provide their credentials without specifying the domain.

我没能然而,这使用PrincipalContext因为我想,但光明的一面,这种解决方案也适用于旧的.NET 2.0应用程序也是如此。

I did not manage to this however using the PrincipalContext as I wanted, but on the bright side, this solution is also applicable for older .NET 2.0 applications as well.

我不知道,这是解决问题的最佳解决方案,但它似乎在我们目前执行的测试工作。

I am not sure that this is the best solution to the problem, however it seems to work in the tests we have so far performed.

这篇关于使用的DirectoryServices跨域认证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆