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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/386982/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 01:30:25  来源:igfitidea点击:

Novell LDAP C# - Novell.Directory.Ldap - Has anybody made it work?

c#.netldapnovell

提问by ceetheman

I'm trying to use the library released by Novell (Novell.Directory.Ldap). Version 2.1.10.

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

What I've done so far:

到目前为止我所做的:

  • I tested the connection with an application (LdapBrowser) and it's working, so its not a communication problem.

  • It's compiled in Mono, but I'm working with Visual Studio. So created a project with the sources. I also included a reference to Mono.Security, because the project depended on it.

  • I commented a call (freeWriteSemaphore(semId); ) in the error catching part of the connection, because it was throwing more exceptions. I checked what that call did, and its just a error tracing mechanism.

  • I followed the basics steps provided in the documentation by Novell (http://www.novell.com/coolsolutions/feature/11204.html).

    // Creating an LdapConnection instance

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

    //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);

  • Right now it's crashing at the Bind() function. I get the error 91.

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

  • 它是用 Mono 编译的,但我正在使用 Visual Studio。所以创建了一个带有源的项目。我还引用了 Mono.Security,因为项目依赖于它。

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

  • 我遵循了 Novell ( http://www.novell.com/coolsolutions/feature/11204.html)文档中提供的基本步骤。

    // 创建一个 LdapConnection 实例

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

    //Connect 函数将创建一个到服务器的套接字连接

    ldapConn.Connect(ldapHost,ldapPort);

    //绑定函数将用户对象Credentials绑定到服务器

    ldapConn.Bind(userDN,userPasswd);

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

So, has someone ever used this library and seen it work? If so, what did you do to make it work, is there some special configuration needed? Is there a way to make it work in .NET environment without Mono (I can have references to Mono dlls, but I don't want it to be installed on the server)?

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

(UPDATE) The connection is on port 636, thus using SSL. I checked with WireShark the communication and compared with what I get from LDAP Browser. I've seen that the step where the SSL certicate is communicated, is not done by the LDAP library. So, what is the best way to make it do what its supposed to?

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

(UPDATE) I checked the documentation and it's indicating that it doesn't support SSL. http://www.novell.com/coolsolutions/feature/11204.html

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

Authenticate to the LDAP server with LdapConnection.Bind(). We support only cleartext authentication. SSL/TLS support is yet to be added.

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

But the documentation date from 2004, and since then, many updates have been made. And there is a parameter in the library to define if the connection uses SSL. So now I'm confused.

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

(UPDATE) Found a more up-to-date documentation : http://developer.novell.com/documentation//ldapcsharp/index.html?page=/documentation//ldapcsharp/cnet/data/bqwa5p0.html. The way the SSL connection is made, is by registering the certificate on the server. The problem is that what I'm doing is not bound to a specific Novell server, so the certificate must be obtained dynamically.

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

采纳答案by ceetheman

I finally found a way to make this work.

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

First, theses posts helped me get on the right track : http://directoryprogramming.net/forums/thread/788.aspx

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

Second, I got a compiled dll of the Novell LDAP Library and used the Mono.Security.Dll.

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

The solution:

解决方案:

I added this function to the code

我在代码中添加了这个函数

// 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("<b><u>CERTIFICATE DETAILS:</b></u> <br>");
            Response.Write("  Self Signed = " + x509.IsSelfSigned + "  X.509  version=" + x509.Version + "<br>");
            Response.Write("  Serial Number: " + CryptoConvert.ToHex(x509.SerialNumber) + "<br>");
            Response.Write("  Issuer Name:   " + x509.IssuerName.ToString() + "<br>");
            Response.Write("  Subject Name:  " + x509.SubjectName.ToString() + "<br>");
            Response.Write("  Valid From:    " + x509.ValidFrom.ToString() + "<br>");
            Response.Write("  Valid Until:   " + x509.ValidUntil.ToString() + "<br>");
            Response.Write("  Unique Hash:   " + CryptoConvert.ToHex(x509.Hash).ToString() + "<br>");
            // }

            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;
        }

And i used it in the binding process

我在绑定过程中使用了它

// 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;

The key elements are using the SSL Handler to dynamically obtain the Certificate, and using X509StoreManager.LocalMachine so that when the website is running its able to save and fetch the certificates.

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

回答by Dmitry Khalatov

91 is "cannot connect". Try to put the server in "ldap://x.x.x.x" format, check that userDN is set properly (with domain etc).

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

I am often using WireSharkto see what is going on at the network level (it is aware of LDAP protocol).

我经常使用WireShark来查看网络级别发生了什么(它知道 LDAP 协议)。

回答by geoffc

I think I may have already offered this answer to someone else in a different question.

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

[OtherQuestion on LDAP][1]

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

Two issues I think: 1) What kind of bind are you trying to do? SSL? Clear text? Anonymous?

我认为有两个问题:1)你想做什么类型的绑定?SSL?清晰的文字?匿名的?

2) How is it configured on the eDirectory side for LDAP binds?

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

The tool LDAP Browser, are you referring to the one at this link? Free LDAP Browser

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

On the eDirectory side, they can require TLS for all LDAP communication, and they can disallow Anonymous binds.

在 eDirectory 方面,它们可以要求所有 LDAP 通信都使用 TLS,并且可以禁止匿名绑定。

Can you ask the folks at the other end to enable LDAP tracing (Using DStrace with the +LDAP option enabled, some links for how to use Dstrace on Novell eDirectory look at: Different types of Dstrace Capturing and understand DS Trace for Identity Manager.)

您能否要求另一端的人启用 LDAP 跟踪(使用 Dstrace 并启用 +LDAP 选项,有关如何在 Novell eDirectory 上使用 Dstrace 的一些链接请查看:不同类型的 Dstrace 捕获和了解身份管理器的 DS 跟踪。)

That usually will show an error message that will enlighten you.

这通常会显示一条错误消息,让您有所启发。

My guess is either Require TLS is enabled, and you might not be doing a successful SSL bind.

我的猜测是 Require TLS 已启用,并且您可能没有成功进行 SSL 绑定。

If so, try to connect on port 636, with SSL enabled, and a fully qualified DN for the user you are trying to login as.

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

If you are trying with SSL enabled, and you are not getting a pop up box about accepting the tree CA's trusted root certficate, then perhaps the CA or the SSL certificate taht the eDirectory server is user has expired or is broken. (There are any number of causes for this that can be common, and take but a moment to fix).

如果您尝试启用 SSL,并且没有收到关于接受树 CA 的受信任根证书的弹出框,则可能是 eDirectory 服务器用户的 CA 或 SSL 证书已过期或损坏。(造成这种情况的原因有很多,这些原因可能很常见,只需花点时间即可解决)。

Usually in Dstrace you will see an error about the SSL certificate if there is a problem. An example from a Novell Identity Manager perspective of an expired certificate is in this article: Certificate Expired As well as some details on how to fix the certificates.

通常在 Dstrace 中,如果出现问题,您会看到有关 SSL 证书的错误。从 Novell Identity Manager 的角度来看过期证书的一个示例在这篇文章中:证书过期以及有关如何修复证书的一些详细信息。

Next possibility is that the DN you are specifying is not quite correct.

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

Let me know if you need more help.

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

回答by Dmitry Khalatov

Following my previous post - if you have to use secure connection, try to use ldaps:// as a prefix to server address.

按照我之前的帖子 - 如果您必须使用安全连接,请尝试使用 ldaps:// 作为服务器地址的前缀。

If there is no SSL/TLS support, you can try this- guidelines and .NET wrapper for OpenLDAP library.

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

One important point - there are settings for TLS security level in OpenLDAP, so if your LDAP server has self-signed certificate you either have to import it on a client side or set TLS to not check the signing authority *that is less secure of course).

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

回答by rdhariwal

I came looking for a solution to a similar problem. My bind command would fail as well while using the same code from Novell's website. The solution that worked for me was adding a dynamic Certificate Validation Call back. You can read about it here.

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

        // 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 i.e. 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;
        }

回答by Vic Meyer

I work on Forefront Identity Manager integration. So the code I write always comes from a few calling clients. This may not be appropriate if you are trying to package an application for use "anywhere".

我致力于 Forefront Identity Manager 集成。所以我写的代码总是来自几个调用客户端。如果您尝试打包应用程序以供“任何地方”使用,这可能不合适。

I just wanted to update this thread with a simple solution for Novell servers which have the default TLS/SSL "confidentiality required" option enabled.

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

1) Make sure you get the SSL certificates off the Novell server you are binding too and enroll those into the trusted store on the executing client / server. There are normally two 1 for the IP and for the hostname dependent on which you will call (DNS preferable)

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

2) Import the following / add references using System.DirectoryServices; using System.DirectoryServices.Protocols;

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

3) Here is a snippet. Make sure you choose the AuthenticationTypes.SecureSocketsLayer which is key.

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();

回答by Ramkumar k

I had gone through this scenario, for me Novell LDAP service running in Kubernetes container. I tried adding CA certificate to the Mono trust store, which will add the file inside "/usr/share/.mono/certs/Trust" in linux container. But nothing did work, still Novell connect not successful for LDAP 636 port.

我已经经历过这个场景,对我来说是在 Kubernetes 容器中运行的 Novell LDAP 服务。我尝试将 CA 证书添加到 Mono 信任库,这将在 linux 容器中的“/usr/share/.mono/certs/Trust”中添加文件。但是没有任何效果,对于 LDAP 636 端口,Novell 连接仍然没有成功。

Finally I made it work in below way:

最后我让它以下面的方式工作:

LdapConnection Connection = new LdapConnection();
    Connection.SecureSocketLayer = true;
    Connection.UserDefinedServerCertValidationDelegate += new
            Novell.Directory.Ldap.RemoteCertificateValidationCallback(LdapSSLHandler);

    public bool LdapSSLHandler(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X509Certificates.X509Chain chain,
                  System.Net.Security.SslPolicyErrors sslPolicyErrors)
    {
        if (sslPolicyErrors == sslPolicyErrors.None)
        {
            return true;   //Is valid
        }

        if (certificate.GetCertHashString() == "YOUR CERTIFICATE HASH KEY") // Thumbprint value of the certificate
        {
            return true;
        }

        return false;
    }