什麼是 LDAP ?
LDAP (輕量目錄訪問協議), 簡單的說, LDAP 是一個 能 得到關於人或者資源的 集合 、靜態數據的快速方式 。
這種說法似乎有點抽象,結合這幾天在做的一個項目具體來談一下。
AD , LDAP ,初來乍到的面對這些在課本上不可能碰到的新術語還真是有些懵了,查了大量的資料之後,終於開始有點感覺了。
大多數企業及單位都會有人員管理系統,而有很多是用 window server 進行管理的,其中的原因相信大家早已明白:簡單,方便。但是很多時候我們會需要利用程序獲取服務器上面的人員數據,聽起來似乎無從下手,但由於資源大多是保存在 AD 域下面的,於是 LDAP 能夠幫我們輕易的完成這件事。
最開始找了很多的程序,但都走了彎路,因爲這些程序大多沒有解釋幾個關鍵概念:
OU( 組織單元 ) :你可以理解爲目錄信息
O( 組織名 ) :可以理解爲公司名,比如說 O=foobar.com ,但是更多情況下我們會把它拆分爲DC=foobar,DC=com( 實踐發現使用 O 會出現連接錯誤,不知道是否這種表示方式已經被 DC 替代 ) 。
下面是一段實例代碼,之後會解釋了各個字段的意思及用法:
package ldap;
import java.util.Iterator;
import com.novell.ldap.LDAPAttributeSet;
import com.novell.ldap.LDAPConnection;
import com.novell.ldap.LDAPEntry;
import com.novell.ldap.LDAPException;
import com.novell.ldap.LDAPSearchResults;
public class LdapCon {
public static void main(String[] args) {
LdapCon lc=new LdapCon();
try {
lc.conenction();
} catch (LDAPException e) {
e.printStackTrace();
}
}
private static void conenction() throws LDAPException{
String MY_HOST = "192.168.139.132";//訪問AD域的IP地址
int MY_PORT = 389;//端口號,默認爲389
LDAPConnection ld = new LDAPConnection();
// ld.setSocketTimeOut(21000);//設置超時
ld.connect( MY_HOST, MY_PORT );
// ld.bind(null, null);
ld.bind("[email protected]", "123456");
String searchBase = "OU=項目部,DC=smallbusiness,DC=local";//域名入口
int searchScope = LDAPConnection.SCOPE_SUBORDINATESUBTREE;//搜索範圍
//過濾器
String filter="(|(objectclass=person)(objectclass=user)(objectclass=organizationalPerson))";
LDAPSearchResults searchResults =ld.search(searchBase,
searchScope,
filter,
null,
false);
while ( searchResults.hasMore()) {
LDAPEntry nextEntry = searchResults.next();
System.out.println("We found "+nextEntry.getDN());
// LDAPAttributeSet attributeSet = nextEntry.getAttributeSet();
// Iterator ite=attributeSet.iterator();
// while(ite.hasNext()){
// System.out.println(ite.next());
// }
}
}
}
具體的解釋一下下面這幾個概念
L d.bind(loginDN,loginPW) : 表示 LDAPConnection 的綁定,不能省略,你可以輸入兩個 null來進行匿名登錄,當然,以匿名方式登錄並不代表你具有所有的權限。下面就來說一下這兩個參數到底應該怎麼填,嘗試了很多種方法, DN 表示域名,根據這種命名方法來猜測, loginDN 應該是登錄名加域名的表示方式,而你在 windwos server 的 AD 域中進行用戶添加的時候就會發現,用戶唯一標示名的表示方式是 login@DN, 密碼則是對應用戶的密碼。
ld.setSocketTimeOut(int) , 設置連接超時,這個方法並沒有產生實際的效果,因爲即使不設置,服務器在連接不上的時候依然會超時。
Search Scope :表示搜索的深度,有四個基本參數:
• SCOPE_BASE. 這個只在你已經知道了目錄結構的時候使用,你用這種搜索方式輸出的時候會發現 什麼都看不到
• SCOPE_ONE. 只搜索處在該層目錄的數據(也就是說如果存在多層結構,處在該層目錄一下的目錄裏面的數據就搜不到)。
• SCOPE_SUB. 按層次遍歷,可以搜到該目錄下面的所有數據,包含目錄 .
• SCOPE_SUBORDINATESUBTREE. 搜索的形式跟上面一個一樣,但是不包含基礎的數據,具體什麼含義,試試就知道了。
Filter : 過濾器, and = "&" filterlist , or = "|" filterlist , not = "!" filterlist ,就像我代碼中寫到的一樣以 | 開頭,表示條件或。還有一種表示方式就是 objectClass=*, 使用通配符表示所有。
有了數據你自然明白該做什麼了O(∩_∩)O~,不過還有一點依然需要強調,就像很多前輩跟我說過的,學好算法跟數據結構,前兩天想單純依靠循環的邏輯控制解決目錄結構的問題,但努力之後才發現,利用多叉樹解決要快得多,雖然我一開始就意識到目錄本身就是一個樹狀結構,但是加以實踐纔是問題的最好答案。算法和數據結構受到如此之重視就是因爲用對了的算法和數據結構有可能使你的代碼在效率和簡潔度上出現意想不到的結果。