LDAP操作的兩種方案


最近由於項目需要研究了一下LDAP相關知識,感覺對沒接觸過的人來說還是有點坑的,所以記錄下來給大家分享。

由於是第一次接觸,就在網上搜了一些相關的文章,照着示例代碼測試,卻怎么也連不上LDAP服務器,最后折騰的能連上服務器了,又不能檢索用戶。

折騰過程中遇到的主要錯誤就是:

  • There is no such object on the server.

  • The username or password is incorrect.

  • The server could not be contacted.

在經歷了N小時的煎熬之后,終於找到了第一種解決方案,其實就是參考網上的示例代碼,但是示例代碼的AuthenticationTypes是None,測試連接的時候總是不能正常連接,LDAP地址只能寫host,后面不能跟DN,否則就連不上服務器,而且這種方法連接上服務器也不能檢索用戶。后來改為AuthenticationTypes.FastBind之后才能正常工作了。

 1     //----------------------------------------------------------------------------------------------
 2     // DirectoryEntry 方案, 需要引用 System.DirectoryServices
 3     //----------------------------------------------------------------------------------------------
 4     var ldapPath = "LDAP://" + host + "/" + baseDN; // LDAP必須要大寫,好像是.NET的特色
 5     DirectoryEntry de = new DirectoryEntry(ldapPath, adminName, adminPass, AuthenticationTypes.FastBind);
 6     DirectorySearcher searcher = new DirectorySearcher(de);
 7     searcher.Filter = "(uid=" + testUser + ")";
 8     searcher.SearchScope = SearchScope.Subtree;
 9     searcher.PropertiesToLoad.Add("uid");
10     searcher.PropertiesToLoad.Add("cn");
11 
12     var result = searcher.FindOne();
13     
14     // 輸出幾個查詢的屬性值
15     foreach (string n in result.Properties.PropertyNames)
16     {
17         Console.WriteLine("{0}: {1}", n, result.Properties[n][0].ToString());
18     }
19 
20     try
21     {
22         int pos = result.Path.LastIndexOf('/');
23         string uid = result.Path.Remove(0, pos + 1);
24         
25         // 二次連接,使用需要認證的用戶密碼嘗試連接
26         DirectoryEntry deUser = new DirectoryEntry(ldapPath, uid, testPass, AuthenticationTypes.FastBind);
27         var connected = deUser.NativeObject;
28         
29         Console.WriteLine("### 認證成功!");
30     }
31     catch
32     {
33         Console.WriteLine("認證失敗~~~");
34     }

 

另外一種方案是我同事找到的,和我上面一種方案幾乎在同一時間找到,比較坑,是使用.NET官方類庫中的LdapConnection,我一直認為LDAP這么常見的東西一定有官方的解決方案,奈何搜遍了國內外的中文、E文網站,“LDAP C#”、“LDAP .NET”關鍵字都搜了,就是沒有任何人提到關於這個類的片言只字,真無語!難道這玩意就這么冷門嗎?難道大家都在用DirectoryEntry嗎?不可思議。

 1     //------------------------------------------------------------------------------------------
 2     // LdapConnection 方案, 需要引用 System.DirectoryServices.Protocols
 3     //------------------------------------------------------------------------------------------
 4     var identifier = new LdapDirectoryIdentifier(host);
 5     var conn = new LdapConnection(identifier, new NetworkCredential
 6     {
 7         UserName = adminName,
 8         Password = adminPass
 9     });
10     conn.AuthType = AuthType.Basic;
11     conn.Bind();
12 
13     var request = new SearchRequest(baseDN, "(uid=" + testUser + ")", SearchScope.Subtree, "otherPassword");
14     SearchResponse response = conn.SendRequest(request) as SearchResponse;
15     if (response.Entries != null && response.Entries.Count > 0)
16     {
17         try
18         {
19             var connUser = new LdapConnection(identifier, new NetworkCredential
20             {
21                 UserName = response.Entries[0].DistinguishedName,
22                 Password = testPass
23             });
24             connUser.AuthType = AuthType.Basic;
25             connUser.Bind();
26 
27             Console.WriteLine("### 認證成功!");
28         }
29         catch
30         {
31             Console.WriteLine("認證失敗~~~ error password");
32         }
33     }
34     else
35     {
36         Console.WriteLine("認證失敗~~~ no user");
37     }

 

 

測試代碼中用到的一些變量聲明:

1     var host = "xxx.xxx.xxx.xxx:389";
2     var baseDN = "dc=xxx,dc=xxx,dc=com";
3     var adminName = "uid=管理賬號,ou=管理組," + baseDN;
4     var adminPass = "管理密碼";
5     var testUser = "測試認證用戶賬號";
6     var testPass = "測試認證用戶密碼";

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM