輕量級目錄訪問協議了LDAP

Xianwei發表於2007-08-03

LDAP的Lightweight Directory Access Protocol,

輕量級目錄訪問協議的簡介

[@more@]LDAP的英文全稱是Lightweight Directory Access Protocol,即輕量級目錄訪問協議.我們
知道,人們對計算機網路的使用和管理涉及了各種龐雜的資源,資訊.為了提高效能,便於使
用,有效管理分散式應用的服務,資源,使用者及別的物件資訊,這些資訊需要清晰,一致地組
織起來.基於這樣的需求,描述各種使用者,應用,檔案,印表機和其它可從網路訪問的資源的
資訊被集中到一個特殊的資料庫中,這種資料庫被稱為目錄.目錄存放物件的公開或非公開的
資訊,這些資訊以某種順序組織,描述了每個物件的細節.電話簿,圖書館藏書卡片目錄就是
常見的目錄.
LDAP是基於X.500標準的,訪問 X.500 目錄需要某種協議,例如:目錄訪問協議 (DAP).
然而,DAP 需要大量的系統資源和支援機制來處理複雜的協議.LDAP 僅透過使用原始 X.500
目錄存取協議 (DAP) 的功能子集而減少了所需的系統資源消耗,而且可以根據需要定製.此
外,與X.500不同,LDAP支援TCP/IP,這對訪問Internet是必須的.
為了能對LDAP協議進行更好的理解,我們需要對以下概念有初步的認識:
目錄:Directory,存放物件的資訊,這些資訊以某種順序組織,詳細描述每個物件.
目錄資訊樹:DIT,Directory Information Tree,目錄條目的集合構成了目錄資訊樹.
條目:Entry,目錄資訊樹中的一個結點,是一個物件資訊的集合,是目錄資訊中最基本的
單位,包含該物件的一系列屬性.
屬性:Attribute,屬性描述物件的特徵.一個屬性由屬性型別(type)和一個或多個屬性值
(values)構成.
相對標識名:RDN,Relative Distinguished Name,條目的名字.
唯一標識名:DN,Distinguished Name,在一個目錄資訊樹中唯一標識一個條目的名字.
LDAP(輕量級目錄訪問協議,Lightweight Directory Access Protocol)是實現提供被稱為目錄服務的資訊服務。
目錄服務是一種特殊的資料庫系統,其專門針對讀取,瀏覽和搜尋操作進行了特定的最佳化。目錄一般用來包含描
述性的,基於屬性的資訊並支援精細複雜的過濾能力。目錄一般不支援通用資料庫針對大量更新操作操作需要的
複雜的事務管理或回捲策略。而目錄服務的更新則一般都非常簡單。這種目錄可以儲存包括個人資訊、web鏈結、
jpeg影像等各種資訊。為了訪問儲存在目錄中的資訊,就需要使用執行在TCP/IP之上的訪問協議—LDAP。

LDAP目錄中的資訊是是按照樹型結構組織,具體資訊儲存在條目(entry)的資料結構中。條目相當於關聯式資料庫中
表的記錄;條目是具有區別名DN(Distinguished Name)的屬性(Attribute),DN是用來引用條目的,DN相當於
關聯式資料庫表中的關鍵字(Primary Key)。屬性由型別(Type)和一個或多個值(Values)組成,相當於關係數
據庫中的欄位(Field)由欄位名和資料型別組成,只是為了方便檢索的需要,LDAP中的Type可以有多個Value,
而不是關聯式資料庫中為降低資料的冗餘性要求實現的各個域必須是不相關的。LDAP中條目的組織一般按照地理位置
和組織關係進行組織,非常的直觀。LDAP把資料存放在檔案中,為提高效率可以使用基於索引的檔案資料庫,而不
是關聯式資料庫。型別的一個例子就是mail,其值將是一個電子郵件地址。

WebLogic的內建的LDAP Server支援IETF LDAP為LDAPv3制定的控制訪問模型。下面這個片斷將講述在內建的LDAP
Server中怎樣實現控制訪問。可以透過編輯訪問控制檔案來將這些規則直接應用到目錄的入口。
WebLogic中的訪問控制檔案是acls.prop。在Server的lib中可以找到這個檔案。
這個檔案的所有訪問控制規則都被註釋掉了,如果想更改這些規則,你要手工更改這個檔案。
注意:WebLogic Server內建的LDAP Server在預設的情況下只允許Admin帳號訪問,WebLogic Server的security providers
只使用Admin帳號訪問內建的LDAP Server。如果你不想使用外部的LDAP Brower訪問WebLogic Server的內建的LDAP Server,
或者你只想使用Admin帳號訪問內建的LDAP Server,你不需要編輯acls.prop檔案,
訪問控制檔案(The Access Control File)

