[英].NET Core - Novell LDAP/AD - Group search for a user that he belongs to - Has anybody made it work?
[英]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.