繁体   English   中英

PrincipalContext LDAPS自签名证书

[英]PrincipalContext LDAPS Self-Signed Certificate

我们有一个应用程序,使用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,但它不起作用。 我在PrincipalContext构造函数上尝试了大量的变体,但是我们所做的一切都会导致连接失败,并出现此错误:

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服务器本身,因为通过这里讨论的方法尝试连接没有错误。 我不太习惯使用try ... catch来获取逻辑流程,而且我已经阅读了这个方法的一些其他问题(比如没有正确地尊重证书等),所以我试图用PrincipalContext来完成这个工作。 。

有人能在这里给我一些指导吗? 我在这个上疯了。

编辑:经过一些进一步的研究,看起来这可能是自签名证书的问题。

编辑2:在将其分解为X509链调用后,我收到了这个特定的错误:

PartialChain无法将证书链构建到受信任的根颁发机构。

看一下,您认为只需将CA添加为受信任的根,但这似乎无法解决问题。

我想知道这个CodeProject文章是否有帮助:

“最近,我遇到了使用System.DirectoryServices.DirectoryEntry连接到Novell eDirectory服务器的问题,因为证书是自签名的。当在ASP.NET应用程序中运行时,机器级证书存储区未被检查。所以,甚至虽然自签名证书位于受信任的存储中,但DirectoryEntry仍然拒绝建立连接。

对于这种情况,LdapConnection类是更好的选择,因为它允许用户手动验证证书。 请注意,在Windows窗体应用程序中运行时,DirectoryEntry方法可以使用受信任的自签名证书。“

使用LdapConnection,您可以使用自己的证书身份验证,如下所示:

LdapConnection con = new LdapConnection(new LdapDirectoryIdentifier("EDIRECTORYSERVER:636"));
con.SessionOptions.SecureSocketLayer = true;
con.SessionOptions.VerifyServerCertificate = 
   new VerifyServerCertificateCallback(ServerCallback);
con.Credential = new NetworkCredential(String.Empty, String.Empty);
con.AuthType = AuthType.Basic;

这样的验证回调:

public static bool ServerCallback(LdapConnection connection, X509Certificate certificate)
{
  try
  {
    X509Certificate expectedCert = 
         X509Certificate.CreateFromCertFile("C:\\certificates\\certificate.cer");

    if (expectedCert.Equals(certificate))
    {
        return true;
    }
    else
    {
        return false;
    }
  }
  catch (Exception ex)
  {
      return false;
  }
}

请查看Gabriel Luci的回答

您确定它支持SSL并且防火墙是否已打开以允许该连接?

LDAP使用端口389.LDAPS使用端口636。

如果安装了telnet客户端,则可以使用它来检查连接:

telnet yourdomain.com 636如果你得到一个空白的屏幕,它是有效的。 如果它无法连接,它会告诉你。

如果它已打开但仍然无效,则可能是使用自签名SSL证书。 检查Windows事件日志中是否存在与证书相关的错误。

我还使用Chrome来检查证书。 你必须像这样运行chrome:

chrome.exe --explicitly-allowed-ports = 636然后浏览到https://yourdomain.com:636并查看它是否为您提供任何证书错误。 然后你就可以看到证书了。 如果这是问题,您可以导入证书并明确信任它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM