Novell LDAP C# – Novell.Directory.Ldap – 有没有人让它工作?

我正在尝试使用Novell发布的库(Novell.Directory.Ldap)。 版本2.1.10。

到目前为止我做了什么:

  • 我测试了与应用程序( LdapBrowser )的连接并且它正在工作,所以它不是通信问题。

  • 它是用Mono编译的,但我正在使用Visual Studio。 所以用源创建了一个项目。 我还提到了对Mono.Security的引用,因为该项目取决于它。

  • 我在连接的错误捕获部分中评论了一个调用(freeWriteSemaphore(semId);),因为它抛出了更多exception。 我检查了那个调用做了什么,它只是一个错误跟踪机制。

  • 我按照Novell( http://www.novell.com/coolsolutions/feature/11204.html )文档中提供的基本步骤进行操作。

    //创建LdapConnection实例

    LdapConnection ldapConn = new LdapConnection(); ldapConn.SecureSocketLayer = ldapPort == 636;

    // Connect函数将创建与服务器的套接字连接

    ldapConn.Connect(ldapHost,ldapPort);

    //绑定function将用户对象凭据绑定到服务器

    ldapConn.Bind(用户DN,userPasswd);

  • 现在它正在崩溃Bind()函数。 我收到错误91。

那么,有人曾经使用过这个库并看到它有效吗? 如果是这样,你做了什么让它工作,是否需要一些特殊的配置? 有没有办法让它在没有Mono的.NET环境中工作(我可以引用Mono dll,但我不希望它安装在服务器上)?

(更新)连接在端口636上,因此使用SSL。 我查看了WireShark的通信,并与我从LDAP浏览器中获得的内容进行了比较。 我已经看到,SSL证书的通信步骤不是由LDAP库完成的。 那么,让它做到它应该做的最好的方法是什么?

(更新)我检查了文档,它表明它不支持SSL。 http://www.novell.com/coolsolutions/feature/11204.html

使用LdapConnection.Bind()对LDAP服务器进行身份validation。 我们仅支持明文身份validation。 尚未添加SSL / TLS支持。

但是文档的日期是2004年,从那时起,已经进行了许多更新。 并且库中有一个参数来定义连接是否使用SSL。 所以现在我很困惑。

(更新)找到了更新的文档: http : //developer.novell.com/documentation//ldapcsharp/index.html?page = / documentation //ldapcsharp/cnet/data/bqwa5p0.html 。 建立SSL连接的方式是在服务器上注册证书。 问题是我正在做的事情并不是绑定到特定的Novell服务器,因此必须动态获取证书。

我终于找到了一种方法来完成这项工作。

首先,这些post帮助我走上正轨: http : //directoryprogramming.net/forums/thread/788.aspx

其次,我得到了Novell LDAP库的编译dll,并使用了Mono.Security.Dll。

解决方案:

我将此函数添加到代码中

// This is the Callback handler - after "Binding" this is called public bool MySSLHandler(Syscert.X509Certificate certificate, int[] certificateErrors) { X509Store store = null; X509Stores stores = X509StoreManager.LocalMachine; store = stores.TrustedRoot; //Import the details of the certificate from the server. X509Certificate x509 = null; X509CertificateCollection coll = new X509CertificateCollection(); byte[] data = certificate.GetRawCertData(); if (data != null) x509 = new X509Certificate(data); //List the details of the Server //if (bindCount == 1) //{ Response.Write("CERTIFICATE DETAILS: 
"); Response.Write(" Self Signed = " + x509.IsSelfSigned + " X.509 version=" + x509.Version + "
"); Response.Write(" Serial Number: " + CryptoConvert.ToHex(x509.SerialNumber) + "
"); Response.Write(" Issuer Name: " + x509.IssuerName.ToString() + "
"); Response.Write(" Subject Name: " + x509.SubjectName.ToString() + "
"); Response.Write(" Valid From: " + x509.ValidFrom.ToString() + "
"); Response.Write(" Valid Until: " + x509.ValidUntil.ToString() + "
"); Response.Write(" Unique Hash: " + CryptoConvert.ToHex(x509.Hash).ToString() + "
"); // } bHowToProceed = true; if (bHowToProceed == true) { //Add the certificate to the store. This is \Documents and Settings\program data\.mono. . . if (x509 != null) coll.Add(x509); store.Import(x509); if (bindCount == 1) removeFlag = true; } if (bHowToProceed == false) { //Remove the certificate added from the store. if (removeFlag == true && bindCount > 1) { foreach (X509Certificate xt509 in store.Certificates) { if (CryptoConvert.ToHex(xt509.Hash) == CryptoConvert.ToHex(x509.Hash)) { store.Remove(x509); } } } Response.Write("SSL Bind Failed."); } return bHowToProceed; }

我在绑定过程中使用它

 // Create Connection LdapConnection conn = new LdapConnection(); conn.SecureSocketLayer = true; Response.Write("Connecting to:" + ldapHost); conn.UserDefinedServerCertValidationDelegate += new CertificateValidationCallback(MySSLHandler); if (bHowToProceed == false) conn.Disconnect(); if (bHowToProceed == true) { conn.Connect(ldapHost, ldapPort); conn.Bind(loginDN, password); Response.Write(" SSL Bind Successfull "); conn.Disconnect(); } quit = false; 

关键元素是使用SSL处理程序动态获取证书,并使用X509StoreManager.LocalMachine,以便在网站运行时能够保存和获取证书。

我来寻找解决类似问题的方法。 使用Novell网站上的相同代码时,我的绑定命令也会失败。 对我有用的解决方案是添加动态证书validation回叫。 你可以在这里阅读它。

  // Creating an LdapConnection instance LdapConnection ldapConn = new LdapConnection(); ldapConn.SecureSocketLayer = true; ldapConn.UserDefinedServerCertValidationDelegate += new CertificateValidationCallback(MySSLHandler); //Connect function will create a socket connection to the server ldapConn.Connect(ldapHost, ldapPort); //Bind function will Bind the user object Credentials to the Server ldapConn.Bind(userDN, userPasswd); // Searches in the Marketing container and return all child entries just below this //container ie Single level search LdapSearchResults lsc = ldapConn.Search("ou=users,o=uga", LdapConnection.SCOPE_SUB, "objectClass=*", null, false); while (lsc.hasMore()) { LdapEntry nextEntry = null; try { nextEntry = lsc.next(); } catch (LdapException e) { Console.WriteLine("Error: " + e.LdapErrorMessage); // Exception is thrown, go for next entry continue; } Console.WriteLine("\n" + nextEntry.DN); LdapAttributeSet attributeSet = nextEntry.getAttributeSet(); System.Collections.IEnumerator ienum = attributeSet.GetEnumerator(); while (ienum.MoveNext()) { LdapAttribute attribute = (LdapAttribute)ienum.Current; string attributeName = attribute.Name; string attributeVal = attribute.StringValue; Console.WriteLine(attributeName + "value:" + attributeVal); } } ldapConn.Disconnect(); Console.ReadKey(); } public static bool MySSLHandler(Syscert.X509Certificate certificate, int[] certificateErrors) { X509Store store = null; X509Stores stores = X509StoreManager.CurrentUser; //string input; store = stores.TrustedRoot; X509Certificate x509 = null; X509CertificateCollection coll = new X509CertificateCollection(); byte[] data = certificate.GetRawCertData(); if (data != null) x509 = new X509Certificate(data); return true; } 

91是“无法连接”。 尝试将服务器置于“ldap:// xxxx”格式,检查userDN是否设置正确(使用域等)。

我经常使用WireShark来查看网络级别的情况(它知道LDAP协议)。

我想我可能已经在另一个问题上向其他人提供了这个答案。

[关于LDAP的其他问题] [1]

我认为有两个问题:1)你想做什么样的约束? SSL? 明文? 匿名?

2)如何在eDirectory端配置LDAP绑定?

工具LDAP浏览器,您指的是此链接中的那个? 免费的LDAP浏览器

在eDirectory端,他们可以要求TLS进行所有LDAP通信,并且他们可以禁止匿名绑定。

您能否请求另一端的人员启用LDAP跟踪(使用启用了+ LDAP选项的DStrace,有关如何在Novell eDirectory上使用Dstrace的一些链接,请参阅:不同类型的Dstrace捕获并了解Identity Manager的DS跟踪。)

这通常会显示一条错误信息,可以启发你。

我猜是要么启用了需要TLS,要么你可能没有成功进行SSL绑定。

如果是这样,请尝试连接端口636,启用SSL,并为您尝试登录的用户提供完全限定的DN。

如果您尝试启用SSL,并且没有获得有关接受树CA的受信任根证书的弹出框,则可能是用户已过期或已损坏eDirectory服务器的CA或SSL证书。 (有许多原因可能很常见,需要花一点时间来修复)。

通常在Dstrace中,如果出现问题,您将看到有关SSL证书的错误。 本文将介绍Novell Identity Manager对过期证书的透视示例:证书已过期以及有关如何修复证书的一些详细信息。

下一种可能性是您指定的DN不太正确。

如果您需要更多帮助,请告诉我。

我致力于Forefront Identity Manager集成。 所以我写的代码总是来自一些调用客户端。 如果您尝试将应用程序打包以“随处”使用,则这可能不合适。

我只是想用一个简单的Novell服务器解决方案来更新这个线程,这些服务器启用了默认的TLS / SSL“机密性要求”选项。

1)确保从您绑定的Novell服务器获取SSL证书,并将这些证书注册到正在执行的客户端/服务器上的可信存储中。 通常有两个1用于IP和主机名依赖于您将调用(DNS优先)

2)使用System.DirectoryServices导入以下/添加引用; 使用System.DirectoryServices.Protocols;

3)这是一个片段。 确保选择AuthenticationTypes.SecureSocketsLayer,这是关键。

 // serverAddress = Server IP or DNS (Match SSL certificate) // ObjectDN = The DN of the user you are binding to // userName = Account which will be used to make the bind // password = password of the user which will make the bind // value = The value you wish to add to the attribute // Connect to the user in LDAP DirectoryEntry entry = new DirectoryEntry("LDAP://" + serverAddress + "/" + ObjectDN + "" , userName , password , AuthenticationTypes.SecureSocketsLayer); // Write the Updated attribute entry.Properties["attribute"].Value = value; // Read back the updated Attribute into a label label.Text = entry.Properties["attribute"].Value.ToString(); 

在我之前的post之后 – 如果您必须使用安全连接,请尝试使用ldaps://作为服务器地址的前缀。

如果没有SSL / TLS支持,您可以尝试这个 – 指南和OpenLDAP库的.NET包装器。

重要的一点 – 在OpenLDAP中有TLS安全级别的设置,因此如果您的LDAP服务器具有自签名证书,您必须在客户端导入它或将TLS设置为不检查当然不太安全的签名机构* )。