我们有一个应用程序,使用 LDAP、通过 IP 地址、通过 VPN 隧道对远程 AD 进行身份验证,使用以下代码:
using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, ldap.Host, ldap.Path.Replace("/", ""), ContextOptions.Negotiate, UserName, Password))
{
using (UserPrincipal user = UserPrincipal.FindByIdentity(pc, domainAndUsername))
{
if (user != null)
{
SAMAccountName = user.SamAccountName;
retVal = true;
}
}
}
这对于普通的非 SSL LDAP 非常有效。但是,我们遇到过需要通过 SSL 连接到 LDAPS 的情况,但它不起作用。我已经在 PrimaryContext 构造函数上尝试了很多变体,但我们所做的一切都会导致连接失败,并出现以下错误:
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.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)
我们知道这不是 LDAP 服务器本身,正如所讨论的方法所尝试的那样here https://stackoverflow.com/a/10853221/1048068连接没有错误。我不太习惯使用 try...catch 进行逻辑流,并且我已经阅读了此方法的一些其他问题(例如没有正确尊重证书等),因此我尝试使用 PrimaryContext 来实现此操作。
有人可以在这里给我一些指导吗?我对这个快要疯了。
EDIT:经过进一步研究,这似乎可能是自签名证书的问题。
EDIT 2:将其分解为 X509 链调用后,我收到以下特定错误:
PartialChain 无法为受信任的根颁发机构构建证书链。
看到这一点,您可能会认为只需将 CA 添加为受信任的根即可,但这似乎并不能解决问题。