多个 LDAP 连接与 C# DirectoryEntry class

Multiple LDAP connecitons with C# DirectoryEntry class

我正在使用 DirectoryEntry class 进行 LDAP 身份验证。当我使用单个 LDAP 连接字符串时它工作正常。但是,一旦我开始在多个线程上为多个 LDAP 连接字符串执行代码,它就会开始随机抛出身份验证异常,即使用户名和密码是正确的。 我正在使用以下代码。

public bool IsAuthenticated(string path, string domain, string group, string username, string pwd)
{
    string domainAndUsername = domain + @"\" + username;

    LogManager.Application.DebugFormat("Inside IsAuthenticated for User {0} from Domain {1} and Group {2} of Path {3} ", username, domain, group, path);

    try
    {
        using (DirectoryEntry entry = new DirectoryEntry(path, domainAndUsername, pwd))
        {

            entry.AuthenticationType = AuthenticationTypes.Secure;
            entry.RefreshCache();
            //Bind to the native AdsObject to force authentication.
            object obj = entry.NativeObject;

            using (DirectorySearcher search = new DirectorySearcher(entry))
            {

                search.Filter = "(SAMAccountName=" + username + ")";
                search.PropertiesToLoad.Add("cn");
                SearchResult result = search.FindOne();

                if (null == result)
                {
                    LogManager.Application.ErrorLogFormat("User {0} is not available in Domain {1}", username, domain);
                    return false;
                }
            }
            LogManager.Application.DebugFormat("User {0} is available in Domain {1}", username, domain);
            return true;
        }
    }
    catch (Exception ex)
    {
        LogManager.Application.ErrorLogFormat("Exception occured while authenticating user {0} : Error {1} ", username, ex.Message);
        return false;
    }
}

此功能通过 ASMX 网络服务公开。此 Web 服务由多个用户同时执行。每个用户提供路径 (LDAP://{IP}/DC={Domain},DC=COM)、域和凭据。因此同时为多个 LDAP 连接执行代码。

更新:

这是调用上述函数的 ASMX 网络服务函数:

public class ValidateUserService : System.Web.Services.WebService
{

    [WebMethod]
    public Models.AuthenticationToken IsUserAuthenticated(string username, string password, string partnerName)
    {
        string path;
        string group;
        string domain;
        // Internal Code to pull the domain name, group and path from the db with help of partnerName.
        //each partner will have different path (LDAP conenction string) and domain.
        bool isAuthenticated = IsAuthenticated(path, domain, group, username, password);

    }
}

我观察到的是,当来自不同 AD 的多个用户尝试执行此代码时,它会随机抛出身份验证错误。 如您所见,代码没有任何静态变量。因此,对于每次调用,它都会创建 DirectoryEntry 的新实例。因此,在更高级别上,此设置代码应该适用于多个 LDAP 连接。

话虽如此,有人见过这种行为吗?在内部,.net 框架是否跨多个 DirectoryEntry 实例共享数据?单个进程可以同时拥有多个 LDAP 连接吗? 非常感谢任何帮助、建议或指点。

我已经找到解决该问题的方法,如果其他人遇到同样的问题,我会发布它。我尝试了以下方法来处理 AD/LDAP:

  1. 使用 DirectoryEntry class
  2. 使用 LdapConnection 和 NetworkCredential class
  3. 使用 PrincipalContext class

我观察到的是,如果应用程序同时与多个 AD 服务器一起工作并同时打开与多个 AD 服务器的连接,则 DirectoryEntry 方法不起作用。对于有效凭据,它会抛出“未经授权的访问”异常。我的猜测是某些 data/variables 是共享的,它会尝试根据不正确的 AD 服务器对用户进行身份验证。我查看了汇编代码并确认它使用了静态变量。这可能是真正的原因,但不能 100% 确定。 如果应用程序需要同时打开到多个 AD 服务器的连接,我的解决方法是使用其他两种方法。在过去的大约六个月里,我用大约 10 个同时连接对它进行了测试,它工作正常。

希望这对遇到同样问题的人有所帮助。