訪問控制檔案(acls.prop)包含內建的LDAP Server的整個目錄的完整的訪問控制列表(ACL)。
這個檔案中的每一行都包含一個訪問控制規則。一個訪問控制規則由下面接個部分組成:
訪問控制位置(Access Control Location)
每個訪問控制規則都應用於LDAP目錄中的一個給定的位置。這個位置通常是一個區別命名(DN),但有一個例外,這就是[root],如果訪問控制規則應用到整個目錄,則只需要指定位置為[root]就可以了!
如果被訪問或更改的入口的位置與訪問控制規則指定的位置不相等,或在訪問控制規則指定的位置的下級,則這個訪問控制規則將不會被執行。

訪問控制範圍(Access Control Scope)
訪問控制範圍有2種:
Entry-一個Entry範圍的訪問控制列表只在下面的情況下被執行:
LDAP目錄的入口的DN與訪問控制規則指定的位置相同。這樣的規則對於包含了比並行和副入口更敏感資訊的單獨入口非常有用。
Subtree-意味著訪問控制規則指定的位置及子樹都可以適用這條規則。
如果Entry與Subtree在訪問控制規則中有衝突,則Entry要優先於Subtree。

訪問許可權(Access Rights)
訪問許可權應用於整個物件或物件的屬性,有2個值:grant(准許)或deny(拒絕)。訪問許可權指定了LDAP操作的型別。

許可(grant或deny)

應用規則的屬性(attribute)

允許或拒絕訪問的主題(subject)
在weblogic可以編寫程式來訪問LDAP.上手時可以選擇JXplorer工具。
1.LDAP Server及LDAP Browser:
對於WLS LDAP為理解起來簡單,去掉限制的方法是修改beaweblogic81serverlibacls.prop檔案後。修改方法:
在該檔案最後新增以下幾行。
[root]|entry#grant:s,r,o,w,c,m#[all]#public
[root]|subtree#grant:s,r,o,w,c,m#[all]#public:
[root]|subtree#grant:a,d,e,i,n,b,t#[entry]#public:
cn=schema|entry#grant:s,r,o,w,c,m#[all]#public:
cn=schema|entry#grant:a,d,e,i,n,b,t#[entry]#public:
注意,該檔案中這些行之間,以及其他行之間不能有空行,否則啟動WLS會報錯的。修改好之後就可以啟動WLS了,
啟動後進入Console裡修改Ldap Server的密碼。密碼修改完後需要再重新啟動一次WLS。
LDAP剛上手的時候沒有方便的工具會很費勁。我看了CSDN上“兔八哥”的文章,用JXplorer,感覺很不錯。
想看這篇文章,到CSDN上搜一下“兔八哥”,系列中No.12就是關於JXplorer的配置和使用。我的連線引數如下:
Host:localhost//根據實際修改
Port:7001
Protocol:LDAP v3
Base DN:dc=ldapdomain//根據實際修改
Level:User+Password
User DN:cn=Admin
Password:weblogic//根據實際修改
.程式設計操作LDAP Server。
下面四個JAVA方法,分別用於初始化,查詢,新增,刪除,修改,關閉連線。
記得每次都需要先大概連線,操作,然後關閉連線。和使用資料庫差不多。

首先是需要用到的標頭檔案:
import java.util.Hashtable;
import java.util.Enumeration;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchControls ;
import javax.naming.NamingEnumeration;
import javax.naming.directory.SearchResult;
import javax.naming.directory.Attributes ;
import javax.naming.directory.Attribute;
import javax.naming.directory.BasicAttributes;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.ModificationItem;
import java.lang.reflect.Method;
import java.io.BufferedReader;
import java.io.InputStreamReader;


然後是一個類域,用於儲存上下文:

DirContext ctx = null;

然後是初始化:

public void init(){
String account="Admin";//操作LDAP的帳戶。預設就是Admin。
String password="weblogic";//帳戶Admin的密碼。
String root="dc=ldapdomain"; //所操作的WLS域。也就是LDAP的根節點的DC
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");//必須這樣寫,無論用什麼LDAP伺服器。
env.put(Context.PROVIDER_URL, "ldap://localhost:7001/" + root);//LDAP伺服器的地址:埠。對WLS埠就是7001
env.put(Context.SECURITY_AUTHENTICATION, "none");//授權界別,可以有三種授權級別,但是如果設為另外兩種都無法登入,我也不知道為啥,但是隻能設成這個值"none"。
env.put(Context.SECURITY_PRINCIPAL, "cn=" + account + "," + root);//載入登陸帳戶和登入密碼
env.put(Context.SECURITY_CREDENTIALS, password);
try{
ctx = new InitialDirContext(env);//初始化上下文
System.out.println("認證成功");//這裡可以改成異常丟擲。
}catch(javax.naming.AuthenticationException e){
System.out.println("認證失敗");
}catch(Exception e){
System.out.println("認證出錯:"+e);
}
}


