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