写在前面
由于最近的一个项目的需求是要是需要读取AD域里面的一些数据,然后保存到数据库中,所以对LDAP这个东西进行了一些研究。 
    感谢以下链接提供的资料 : 
    http://wibiline.VEvb.com/blog/1840739
    http://aa00aa00.VEvb.com/blog/1276936 
    http://www.VEVb.com/forbreak/archive/2012/10/30/2746464.html 
    http://cgs1999.VEvb.com/blog/1574635 
    http://www.VEVb.com/awpatp/archive/2010/02/14/1668097.html 
 
项目需求
已知一个节点 "CN=Authorization2,CN=PRogram Data Test,DC=cayzlh,DC=com",需要得到节点下的某个节点里面的相关属性,然后提取出来,保存到数据库中。 

解决问题
获得LDAP连接
public class LdapADHelper { 
   private final String URL = "ldap://"+"192.168.1.204:389"; 
   private final String ADMINNAME = "test@test.com"; 
   private final String ADMINPASSWord = "test123";     private LdapContext ctx = null; 
 
   public static LdapADHelper getInstance() throws NamingException{ 
      return new LdapADHelper(); 
 
   } 
   private LdapADHelper () throws NamingException { 
      this.initLdap(); 
   } 
   /** 
    * 初始化ldap 
    * @throws NamingException 
    */ 
   private void initLdap() throws NamingException { 
      // ad服务器 
      Hashtable<String, String> HashEnv = new Hashtable<String, String>(); 
      HashEnv.put(Context.SECURITY_AUTHENTICATION, "simple"); // LDAP访问安全级别 
      HashEnv.put(Context.SECURITY_PRINCipAL, this.ADMINNAME); // AD User        HashEnv.put(Context.SECURITY_CREDENTIALS, this.ADMINPASSWORD); // AD Password 
      HashEnv.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); // LDAP工厂类 
      HashEnv.put(Context.PROVIDER_URL, this.URL); 
      try { 
         ctx = new InitialLdapContext(HashEnv, null); 
         System.out.println("初始化ldap成功!"); 
      } catch (NamingException e) { 
         e.printStackTrace(); 
         System.err.println("Throw Exception : " + e); 
         throw e; 
      } 
   } 
   .... 
} 
在外部类中调用这个类的getInstance()方法则可以得到helper对象并初始化好了LdapContext对象 
查询对象属性
try { 
   // 域节点 
   String searchBase = this.getBaseDnForRoleObject("CN=角色1,CN=RoleObjectDemo2,CN=msDS-AzapplicationTest2,CN=Authorization2,CN=Program Data Test,DC=cayzlh,DC=com");     // LDAP搜索过滤器类 
   String searchFilter = "(cn=*)"; 
   // 创建搜索控制器 
   SearchControls searchCtls = new SearchControls(); 
   // 设置搜索范围 
   searchCtls.setSearchScope(SearchControls.ONELEVEL_SCOPE); 
   String returnedAtts[] = { "distinguishedName " }; // 定制返回属性, 这里只需要查询 角色1 这个对象的 distinguishedName 属性 
   searchCtls.setReturningAttributes(returnedAtts); // 设置返回属性集 
   // 不设置则返回所有属性 
   // 根据设置的域节点、过滤器类和搜索控制器搜索LDAP得到结果 
   NamingEnumeration<?> answer = ctx.search(searchBase, searchFilter, searchCtls);// Search 
 
   while (answer.hasMoreElements()) {// 遍历结果集 
      // 得到符合搜索条件的DN 
      SearchResult sr = (SearchResult) answer.next(); 
      // 得到符合条件的属性集 
      Attributes attrs = sr.getAttributes(); 
      if (attrs != null) { 
         try { 
            if ( attrs.getAll().hasMore() ) { 
               Attribute attr = (Attribute) ne.next();// 得到下一个属性 
               System.out.println(attr.getAll().next().toString()); 
               // 这里输出得到的就是 角色1 的distinguishedName 属性,如果要获取有多个值的属性, 则可以利用循环和next()方法来获取得到这个属性的所有值 
            } 
         } catch (NamingException e) { 
            e.printStackTrace(); 
            System.err.println("Throw Exception : " + e); 
         } 
      } 
   } 
} catch (NamingException e) { 
   System.err.println("Throw Exception : " + e); 
} 
工具
在开发过程中使用的工具是 ADSI编辑器在域服务中进行查看和编辑相应的属性。打开方式如图所示: 
    
源代码
写了一份简单的demo,是web版的,也许有些问题,稍微改一下就可以了。又需要的可以下载来玩玩。。 
下载地址:http://files.VEVb.com/files/chenanyu/LdapTest.zip 

好久好久没有发过博客,不足之处见谅。。