gpt4 book ai didi

c# - Windows 服务 LdapException : The LDAP server is unavailable

转载 作者:行者123 更新时间:2023-12-03 19:25:50 33 4
gpt4 key购买 nike

我有一个 Windows 服务,它通过 WCF 向 Windows 窗体应用程序提供数据。该服务还负责用户身份验证,通过公司 Active Directory 服务器使用 LDAP 验证用户密码。

问题是它可以工作数周(甚至数月),然后发生某些事情并且 LDAP 用户身份验证失败并出现以下异常,直到我重新启动服务:

System.DirectoryServices.AccountManagement.PrincipalServerDownException: The server could not be contacted. 
---> System.DirectoryServices.Protocols.LdapException: The LDAP server is unavailable.
at System.DirectoryServices.Protocols.LdapConnection.Connect()
at System.DirectoryServices.Protocols.LdapConnection.SendRequestHelper(DirectoryRequest request, Int32& messageID)
at System.DirectoryServices.Protocols.LdapConnection.SendRequest(DirectoryRequest request, TimeSpan requestTimeout)
at System.DirectoryServices.Protocols.LdapConnection.SendRequest(DirectoryRequest request)
at System.DirectoryServices.AccountManagement.PrincipalContext.ReadServerConfig(String serverName, ServerProperties& properties)
--- End of inner exception stack trace ---
at System.DirectoryServices.AccountManagement.PrincipalContext.ReadServerConfig(String serverName, ServerProperties& properties)
at System.DirectoryServices.AccountManagement.PrincipalContext.DoServerVerifyAndPropRetrieval()
at System.DirectoryServices.AccountManagement.PrincipalContext..ctor(ContextType contextType, String name, String container, ContextOptions options, String userName, String password)
at System.DirectoryServices.AccountManagement.PrincipalContext..ctor(ContextType contextType, String name, String userName, String password)
at SMSTModel.Authentication.ActiveDirectory.IsUserAllowed(String username, String password)

服务重启解决了这个问题。
public static bool IsUserAllowed(string username, string password)
{
String localDomain = Domain.GetComputerDomain().Name;
string userDomain = null;
string user = username;
if (user.Contains(@"\"))
{
userDomain = user.Substring(0, user.IndexOf("\\"));
user = user.Substring(user.IndexOf("\\") + 1);
}

userDomain = userDomain != null ? userDomain : localDomain;
using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, userDomain, user, password))
{
bool credOk = pc.ValidateCredentials(user, password);
if (!credOk)
return false;
using (UserPrincipal userP = UserPrincipal.FindByIdentity(pc, user))
{
if (userP != null)
{
using (PrincipalContext pc1 = new PrincipalContext(ContextType.Domain, localDomain))
{
using (GroupPrincipal groupPrincipal = new GroupPrincipal(pc1))
{
groupPrincipal.Name = "APP_*";
using (PrincipalSearcher principalSearcher = new PrincipalSearcher(groupPrincipal))
foreach (Principal found in principalSearcher.FindAll())
{
if (found.Name == "APP_Group" && found is GroupPrincipal && userP.IsMemberOf((GroupPrincipal)found))
{
return true;
}
}
}
}
}
}
}

return false;
}

关于它为什么会发生以及如何解决它的任何想法?

最佳答案

看起来这里发生了异常:

using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, userDomain, user, password))

那么你知道什么 userDomain正在使用的是?看起来您的环境中可能有多个域,那么您的所有域都会发生这种情况,还是只有一个域?

在我们的环境中,我见过我们的 AD 管理员停用域 Controller 的情况,但由于某种原因该服务器仍然出现在 DNS 中。换句话说,如果我在命令行中进行 DNS 查找:
nslookup example.com

其中一个 IP 用于退役的 DC。

在你的情况下,这是一种可能性。如果它选择了一个错误的 IP 地址,那么重新启动应用程序将使其进行另一次 DNS 查找,这可能会在列表顶部返回一个不同的 IP 地址,并且事情会再次运行。

要弄清这个问题的根源,您真的必须观察它停止工作时发生的情况。如果您还没有安装,请安装 Wireshark在您的服务器上。当它停止工作时,使用 Wireshark 使用端口 389(默认 LDAP 端口)查找流量并查看它尝试连接到哪个 IP。

关于c# - Windows 服务 LdapException : The LDAP server is unavailable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57321596/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com