Ldap Api

Java6.0 API for LDAP概述

從JDK5.0開始,對LDAP協議的數據訪問操作就被集成在javax的擴展API包中,並隨同JDK一併發佈,這一章節,我們主要介紹API包中的類信息。
javax.naming.directory 包的結構


常用API解析

javax.naming.directory.InitialDirContext,初始化目錄服務上下文類
該類是LDAP數據內容的操作工具類,通過該類可以執行綁定LDAP服務器、新增LDAP條目、獲取條目實例、修改條目屬性、刪除條目和根據條件搜索條目等操作。常用方法說明如下:

初始化LDAP 目錄服務上下文(相當於使用JDBC打開一個數據庫鏈接)

  • InitialDirContext(Hashtable<?,?> environment)


綁定/創建LDAP條目對象(相當於新增一個LDAP條目數據bind(Name

  • name, Object obj, Attributes attrs)

  • bind(String name, Object obj, Attributes attrs)

  • createSubcontext(Name name, Attributes attrs)

  • createSubcontext(String name, Attributes attrs)


獲取條目實例(屬性集)

  • getAttributes(Name name)

  • getAttributes(Name name, String[] attrIds)

  • getAttributes(String name)

  • getAttributes(String name, String[] attrIds)


修改條目屬性

  • modifyAttributes(Name name, int mod_op, Attributes attrs)

  • modifyAttributes(Name name, ModificationItem[] mods)

  • modifyAttributes(String name, int mod_op, Attributes attrs)

  • modifyAttributes(String name, ModificationItem[] mods)

u
刪除條目

  • destroySubcontext(Name name)

  • destroySubcontext(String name)


根據屬性集搜索條目

  • search(Name name, Attributes matchingAttributes)

  • search(Name name, Attributes matchingAttributes, String[] attributesToReturn)

  • search(String name, Attributes matchingAttributes)

  • search(String name, Attributes matchingAttributes, String[] attributesToReturn)

u
根據過濾器搜索條目

  • search(Name name, String filterExpr, Object[] filterArgs, SearchControls cons)

  • search(Name name, String filter, SearchControls cons)

  • search(String name, String filterExpr, Object[] filterArgs, SearchControls cons)

  • search(String name, String filter, SearchControls cons)



javax.naming.directory.BasicAttribute
,LDAP基本屬性對象
該類用來表示LDAP條目中的單個屬性對象。在目錄服務中,每個屬性名稱是可以對應多個的屬性值的。

構建屬性對象

  • BasicAttribute(String id)

  • BasicAttribute(String id, boolean ordered)

  • BasicAttribute(String id, Object value)

  • BasicAttribute(String id, Object value, boolean ordered)


添加屬性值

  • add(int ix, Object attrVal),添加屬性值到多值屬性的指定位置

  • add(Object attrVal) , 追加屬性值到多值屬性尾部


判斷屬性值是否包含

  • contains(Object attrVal) , 多值屬性中有一個值是匹配的,返回true


獲取屬性值

  • get(),取得屬性值中的一個

  • get(int ix),從多值屬性中的指定位置取值


獲取屬性ID

  • getID(),屬性的ID就是屬性名


刪除屬性值

  • remove(int ix),刪除指定位置的屬性值

  • remove(Object attrval),刪除指定的屬性值



javax.naming.directory.BasicAttributes
,LDAP實體的屬性集
該類表示一個LDAP條目綁定的屬性集合,在絕大多數情況下,一個LDAP條目存在多個屬性。

構造屬性集

  • BasicAttributes()

  • BasicAttributes(boolean ignoreCase),屬性ID是否大小寫敏感,建議不要使用敏感

  • BasicAttributes(String attrID, Object val)

  • BasicAttributes(String attrID, Object val, boolean ignoreCase)


獲取屬性集中的單個屬性對象

  • get(String attrID)


獲取全部屬性的枚舉

  • getAll()


獲取全部屬性的ID枚舉

  • getIDs()

u
添加新屬性

  • put(Attribute attr)

  • put(String attrID, Object val)

u
移除指定屬性

  • remove(String attrID)



javax.naming.directory.SearchControls , LDAP
目錄服務搜索控制對象
該類負責控制LDAP搜索行爲的範圍、設定返回結果數上限,搜索耗時上限,指定結果所包括的屬性集等。

設定搜索行爲的範圍

  • setSearchScope(int scope)

u
設定返回結果數上限

  • setCountLimit(long limit)

u
設定搜索耗時上限

  • setTimeLimit(int ms) , 以毫秒爲單位

u
指定結果所包括的屬性集

  • setReturningAttributes(String[] attrs)



javax.naming.directory.SearchResult
, 表示.search() 方法的返回結果集中的一項。
SearchResult
類是對LDAP條目屬性集的封裝。在search()操作中可能返回完整的條目屬性,也可能是條目屬性的一部分。

獲取SearchResult封裝的條目屬性

  • getAttributes()



以上只列舉了LDAP操作API的常用部分,更多更詳細的描述,請參考 Sun Java6.0 API DOC

LDAP
操作代碼樣例
在這個章節中,我們將結合LDAP操作的代碼實例瞭解API使用。

初始化LDAP 目錄服務上下文
該例子中,我們使用uid=linly,ou=People,dc=jsoso,dc=net這個賬號,鏈接位於本機8389端口的LDAP服務器(ldap://localhost:8389),認證方式採用simple類型,即用戶名/密碼方式。

Java代碼

  1. private static void initialContext() throws NamingException{  

  2.    if(singleton == null){  

  3.        singleton = new LDAPConnection();  

  4.        /*  

  5.         * 在實際編碼中,這些環境變量應儘可能通過配置文件讀取

  6.         */  

  7.        //LDAP服務地址

  8.        singleton.sLDAP_URL = "ldap://localhost:8389";    

  9.        //管理員賬號

  10.        singleton.sMANAGER_DN = "uid=linly,ou=People,dc=jsoso,dc=net";  

  11.        //管理員密碼

  12.        singleton.sMANAGER_PASSWORD = "coffee";  

  13.        //認證類型

  14.        singleton.sAUTH_TYPE = "simple";  

  15.        //JNDI Context工廠類

  16.        singleton.sCONTEXT_FACTORY = "com.sun.jndi.ldap.LdapCtxFactory";    


  17.        singleton.envProps.setProperty(Context.INITIAL_CONTEXT_FACTORY, singleton.sCONTEXT_FACTORY);  

  18.        singleton.envProps.setProperty(Context.PROVIDER_URL, singleton.sLDAP_URL);  

  19.        singleton.envProps.setProperty(Context.SECURITY_AUTHENTICATION, singleton.sAUTH_TYPE);  

  20.        singleton.envProps.setProperty(Context.SECURITY_PRINCIPAL, singleton.sMANAGER_DN);  

  21.        singleton.envProps.setProperty(Context.SECURITY_CREDENTIALS, singleton.sMANAGER_PASSWORD);  

  22.        /*  

  23.         * 綁定ldap服務器

  24.         */  

  25.        singleton.dirCtx = new InitialDirContext(singleton.envProps);  

  26.    }  

  27. }  






























通過一個Hashtable或者Properties對象爲LDAP的Context設置參數,而後初始化InitialDirContext,即可綁定LDAP服務。這相當於JDBC中獲取數據庫的Connection對象。

綁定/創建LDAP條目對象
用戶可以使用bind方法創建新的LDAP條目,下面的代碼創建一個DN:"ou=Employee , dc=jsoso ,dc=net"的OrganizationUnit類LDAP條目如下:

Java代碼

  1. public boolean createOrganizationUnit(){  

  2.    String ldapGroupDN = "ou=Employee , dc=jsoso ,dc=net";  

  3.    try {  

  4.        /*  

  5.         * 查找是否已經存在指定的OU條目

  6.         * 如果存在,則打印OU條目的屬性信息

  7.         * 如果不存在,則程序會拋出NamingException異常,進入異常處理

  8.         */  

  9.        Attributes attrs = dirContext.getAttributes(ldapGroupDN);  

  10.        System.out.println("Find the group , attributes list :");  

  11.        NamingEnumeration<String>  nEnum = attrs.getIDs();              

  12.        for( ; nEnum.hasMore() ; ){  

  13.            String attrID = nEnum.next();  

  14.            Attribute attr = (Attribute)attrs.get(attrID);  

  15.            System.out.println(attr.toString());  

  16.        }              

  17.        return false;  

  18.    } catch (NamingException e) {  

  19.        /*  

  20.         * 沒有找到對應的Group條目,新增Group條目

  21.         */  

  22.        //創建objectclass屬性

  23.        Attribute objclass = new BasicAttribute("objectclass");  

  24.        objclass.add("top");  

  25.        objclass.add("organizationalunit");    

  26.        //創建cn屬性

  27.        Attribute cn = new BasicAttribute("ou", "Employee");    

  28.        //創建Attributes,並添加objectclass和cn屬性

  29.        Attributes attrs = new BasicAttributes();    

  30.        attrs.put(objclass);    

  31.        attrs.put(cn);    

  32.        //將屬性綁定到新的條目上,創建該條目

  33.        try {  

  34.            dirContext.bind(ldapGroupDN, null, attrs);  

  35.            System.out.println("Group created successful");  

  36.            return true;  

  37.        } catch (NamingException e1) {  

  38.            e1.printStackTrace();  

  39.        }              

  40.    }  

  41.    return false;  

  42. }  












































或者使用createSubcontext方法創建亦可,以下例子我們新增一個inetorgperson類的LDAP條目:

Java代碼

  1. /**  

  2. * 創建LDAP用戶條目

  3. * @param user  

  4. * @return  

  5. */  

  6. public boolean createUser(LDAPUser user){  

  7.    if(user == null){  

  8.        return false;  

  9.    }  


  10.    if(user.getUserID() == null || user.getUserID().length() == 0

  11.            || user.getFirstName() == null || user.getFirstName().length() == 0

  12.            || user.getLastName() == null || user.getLastName().length() == 0

  13.            || user.getCommomName() == null || user.getCommomName().length() == 0){  

  14.        return false;  

  15.    }  


  16.    //判斷用戶條目是否已經存在

  17.    if(isUserexist(user.getDistinguishedName())){  

  18.        return true;  

  19.    }  


  20.    /*  

  21.     * 新建條目屬性集

  22.     */  

  23.    Attributes attrs = new BasicAttributes();    

  24.    setBasicAttribute(attrs , "objectclass" , "top,person,organizationalPerson,inetorgperson");  

  25.    setBasicAttribute(attrs , "cn" , user.getCommomName());  

  26.    setBasicAttribute(attrs , "givenname" , user.getFirstName());  

  27.    setBasicAttribute(attrs , "sn" , user.getLastName());  

  28.    setBasicAttribute(attrs , "uid" , user.getUserID());  

  29.    setBasicAttribute(attrs , "userpassword" , user.getPassword());  


  30.    //添加用戶條目節點

  31.    try {  

  32.        dirContext.createSubcontext(user.getDistinguishedName(), attrs);  

  33.        System.out.println("Add User(" + user.getDistinguishedName() + ") ok.");    

  34.        return true;  

  35.    } catch (NamingException e) {  

  36.        e.printStackTrace();  

  37.    }    

  38.    return false;  

  39. }  














































獲取條目屬性
下面一段代碼獲取entryDN參數指定條目中的屬性集合,並打印到控制檯

Java代碼

  1. /**  

  2. * 獲取一個指定的LDAP Entry  

  3. * @param entryDN  

  4. */  

  5. public void find(String entryDN){  

  6.    try {    

  7.        Attributes attrs = dirContext.getAttributes(entryDN);    

  8.        if (attrs != null) {  

  9.            NamingEnumeration<String>  nEnum = attrs.getIDs();  

  10.            for( ; nEnum.hasMore() ; ){  

  11.                String attrID = nEnum.next();  

  12.                Attribute attr = (Attribute)attrs.get(attrID);  

  13.                System.out.println(attr.toString());  

  14.            }  

  15.            System.out.println();  

  16.        }else{    

  17.            System.out.println("No found binding.");  

  18.        }    

  19.    }catch(NamingException ne) {    

  20.        ne.printStackTrace();  

  21.    }    

  22. }  

























修改條目屬性
修改DN=user.getDistinguishedName()的條目中的cn、givenname、sn和userpassword四個屬性值。
(注:參數DirContext.REPLACE_ATTRIBUTE有另外兩個常量:DirContext.ADD_ATTRIBUTE;DirContext.REMOVE_ATTRIBUTE,分別表示新增屬性和刪除屬性。)

Java代碼

  1. /**  

  2. * 修改用戶信息

  3. * @param user  

  4. * @return  

  5. * @throws Exception  

  6. */    

  7. public boolean modifyUser(LDAPUser user) throws Exception {    

  8.    //用戶對象爲空

  9.    if (user == null) {    

  10.        throw new Exception("No user information!n");    

  11.    }  


  12.    //檢查uid    

  13.    String userDN = user.getDistinguishedName();    

  14.    if (userDN == null && userDN.length() == 0) {    

  15.        throw new NamingException("No userDN you specify!n");    

  16.    }    


  17.    //判斷用戶條目是否已經存在

  18.    if(!isUserexist(userDN)){  

  19.        return false;  

  20.    }  


  21.    //設置屬性

  22.    Attributes attrs = new BasicAttributes();    

  23.    setBasicAttribute(attrs, "cn", user.getCommomName());    

  24.    setBasicAttribute(attrs, "givenname", user.getFirstName());    

  25.    setBasicAttribute(attrs, "sn", user.getLastName());    

  26.    setBasicAttribute(attrs, "userpassword", user.getPassword());      

  27.    //修改屬性

  28.    try{  

  29.        dirContext.modifyAttributes(user.getDistinguishedName(),DirContext.REPLACE_ATTRIBUTE, attrs);    

  30.        System.out.println("User(" + user.getDistinguishedName() + ") information modified.n");  

  31.        return true;  

  32.    }catch(NamingException ne){  

  33.        ne.printStackTrace();  

  34.    }  

  35.    return false;  

  36. }  










































刪除條目
刪除DN= userDN條目

Java代碼

  1. /**  

  2. * 刪除用戶

  3. * @param userDN  

  4. * @return  

  5. */  

  6. public boolean deleteUser(String userDN) {    

  7.    if(!isUserexist(userDN)) {    

  8.        return true;  

  9.    }    

  10.    try {  

  11.        dirContext.destroySubcontext(userDN);  

  12.        System.out.println("User( " + userDN + ") deleted.n");    

  13.        return true;  

  14.    } catch (NamingException e) {  

  15.        e.printStackTrace();  

  16.    }    

  17.    return false;          

  18. }  





















根據屬性集搜索條目
根據屬性集matchingAttributes中的匹配值,在上下文DN= "ou=People,dc=jsoso ,dc=net"中搜索它的所有子樹中的匹配條目。
(注:SearchControls的SCOPE參數詳見SearchControls SCOPE補充說明)

Java代碼

  1.         /**  

  2. * 通過屬性搜索LDAP範例

  3. * @return  

  4. */  

  5. public void searchByAttribute(Attributes matchingAttributes){  

  6.     String baseDN = "ou=People,dc=jsoso ,dc=net";  

  7.     SearchControls cons = new SearchControls();  

  8.     cons.setSearchScope(SearchControls.SUBTREE_SCOPE);  

  9.     try {  

  10.        Name baseName = new LdapName(baseDN);  

  11.        NamingEnumeration<SearchResult> ne = dirContext.search(baseName, matchingAttributes);  

  12.        SearchResult entry = null;  

  13.        for(;ne.hasMore();){  

  14.            entry = ne.next();  

  15. showEntry(entry);  

  16.        }                      

  17.    } catch (NamingException e) {  

  18.        e.printStackTrace();  

  19.    }  

  20. }  























根據過濾器搜索條目
根據過濾器條件,在上下文DN = "ou=People,dc=jsoso ,dc=net"中,搜索它的所有子樹中的匹配條目。
(注:過濾器filter的相關語法詳見LDAP filter語法補充說明)

Java代碼

  1. /**  

  2. * 通過過濾器搜索LDAP範例

  3. * @return  

  4. */  

  5. public void searchByFilter(String filter){  

  6.     String baseDN = "ou=People,dc=jsoso ,dc=net";          

  7.     SearchControls cons = new SearchControls();  

  8.     cons.setSearchScope(SearchControls.SUBTREE_SCOPE);  

  9.     try {  

  10.        NamingEnumeration<SearchResult> ne = dirContext.search(baseDN, filter , cons);  

  11.        SearchResult entry = null;  

  12.        for(;ne.hasMore();){  

  13.            entry = ne.next();  

  14. showEntry(entry);  

  15.        }                      

  16.    } catch (NamingException e) {  

  17.        e.printStackTrace();  

  18.    }  

  19. }  






















相關補充

javax.naming.Name
對象說明
在API中,我們常常見到對LDAP上下文條目有兩種參數形式,一種是大家都熟悉的String參數,如: String baseDN = "ou=People,dc=jsoso ,dc=net";
另一種是使用javax.naming.Name類型的參數,那麼Name類和String有什麼區別呢?
簡單的說,Name是對String類DN的封裝,它把一個完整的DN字竄分解成了RDN的list。這個list的順序剛好和String相反。就拿"ou=People,dc=jsoso ,dc=net"爲例,Name中的RDN順序是[0]=net,[1]=jsoso,[2]=People。這樣做的好處是更方便對Name進行操作,比如取其前綴或者後綴。

SearchControls SCOPE補充說明


LDAP filter語法補充說明
filter的運算符

filter布爾運算符


搜索過濾器示例

  • 下列過濾器將搜索包含一個或多個 manager 屬性值的條目。這也稱爲存在搜索: manager=*

  • 下列過濾器將搜索包含通用名 Ray Kultgen 的條目。這也稱爲等價搜索:cn=Ray Kultgen

  • 下列過濾器返回所有不包含通用名 Ray Kultgen 的條目:(!(cn=Ray Kultgen))

  • 下列過濾器返回的所有條目中都有包含子字符串 X.500 的說明屬性:description=*X.500*

  • 下列過濾器返回所有組織單元爲 Marketing 且說明字段中不包含子字符串 X.500 的條目: (&(ou=Marketing)(!(description=*X.500*)))

  • 下列過濾器返回所有組織單元爲 Marketing 且 manager 爲 Julie Fulmer 或 Cindy Zwaska 的條目: (&(ou=Marketing)(|(manager=cn=Julie Fulmer,ou=Marketing,dc=siroe,dc=com)(manager=cn=Cindy Zwaska,ou=Marketing,dc=siroe,dc=com)))

  • 下列過濾器返回所有不代表人員的條目: (!(objectClass=person))

  • 下列過濾器返回所有不代表人員且通用名近似於 printer3b 的條目:(&(!(objectClass=person))(cn~=printer3b))



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章