繁体   English   中英

LdapConnection与PrincipalContext

[英]LdapConnection vs. PrincipalContext

我有以下两种使用LDAP和LDAPS验证用户的实现,我想知道哪个更好/更正确。 对于记录,这两个都适用于SSL和非SSL连接。

我也很好奇,因为在Non-SSL PrincipalContext版本上使用Wireshark观看时,我仍然看到端口636上的流量。在四种组合中( Non-SSL LdapConnectionSSL LdapConnectionNon-SSL PrincipalContextSSL PrincipalContext ),它是只有一个在389和636端口都有流量,而不只是一个或另一个。 可能是什么导致了这个?

LDAP连接方法:

bool userAuthenticated = false;
var domainName = DomainName;

if (useSSL)
{
  domainName = domainName + ":636";
}

try
{
  using (var ldap = new LdapConnection(domainName))
  {
    var networkCredential = new NetworkCredential(username, password, domainName);
    ldap.SessionOptions.VerifyServerCertificate = new VerifyServerCertificateCallback((con, cer) => true);
    ldap.SessionOptions.SecureSocketLayer = useSSL;
    ldap.SessionOptions.ProtocolVersion = 3;
    ldap.AuthType = AuthType.Negotiate;
    ldap.Bind(networkCredential);
  }

  // If the bind succeeds, we have a valid user/pass.
  userAuthenticated = true;
}
catch (LdapException ldapEx)
{
  // Error Code 0x31 signifies invalid credentials, anything else will be caught outside.
  if (!ldapEx.ErrorCode.Equals(0x31))
  {
    throw;
  }
}

return userAuthenticated;

PrincipalContext方法:

bool userAuthenticated = false;
var domainName = DomainName;

if (useSSL)
{
  domainName = domainName + ":636";
  ContextOptions options = ContextOptions.SimpleBind | ContextOptions.SecureSocketLayer;

  using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, domainName, null, options))
  {
    userAuthenticated = pc.ValidateCredentials(username, password, options);
  }
}
else
{
  using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, domainName))
  {
    userAuthenticated = pc.ValidateCredentials(username, password);
  }
}

return userAuthenticated;

@ DTI-Matt,在上面的示例中,您使用始终返回true VerifyServerCertificate回调。 这基本上违反了通过SSL连接到LDAP的目的,因为没有执行真正的证书检查。

虽然您可以使用X509Chain和/或X509Certificate2类实现真正的证书检查,但似乎PrincipalContext为您处理检查。

总而言之, LdapConnectionPrincipalContext提供了非常类似的功能,通过普通或SSL连接连接到LDAP服务器。 您必须为LdapConnection更多手写代码才能正常工作。 另一方面, PrincipalContext为您提供相同的功能,只需较少的代码即可手动编写。

请注意,非SSL PrincipalContext与端口636(您的默认LDAP over SSL端口)的连接可能是由于此类尝试尽可能安全地连接的事实。

这就是我们最终解决的问题,即SSL /非SSL。

public bool UserValid(string username, string password, bool useSSL)
{
    bool userAuthenticated = false;
    var domainName = DomainName;

    if (useSSL)
    {
        domainName = domainName + ":636";
    }

    try
    {
        using (var ldap = new LdapConnection(domainName))
        {
            var networkCredential = new NetworkCredential(username, password, DomainName); // Uses DomainName without the ":636" at all times, SSL or not.
            ldap.SessionOptions.VerifyServerCertificate += VerifyServerCertificate;
            ldap.SessionOptions.SecureSocketLayer = useSSL;
            ldap.AuthType = AuthType.Negotiate;
            ldap.Bind(networkCredential);
        }

        // If the bind succeeds, we have a valid user/pass.
        userAuthenticated = true;
    }
    catch (LdapException ldapEx)
    {
        // Error Code 0x31 signifies invalid credentials, so return userAuthenticated as false.
        if (!ldapEx.ErrorCode.Equals(0x31))
        {
            throw;
        }
    }

    return userAuthenticated;
}

private bool VerifyServerCertificate(LdapConnection connection, X509Certificate certificate)
{
    X509Certificate2 cert = new X509Certificate2(certificate);

    if (!cert.Verify())
    {
        // Could not validate potentially self-signed SSL certificate. Prompting user to install certificate themselves.
        X509Certificate2UI.DisplayCertificate(cert);

        // Try verifying again as the user may have allowed the certificate, and return the result.
        if (!cert.Verify())
        {
            throw new SecurityException("Could not verify server certificate. Make sure this certificate comes from a trusted Certificate Authority.");
        }
    }

    return true;
}

暂无
暂无

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

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