查詢操作:

public void search(){//我只能按照某些屬性查詢節點,偶還不會怎麼查詢一個目錄或按照更復雜的正則式查詢特定節點/目錄
try{
SearchControls constraints = new SearchControls();
constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
System.out.print("what would you want to search:");
BufferedReader bd=new BufferedReader(new InputStreamReader(System.in));
String s=bd.readLine();
NamingEnumeration en = ctx.search("", "uid="+s, constraints); //要查詢的UID。如果是*則可以查到所有UID的節點
if(en == null){
System.out.println("Have no NamingEnumeration.");
}
if(!en.hasMoreElements()){
System.out.println("Have no element.");
}
while (en != null && en.hasMoreElements()){//可以查出多個元素
Object obj = en.nextElement();
if(obj instanceof SearchResult){
SearchResult si = (SearchResult) obj;
System.out.println(" name: " + si.getName());
Attributes attrs = si.getAttributes();
if (attrs == null){
System.out.println(" No attributes");
}else{
for (NamingEnumeration ae = attrs.getAll(); ae.hasMoreElements();){//獲得該節點的所有屬性
Attribute attr = (Attribute) ae.next();//下一屬性
String attrId = attr.getID();//獲得該屬性的屬性名
for (Enumeration vals = attr.getAll();vals.hasMoreElements();){//獲得一個屬性中的所有屬性值
System.out.print(" "+attrId + ": ");
Object o = vals.nextElement();//下一屬性值
if(o instanceof byte[])
System.out.println(new String((byte[])o));
else
System.out.println(o);
}
}
}
}
else{
System.out.println(obj);
}
System.out.println();
}
}catch(Exception e){
System.out.println("Exception in search():"+e);
}
}

新增操作:

public void add(){
try{
String newUserName = "stella";
BasicAttributes attrs = new BasicAttributes();
BasicAttribute objclassSet = new BasicAttribute("objectclass");
objclassSet.add("person");
objclassSet.add("top");
objclassSet.add("organizationalPerson");
objclassSet.add("inetOrgPerson");
objclassSet.add("wlsUser");
attrs.put(objclassSet);
attrs.put("sn", newUserName);
attrs.put("uid", newUserName);
attrs.put("cn", newUserName);
ctx.createSubcontext("uid=" + newUserName+",ou=people,ou=myrealm", attrs); //新增一個節點,我還不會新增目錄
}catch(Exception e){
System.out.println("Exception in add():"+e);
}
}


修改操作:

public void edit(){
try{
String account = "stella";//修改以前舊的值
String sn = "stella sn";//修改以後新的值
ModificationItem modificationItem[] = new ModificationItem[1];
modificationItem[0] =
new ModificationItem(
DirContext.REPLACE_ATTRIBUTE,
new BasicAttribute("sn", sn));//所修改的屬性
ctx.modifyAttributes("uid=" + account, modificationItem); //執行修改操作
}catch(Exception e){
System.out.println("Exception in edit():"+e);
}
}


刪除節點操作:

public void delete(){
try{
String uid = "stella";
ctx.destroySubcontext("uid=" + uid); //按照UID刪除某個節點。我還不會刪除一個目錄。
}catch(Exception e){
System.out.println("Exception in edit():"+e);
}
}


關閉連線:

public void close(){
if(ctx != null)
{
try
{
ctx.close();
}
catch (NamingException e)
{
System.out.println("NamingException in close():"+e);
}
}
}
我對LDAP的理解:它是用於對資源的管理和服務的訪問協議,在Weblogic平臺上的JNDI(包含EJB和DataSource)都是提供它來提供的。
正是JNDI的服務和RMI結合就形成J2EE平臺上分散式的應用,因此說到底層,還是LDAP協議的支援。

部分資料參考:http://www.blogjava.net/kapok/archive/2005/05/05/4034.html

http://www.blogdriver.com/goblinize/250559.html

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/722856/viewspace-931030/,如需轉載,請註明出處,否則將追究法律責任。

相關文章