簡體   English   中英

Novell LDAP C# - Novell.Directory.Ldap - 有沒有人讓它工作?

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

我正在嘗試使用 Novell (Novell.Directory.Ldap) 發布的庫。 版本 2.1.10。

到目前為止我所做的:

  • 我測試了與應用程序( 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。

那么,有沒有人使用過這個庫並看到它工作? 如果是這樣,你做了什么使它工作,是否需要一些特殊的配置? 有沒有辦法讓它在沒有 Mono 的 .NET 環境中工作(我可以引用 Mono dll,但我不希望它安裝在服務器上)?

(更新)連接在端口 636 上,因此使用 SSL。 我檢查了 WireShark 的通信並與我從 LDAP 瀏覽器獲得的內容進行了比較。 我已經看到傳遞 SSL 證書的步驟不是由 LDAP 庫完成的。 那么,讓它做它應該做的最好的方法是什么?

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

使用 LdapConnection.Bind() 對 LDAP 服務器進行身份驗證。 我們僅支持明文身份驗證。 尚未添加 SSL/TLS 支持。

但是文檔的日期是 2004 年,從那時起,已經進行了許多更新。 並且庫中有一個參數來定義連接是否使用 SSL。 所以現在我很困惑。

(更新)找到了更新的文檔: http : //developer.novell.com/documentation//ldapcsharp/index.html?page=/ documentation //ldapcsharp/cnet/data/bqwa5p0.html 建立 SSL 連接的方式是在服務器上注冊證書。 問題是我正在做的事情沒有綁定到特定的 Novell 服務器,因此必須動態獲取證書。

我是來尋找類似問題的解決方案的。 使用 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;
        }

我終於找到了一種方法來完成這項工作。

首先,這些帖子幫助我走上了正軌: 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("<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;
        }

我在綁定過程中使用了它

// 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 Handler 動態獲取證書,並使用 X509StoreManager.LocalMachine 以便在網站運行時能夠保存和獲取證書。

我致力於 Forefront Identity Manager 集成。 所以我寫的代碼總是來自幾個調用客戶端。 如果您嘗試打包應用程序以供“任何地方”使用,這可能不合適。

我只是想用一個簡單的解決方案來更新這個線程,這些解決方案適用於啟用了默認 TLS/SSL“需要保密”選項的 Novell 服務器。

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

91 是“無法連接”。 嘗試將服務器設置為“ldap://xxxx”格式,檢查 userDN 是否設置正確(包括域等)。

我經常使用WireShark來查看網絡級別發生了什么(它知道 LDAP 協議)。

我想我可能已經在另一個問題中向其他人提供了這個答案。

[有關 LDAP 的其他問題][1]

我認為有兩個問題:1)你想做什么類型的綁定? SSL? 清晰的文字? 匿名?

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

LDAP 瀏覽器工具,您指的是此鏈接中的工具嗎? 免費 LDAP 瀏覽器

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

您能否要求另一端的人啟用 LDAP 跟蹤(使用 Dstrace 並啟用 +LDAP 選項,有關如何在 Novell eDirectory 上使用 Dstrace 的一些鏈接請查看:不同類型的 Dstrace 捕獲和了解身份管理器的 DS 跟蹤。)

這通常會顯示一條錯誤消息,讓您有所啟發。

我的猜測是 Require TLS 已啟用,並且您可能沒有成功進行 SSL 綁定。

如果是這樣,請嘗試在端口 636 上連接,啟用 SSL,並為您嘗試登錄的用戶提供完全限定的 DN。

如果您嘗試啟用 SSL,並且沒有收到關於接受樹 CA 的受信任根證書的彈出框,則可能是 eDirectory 服務器用戶的 CA 或 SSL 證書已過期或損壞。 (造成這種情況的原因有很多,這些原因可能很常見,只需花點時間即可解決)。

通常在 Dstrace 中,如果出現問題,您會看到有關 SSL 證書的錯誤。 從 Novell Identity Manager 的角度來看,過期證書的一個示例在這篇文章中:證書過期以及有關如何修復證書的一些詳細信息。

下一個可能是您指定的 DN 不太正確。

如果您需要更多幫助,請告訴我。

按照我之前的帖子 - 如果您必須使用安全連接,請嘗試使用 ldaps:// 作為服務器地址的前綴。

如果沒有 SSL/TLS 支持,您可以試試這個- OpenLDAP 庫的指南和 .NET 包裝器。

重要的一點 - OpenLDAP 中有 TLS 安全級別的設置,因此如果您的 LDAP 服務器具有自簽名證書,您要么必須在客戶端導入它,要么將 TLS 設置為不檢查簽名權限*這當然不太安全)。

我已經經歷過這個場景,對我來說是在 Kubernetes 容器中運行的 Novell LDAP 服務。 我嘗試將 CA 證書添加到 Mono 信任庫,這將在 linux 容器中的“/usr/share/.mono/certs/Trust”中添加文件。 但是沒有任何效果,對於 LDAP 636 端口,Novell 連接仍然沒有成功。

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

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

UserDefinedServerCertValidationDelegate 已過時,因此如果它是無效 ssl 證書的問題,您可以通過以下方式跳過證書驗證:

        LdapConnectionOptions options = new LdapConnectionOptions()
            .ConfigureRemoteCertificateValidationCallback(new CertCallback((a, b, c, d) => true))
            .UseSsl();

        LdapConnection connection = new LdapConnection(options);

        connection.Connect(...);
       

但是,您應該檢查忽略證書是否是您應用程序的安全解決方案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM