zoukankan      html  css  js  c++  java
  • Java6.0 API for LDAP概述

    摘自:http://linliangyi2007.iteye.com/blog/167128

    从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)


    删除条目 

    • 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)


    根据过滤器搜索条目 

    • 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()


    添加新属性 

    • put(Attribute attr)
    • put(String attrID, Object val)

     
    移除指定属性 

    • remove(String attrID)



    javax.naming.directory.SearchControls , LDAP目录服务搜索控制对象 
    该类负责控制LDAP搜索行为的范围、设定返回结果数上限,搜索耗时上限,指定结果所包括的属性集等。 

    设定搜索行为的范围 

    • setSearchScope(int scope)

     
    设定返回结果数上限 

    • setCountLimit(long limit)


    设定搜索耗时上限 

    • setTimeLimit(int ms) , 以毫秒为单位


    指定结果所包括的属性集 

    • 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.           
    18.         singleton.envProps.setProperty(Context.INITIAL_CONTEXT_FACTORY, singleton.sCONTEXT_FACTORY);  
    19.         singleton.envProps.setProperty(Context.PROVIDER_URL, singleton.sLDAP_URL);  
    20.         singleton.envProps.setProperty(Context.SECURITY_AUTHENTICATION, singleton.sAUTH_TYPE);  
    21.         singleton.envProps.setProperty(Context.SECURITY_PRINCIPAL, singleton.sMANAGER_DN);  
    22.         singleton.envProps.setProperty(Context.SECURITY_CREDENTIALS, singleton.sMANAGER_PASSWORD);  
    23.         /* 
    24.          * 绑定ldap服务器 
    25.          */  
    26.         singleton.dirCtx = new InitialDirContext(singleton.envProps);  
    27.     }  
    28. }  


    通过一个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.       
    11.     if(user.getUserID() == null || user.getUserID().length() == 0   
    12.             || user.getFirstName() == null || user.getFirstName().length() == 0  
    13.             || user.getLastName() == null || user.getLastName().length() == 0  
    14.             || user.getCommomName() == null || user.getCommomName().length() == 0){  
    15.         return false;  
    16.     }  
    17.   
    18.     //判断用户条目是否已经存在  
    19.     if(isUserexist(user.getDistinguishedName())){  
    20.         return true;  
    21.     }  
    22.   
    23.     /* 
    24.      * 新建条目属性集 
    25.      */  
    26.     Attributes attrs = new BasicAttributes();   
    27.     setBasicAttribute(attrs , "objectclass" , "top,person,organizationalPerson,inetorgperson");  
    28.     setBasicAttribute(attrs , "cn" , user.getCommomName());  
    29.     setBasicAttribute(attrs , "givenname" , user.getFirstName());  
    30.     setBasicAttribute(attrs , "sn" , user.getLastName());  
    31.     setBasicAttribute(attrs , "uid" , user.getUserID());  
    32.     setBasicAttribute(attrs , "userpassword" , user.getPassword());  
    33.   
    34.     //添加用户条目节点   
    35.     try {  
    36.         dirContext.createSubcontext(user.getDistinguishedName(), attrs);  
    37.         System.out.println("Add User(" + user.getDistinguishedName() + ") ok.");   
    38.         return true;  
    39.     } catch (NamingException e) {  
    40.         e.printStackTrace();  
    41.     }   
    42.     return false;  
    43. }  



    获取条目属性 
    下面一段代码获取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.   
    13.     //检查uid   
    14.     String userDN = user.getDistinguishedName();   
    15.     if (userDN == null && userDN.length() == 0) {   
    16.         throw new NamingException("No userDN you specify!n");   
    17.     }   
    18.   
    19.     //判断用户条目是否已经存在  
    20.     if(!isUserexist(userDN)){  
    21.         return false;  
    22.     }  
    23.       
    24.     //设置属性   
    25.     Attributes attrs = new BasicAttributes();   
    26.     setBasicAttribute(attrs, "cn", user.getCommomName());   
    27.     setBasicAttribute(attrs, "givenname", user.getFirstName());   
    28.     setBasicAttribute(attrs, "sn", user.getLastName());   
    29.     setBasicAttribute(attrs, "userpassword", user.getPassword());     
    30.     //修改属性   
    31.     try{  
    32.         dirContext.modifyAttributes(user.getDistinguishedName(),DirContext.REPLACE_ATTRIBUTE, attrs);   
    33.         System.out.println("User(" + user.getDistinguishedName() + ") information modified.n");  
    34.         return true;  
    35.     }catch(NamingException ne){  
    36.         ne.printStackTrace();  
    37.     }  
    38.     return false;  
    39. }  



    删除条目 
    删除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))
  • 相关阅读:
    转C#与CSV
    转Log4Net配置
    转sp_addlinkedserver实现远程数据库链接
    HTML DOM
    JavaScript学习
    2016年的个人计划-xiangjiejie
    sass转换为css
    返回上一页显示上次操作后的界面
    angular ng-bind-html 对src路径失效 解决方案
    angular json转义html
  • 原文地址:https://www.cnblogs.com/oolnc/p/8794684.html
Copyright © 2011-2022 走看看