`

AD 域单点登陆之 分页获取 (三)

阅读更多

 

 

http://hi.baidu.com/2512149/item/8ad9d8fd6cb29917ce9f32a7

获取AD域中的组织单位域用户,并且对用户大于1000个的进行分批读取

package hz;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.Control;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;
import javax.naming.ldap.PagedResultsControl;
import javax.naming.ldap.PagedResultsResponseControl;

import net.devin.db.DbMapUtil;
public class AdUserSys {
  public AdUserSys() {
  }
  /**
   * 
    * 方法描述:获取组织单位的结构
    * @param: host AD服务器IP,prot AD服务器端口 adminName 用户名  adminPassword 密码
    * @return: 
    * @version: 1.0
    * @author: 王健
    * @version: Apr 24, 2013 9:49:38 AM
    * 所属部门  ECM事业部
    * 版权所有  杭州慧智电子科技有限公司
   */
 public List<Map<String,String>> getUnit(String host,String port,String adminName,String adminPassword,String ou,String dc,String dc_houzui){
    String company = "";
//    String host = "192.168.0.14"; // AD服务器
//    String port = "389"; // 端口
    List<Map<String,String>> li=new ArrayList<Map<String, String>>();
    List<Map<String,String>> list=new ArrayList<Map<String, String>>();
    Map<String, String> namerow=new HashMap<String, String>();
    String url = new String("ldap://" + host + ":" + port);
    Hashtable HashEnv = new Hashtable();
//    String adminName = "shejiguanli\\administrator"; // 注意用户名的写法:domain\User 
//    String adminPassword = "abc123!"; // 密码
    HashEnv.put(Context.SECURITY_AUTHENTICATION, "simple"); // LDAP访问安全级别
    HashEnv.put(Context.SECURITY_PRINCIPAL, adminName); // AD User
    HashEnv.put(Context.SECURITY_CREDENTIALS, adminPassword); // AD Password
    HashEnv.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory"); // LDAP工厂类
    HashEnv.put(Context.PROVIDER_URL, url);
    //HashEnv.put(Context.BATCHSIZE, "2500");
    try{
      LdapContext ctx = new InitialLdapContext(HashEnv, null);
      

      // 域节点
      String OU=hz.dtable.util.ParseUtil.convert2Null(ou);
      String searchBase = "DC="+dc+",DC="+dc_houzui; 
      if(OU.length() >0){
       searchBase = "OU="+OU+",DC="+dc+",DC="+dc_houzui; 
      }
      
      // LDAP搜索过滤器类
      String searchFilter = "objectClass=organizationalUnit";//获取帐号
      // 搜索控制器
      SearchControls searchCtls = new SearchControls(); // Create the
      // 创建搜索控制器
      searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
      // 定制返回属性
      String[] returnedAtts = { "uSNCreated","name","instanceType","ou"};
      searchCtls.setReturningAttributes(returnedAtts); // 设置返回属性集
      // 根据设置的域节点、过滤器类和搜索控制器搜索LDAP得到结果
      //objectClass=organizationalUnit 获取用户单位
      NamingEnumeration answe1=ctx.search(searchBase, searchFilter, searchCtls);
      int totalResults = 0;
     //有字段(uSNCreated:这个字段是对象创建时系统自动分配的创建序列号,并且是无符整型)可用来做uid或gid , 这是对这个字段的描述以及别人的应用
      while(answe1.hasMoreElements()){
       SearchResult sr = (SearchResult) answe1.next();// 得到符合搜索条件的DN
       String dn=sr.getName();
        Attributes Attrs = sr.getAttributes();// 得到符合条件的属性集
        if (Attrs != null) {
         Map<String, String> row=new HashMap<String, String>();
           for (NamingEnumeration ne = Attrs.getAll(); ne.hasMore();) {
            Attribute Attr = (Attribute) ne.next();// 得到下一个属性
            ///System.out.println(" AttributeID=属性名:"+ Attr.getID().toString());
            // 读取属性值
            for (NamingEnumeration e = Attr.getAll(); e.hasMore(); totalResults++) {
             company =e.next().toString();
                //System.out.println("AttributeValues=属性值:" + company);
            }
             row.put(Attr.getID().toString(), company+"".trim());
            row.put("dn", dn);
         }
           
         namerow.put(dn+"".trim(), row.get("uSNCreated"));
           li.add(row);
        }
      }
      namerow.put("huizhisys","-1000");
      ctx.close();
      //System.out.println(namerow.toString());
      for(int i=0;i<li.size();i++){
       Map rows=li.get(i);
       String uSNCreated=DbMapUtil.getValue(rows, "uSNCreated", "0");
       String distinguishedName=DbMapUtil.getValue(rows, "distinguishedName", "");
       String dn=DbMapUtil.getValue(rows, "dn", ""); //如果DN等于空那么默认为顶节点
       String name=DbMapUtil.getValue(rows, "name", ""); //如果DN等于空那么默认为顶节点
       if(dn.length() ==0){
        rows.put("parentid", "0");
       }else{
        if(("OU="+name).equalsIgnoreCase(dn)){
         //System.out.println(namerow.get("huizhisys"));
         rows.put("parentid",namerow.get("huizhisys"));
        }else{
         dn=dn.replace("OU="+name+",", "");
         rows.put("parentid",namerow.get(dn));
        }
       
       }
      System.out.println(rows.toString());
       list.add(rows);
      }
     return list;
    }catch(Exception e){
     e.printStackTrace();
     return null;
    
    }
    
 }
 /**
  * 
   * 方法描述:获取AD域所有的用户 并进行分页。如果用户不大于1000个那么可以不用部分,如果大于1000  不分页 只能读取1000个
   * @param:  
   * @return: 
   * @version: 1.0
   * @author: 王健
   * @version: Apr 27, 2013 3:04:03 PM
   * 所属部门  ECM事业部
   * 版权所有  杭州慧智电子科技有限公司
  */
  public List<Map<String,String>> getADInfo(String host,String port,String adminName,
    String adminPassword,String ou,String dc,String dc_houzui,Map<String,String> usermap) {
  
   String company = "";
   List<Map<String,String>> li=new ArrayList<Map<String, String>>();
   List<Map<String,String>> list=new ArrayList<Map<String, String>>();
   Map<String, String> namerow=new HashMap<String, String>();
   
   String url = new String("ldap://" + host + ":" + port);
   Hashtable HashEnv = new Hashtable();
   HashEnv.put(Context.SECURITY_AUTHENTICATION, "simple"); // LDAP访问安全级别
   HashEnv.put(Context.SECURITY_PRINCIPAL, adminName); // AD User
   HashEnv.put(Context.SECURITY_CREDENTIALS, adminPassword); // AD Password
   HashEnv.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory"); // LDAP工厂类
   HashEnv.put(Context.PROVIDER_URL, url);
  // HashEnv.put(Context.BATCHSIZE, 2500+"");
   int pageSize=980;   //每次获取多少条
   int total; //总共获取的条数
   byte[] cookie = null;
   try {
    LdapContext ctx = new InitialLdapContext(HashEnv, null);
    ctx.setRequestControls(new Control[] { new PagedResultsControl(pageSize, Control.CRITICAL) });//分页读取控制---因为LDAP 默认情况只能读取1000条数据
    // 域节点
   
    do{
    String OU=hz.dtable.util.ParseUtil.convert2Null(ou);
    String searchBase = "DC="+dc+",DC="+dc_houzui; 
    if(OU.length() >0){
     searchBase = "OU="+OU+",DC="+dc+",DC="+dc_houzui; 
    }
    // LDAP搜索过滤器类
    //(&(|(objectclass=user)(objectclass=person)(objectclass=inetOrgPerson)(objectclass=organizationalPerson)))
    String searchFilter = "(&(objectclass=user)(sAMAccountName=*))";//获取帐号
    // 搜索控制器
    SearchControls searchCtls = new SearchControls(); // Create the
    // 创建搜索控制器
    searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
    
   /*1 姓(L) sn                                      
  2 名(F) givenName                               
  3 显示名称(S) displayName                             
  4 描述(D) description                             
  5 办公室(C) physicalDeliveryOfficeName              
  6 英文缩写(I) initials                                
  7 电话号码(T) telephoneNumber                         
  8 电子邮件(M) mail                                    
  9 网页(W) wWWHomePage                             
  10 电话号码-其它(O)... otherTelephone                          
  11 网页-其它(R)... url
  -----
  1 国家/地区(O) co                                       
  2 省/自治区(V) st                                       
  3 市/县(C) l 
  4街道(S) streetAddress 
  5 邮政信箱(B) postOfficeBox 
  6 邮政编码(Z) postalCode 
  ---------
  1 用户登录名(U) userPrincipalName 
  2 用户登录名(Windows 2000 以前版本)(W) sAMAccountName 
  ------------
  1  家庭电话(M) homePhone                                
  2 寻呼机(P) pager 
  3 移动电话(B) mobile 
  4 传真(F) facsimileTelephoneNumber 
  5 IP电话(I) ipPhone 
  6 注释 info 
  7 家庭电话-其它(O)  otherHomePhone                           
  8 寻呼机-其它(T) otherPager                               
  9 移动电话-其它(B) otherMobile                              
  10 传真-其它(E) otherFacsimileTelephoneNumber            
  11 IP电话-其它(R) otherIpPhone   

  ----------
  1   公司(C)    company                                   
  2 部门(D)    department             
  3 职务(J)     title 
  4 经理-姓名(N)        manager                    
  5 直接下属(E) directReports 
  ---------
  */
    String[] returnedAtts = { "uSNCreated","name","userPrincipalName" };// 定制返回属性
    searchCtls.setReturningAttributes(returnedAtts); // 设置返回属性集
   // System.out.println(searchCtls.);
    // 根据设置的域节点、过滤器类和搜索控制器搜索LDAP得到结果
    int totalResults = 0;
    int rows = 0;
    
 
    NamingEnumeration answer =ctx.search(searchBase, searchFilter, searchCtls);
    // 初始化搜索结果数为0
     while (null !=answer &&answer.hasMoreElements()) {// 遍历结果集
       SearchResult sr = (SearchResult) answer.next();// 得到符合搜索条件的DN
       String dn = sr.getName();
      Attributes Attrs = sr.getAttributes();// 得到符合条件的属性集
       if (Attrs != null) {
        Map<String, String> row=new HashMap<String, String>();
          for (NamingEnumeration ne = Attrs.getAll(); ne.hasMore();) {
           Attribute Attr = (Attribute) ne.next();// 得到下一个属性
           // 读取属性值
           for (NamingEnumeration e = Attr.getAll(); e.hasMore(); totalResults++) {
            company =  e.next().toString();
           }
           row.put(Attr.getID().toString(), company);
         }
          row.put("userdn", dn);
          //System.out.println(row.toString());
          li.add(row);
       }
     }
      Control[] controls = ctx.getResponseControls();
       if (controls != null) {
         for (int i = 0; i < controls.length; i++) {
           if (controls[i] instanceof PagedResultsResponseControl) {
             PagedResultsResponseControl prrc = (PagedResultsResponseControl) controls[i];
             total = prrc.getResultSize();
             cookie = prrc.getCookie();
           } else {
          }
        }
      }
       
      ctx.setRequestControls(new Control[] { new PagedResultsControl(pageSize, cookie, Control.CRITICAL) });
    }while(cookie !=null);
    ctx.close();
    //System.out.println("总共:" + li.size() + "条信息.");
    for(int i=0;i<li.size();i++){
     Map userrow=li.get(i);
     String userdn=DbMapUtil.getValue(userrow, "userdn", ""); //如果DN等于空那么默认为顶节点
     String name=DbMapUtil.getValue(userrow, "name", ""); //如果DN等于空那么默认为顶节点
     if(userdn.length() >0){ 
       String userdns=userdn.replace("CN="+name, "");
        if(userdns.trim().length() ==0){
         userrow.put("orgid","-1000");
        }else{
         userdns=userdn.replace("CN="+name+",", "");
         if(usermap !=null){
          userrow.put("orgid",usermap.get(userdns));
         }
        }
   // System.out.println(userrow.toString());
     list.add(userrow);
     }
    }
   } catch (Exception e) {
    e.printStackTrace();
    return null;
   }
   return list;
  }
  public static void main(String args[]) {
   // 实例化
   AdUserSys ad = new AdUserSys();
   Map<String,String> usermap=new HashMap<String, String>();
   usermap.put("OU=Domain Controllers", "5828");
   usermap.put("OU=行政部", "12844");
   usermap.put("OU=人力部,OU=行政部", "53324");
   usermap.put("OU=管理部,OU=行政部", "12847");
   usermap.put("OU=杭州慧智电子科技", "53308");
     ad.getADInfo("192.168.0.14","389","shejiguanli\\administrator","abc123!","","shejiguanli","com",usermap);
   //ad.getUnit("192.168.0.14","389","shejiguanli\\administrator","abc123!","","shejiguanli","com");
  
  }
 }

分享到:
评论

相关推荐

    AD域分页查询全部域用户数据

    因此,"AD域分页查询全部域用户数据"是一种优化查询效率的方法,它允许管理员分批获取用户信息,而不是一次性加载。 首先,我们需要理解AD域分页查询的工作原理。在Java中,我们可以使用JNDI(Java Naming and ...

    AD域单点登陆NTLM

    在IT领域,特别是企业网络管理中,Active Directory(AD)域单点登录(Single Sign-On,简称SSO)是一项至关重要的技术。它允许用户在验证一次身份后,无需再次输入凭证即可访问多个受保护的资源。NT LAN Manager...

    验证AD域账号登陆,获取AD域用户列表,获取用户邮箱

    验证AD域账号登陆,获取AD域用户列表,获取用户邮箱,修改密码等AD域操作

    CAS5.3+windows AD域实现单点登录免身份认证.docx

    CAS 5.3 及 Windows AD 域实现单点登录免身份认证 CAS(Central Authentication Service)是一种流行的开源身份验证系统,旨在提供单点登录(SSO)解决方案。Windows AD(Active Directory)则是微软公司推出的目录...

    配置WLP和Microsoft AD域之间的单点登录

    配置WLP和Microsoft AD域之间的单点登录

    CAS+windows AD域实现单点登录免身份认证.docx

    cas集成window AD 域实现免身份认证单点登录,cas部署为centos系统,window server 2012 R2

    深信服上网行为管理-AD域单点登录指南.pptx

    深信服上网行为管理-AD域单点登录指南.pptx

    SANGFOR_AC__v11.0_四种AD域单点登录方案总结_20151009.pdf

    AD域单点登录是为了解决内网用户在使用Windows Active Directory(AD域)进行统一用户管理的同时,希望实现更加便捷认证过程的一项技术。它允许用户在登录Windows域账号后,能够自动通过认证设备(如深信服AC)实现...

    C# 、.NET 读取AD域里用户名或组

    本篇文章将详细介绍如何使用C#和.NET框架进行AD域操作,包括读取用户和组信息、创建与删除用户和组,以及移动用户到组等功能。 首先,进行AD域操作前,需要引用System.DirectoryServices命名空间,通过...

    AD域-限制windows域用户多点并发登录.docx

    AD域-限制windows域用户是指使用Active Directory域来限制Windows域用户多点并发登录,提高域安全性。 部分内容解释 logon.vbs脚本是用于限制用户多点并发登录的脚本,通过该脚本可以记录用户的登录信息,判断用户...

    基于AD域实现单点登录设计文档.docx

    《基于AD域实现单点登录的设计与实现》 在现代企业网络环境中,为了提高用户访问系统的便捷性和安全性,单点登录(Single Sign-On, SSO)成为了一种重要的技术手段。本文将详细介绍如何在Windows Server 2016环境下...

    AD域用户如可指定域控制器登陆.doc

    AD 域用户指定域控制器登陆 在 Active Directory(AD)域中,域控制器扮演着至关重要的角色,它负责认证和授权用户登陆域中的资源。在实际应用中,我们可能需要指定域控制器来登陆,以满足不同的业务需求。下面我们...

    SANGFOR_AC&SG_v11.0_2016年度渠道高级认证培训05_AD域单点登录.ppt

    3. **免插件模式**:AC设备开启域监控单点登录,监测AD域控制器上的登录日志,获取用户信息,实现单点登录。 4. **监听方式**:AD服务器无论在AC外网还是内网,AC设备通过监听AD认证流量(通常是UDP88端口)来同步...

    深信服AC-AD域单点登录场景.zip

    深信服AC-AD域单点登录场景是一个高级的网络管理功能,主要应用于企业或组织的内部网络环境中,旨在提供安全、便捷的访问控制。在这样的场景下,深信服的上网行为管理设备(AC)与活动目录(Active Directory, AD)...

    java验证AD域用户登录

    在Java中实现AD域用户登录验证,主要涉及到以下知识点: 1. **JNDI (Java Naming and Directory Interface)**: JNDI 是Java平台的标准API,它提供了一种统一的方式来访问各种命名和目录服务,包括AD域。通过JNDI,...

    C#读取AD域的组织结构和用户

    本文将深入探讨如何使用C#编程语言来读取AD域中的组织结构和用户信息。C#提供了丰富的类库,如System.DirectoryServices命名空间,使得与AD进行交互变得相对简单。 首先,我们需要理解AD的组织结构。AD域是基于树形...

Global site tag (gtag.js) - Google Analytics