`
zean
  • 浏览: 19185 次
  • 性别: Icon_minigender_1
  • 来自: 广州
文章分类
社区版块
存档分类
最新评论

通过ldap搜索未知结构的AD

阅读更多

网上通过ldap操作AD的例子很多,我也是通过网络搜索然后成功的搜索了公司未知结构的AD,中间经历了一些波折,下面总结一下过程,我相信对需要操作AD的码工码农们多多少少是有些帮助。

1 获取DirContext要注意的地方。

以下是构造DirContext的基本代码:

 

 DirContext ctx = null;
  String ldapURL = "ldap://10.0.15.1:389";
  String user = "test@xxx.com";
  String password = "restart#123";
  Hashtable env = new Hashtable();
  env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
  env.put(Context.SECURITY_AUTHENTICATION, "simple");
  env.put(Context.PROVIDER_URL, ldapURL);
  env.put(Context.SECURITY_PRINCIPAL, user);
  env.put(Context.SECURITY_CREDENTIALS, password);
  ctx = new InitialDirContext(env);

 

 

(1) 对AD结构是未知的情况下,ldapURL的写法保守一点比较好,所以不在端口后加DN。

(2) 为什么不用域名,而用IP,因为有时候通过域名访问不到AD,存在不稳定情况,获取域地址方法,通过cmd输入ipconfig -all找到win server既是所需ip,可能会存在多个,一般大点的公司会有多个域控制器。

(3)用户名的写法,不能直接用用户名,而要加上域信息,如userid@domain address或domain address\userid方式,如test@xxx.com,test是域帐号,xxx.com为AD域名,否则会报异常。

 

2 查询要注意的地方。

因为AD结构未知,所以查询仍然要保守点。

 

DirContext cnt = null;
  try
  {
   cnt = this.getContext();
   String base = "dc=xxx,dc=com";
   String filter = "(&(objectClass=user)(sAMAccountName=*test*))";
   int limitsize = 1;
   SearchControls searchCons = new SearchControls();
   NamingEnumeration namingEnum = null;
   searchCons.setSearchScope(2);
   searchCons.setCountLimit(limitsize);
   searchCons.setTimeLimit(0);
   namingEnum = cnt.search(base, filter, searchCons);
   print(namingEnum, base, limitsize);
  }
  catch (Exception e)
  {
   e.printStackTrace();
  }
  finally
  {
   if (cnt != null)
   {
    cnt.close();
   }
  }

 

 

 

(1) 未知AD情况下base开始只写出dc,因为域帐号通常不会直接建立在user节点下,一般会自己建立组织。

(2) 过滤器条件越少越好,而且最好用模糊匹配,如String filter = sAMAccountName=*test*",其中test为登录帐号名。
(3)searchCons.setSearchScope(2),设为2会查询子节点。

(4) searchCons.setTimeLimit(0),设超时时间为0标识没有超时限制。

(5)因为过滤条件比较简单而且是模糊条件,此时基本上能查出想要的数据,但节点数量很大的话查询会比较慢,此时可以根据查询的结果信息来补充DN和filter,如在DN中加入OU根,在filter加上多个条件,filter加多个条件的方法(&(条件1)(条件2))。

(6)searchCons.setCountLimit(limitsize)问题,有时查询时会报limitsize的异常,这是在遍历查询结果时出现的问题,下面是遍历的部分代码:

while (namingEnum != null && namingEnum.hasMore())

可以手工设置一个limitsize,当while循环次数到达limitsize时跳出while循环。

(7)注意关闭DirContext

 

3 遍历结果要注意的问题。

(1) 时间的处理

 

private String getConvertTime(Object time)
 {
  SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  if (time == null || "".equalsIgnoreCase(time.toString().trim()))
  {
   return "";
  }
  String strTime = time.toString().trim();

  if (strTime.indexOf(".") != -1)
  {
   strTime = strTime.substring(0, strTime.indexOf("."));
  }
  long longTime = Long.valueOf(strTime);

  GregorianCalendar Win32Epoch = new GregorianCalendar(1601, Calendar.JANUARY, 1);
  Win32Epoch.setTimeZone(TimeZone.getTimeZone("China"));
  Date Win32EpochDate = Win32Epoch.getTime();
  long TimeSinceWin32Epoch = longTime / 10000 + Win32EpochDate.getTime(); 
  Date lastLogon = new Date(TimeSinceWin32Epoch);
  return sf.format(lastLogon);

 }

 

 

这个时间是基于格林威治1601年1月1日的,这要处理两个问题,a:加上1601年1月1日这个基础时间-Win32EpochDate.getTime(),b:格林威治时间与你所在时区有偏移量(Win32Epoch.setTimeZone(TimeZone.getTimeZone("China"));
),所以要加减偏移量才是真正的时间。

(2) lastLogon与lastLogonTimestamp,其中lastLogon至少在一台AD上是实时更新的,而lastLogonTimestamp则不是通常半个月才会更新,lastLogon因为存在在不同AD上的同步问题,所以需要在所有AD上都找到lastLogon,并找出最大值才是最后的登录时间。

(3)id类的处理,id属性值是一串二进制数据,需要进行转换字符串。

 

private static String getGUID(byte[] inArr)
 {
  StringBuffer guid = new StringBuffer();
  for (int i = 0; i < inArr.length; i++)
  {
   StringBuffer dblByte = new StringBuffer(Integer.toHexString(inArr[i] & 0xff));
   if (dblByte.length() == 1)
   {
    guid.append("0");
   }
   guid.append(dblByte);
  }
  return guid.toString();
 }

 

分享到:
评论

相关推荐

    Python+ldap3 实现操作AD域控

    通过Python,基于ldap3来实现操作AD域控,账户信息获取、解锁账户、禁用账户、启用账户、重置密码等功能。

    LDAP实现AD域账号验证 - Java/SpringBoot

    在IT行业中, Lightweight Directory Access Protocol (LDAP) 是一种用于存储和检索目录信息的标准协议,而Active Directory (AD) 是微软提供的目录服务,广泛应用于企业环境中进行用户身份验证和权限管理。...

    ldap 访问AD测试

    4. **查询和搜索**:介绍如何执行基本的LDAP搜索操作,比如查找用户、组或其他对象,以及使用过滤器进行精确查找。 5. **添加和修改条目**:讲解如何通过LDAP操作向AD中添加新对象,如用户账户,以及更新现有对象的...

    对LDAP的基本操作(Spring-ldap)+Ext实现显示LDAP的树状结构

    Extjs实现的对Ldap的树状结构的显示,结构有点类似Softerra LDAP;一个测试类。 pdf:spring-ldap-reference.pdf Extjs.pdf 非常好的一本关于Extjs的书。 由于这些我也是才入门的时候写的,进行测试等用的,所以...

    LDAP Weblogic和AD之间的通信

    **LDAP (轻量级目录访问协议) 是一种用于访问和管理...通过这样的集成,企业可以利用已有的 AD 体系结构,简化用户管理和安全性。在实践中,理解 LDAP 协议和 AD 架构,以及掌握相关工具的使用,是确保成功集成的关键。

    基于SSL的ldap安全访问AD认证

    基于SSL的LDAP安全访问AD认证 基于SSL的LDAP安全访问AD认证是指使用SSL(Secure Sockets Layer)协议来保护LDAP(Lightweight Directory Access Protocol)协议与AD(Active Directory)的通信,使得密码在网络中...

    Springboot-LDAP针对AD域控做用户和组织进行同步.zip

    总之,通过Spring Boot 2.x和LDAP的集成,我们可以构建出高效、安全的企业级应用,实现与AD域控制器的无缝对接,从而方便地管理和同步用户及组织信息。这对于大型企业来说,是提高IT效率、保证数据安全的关键步骤。

    Sync_Data.rar_C LDAP AD_c++ ldap_ldap_数据同步

    总结,"Sync_Data.rar_C LDAP AD_c++ ldap_ldap_数据同步"涉及了使用C++通过LDAP库与AD进行交互并实现数据同步的高级技术。理解和应用这些知识,可以帮助开发出高效且可靠的目录服务同步解决方案。

    java使用ldap修改ad域用户密码

    Java 使用 LDAP 修改 AD 域用户密码 本文将详细介绍如何使用 Java 语言通过 LDAP 协议修改 Windows Active Directory 域用户的密码。同时,本文也将对相关概念进行解释,以便读者更好地理解整个过程。 LDAP 概念 ...

    Windows-Server-AD-Kerberos-LDAP.zip_AD kerberos_AD ldap_Kerberos

    4. **操作**:通过LDAP,可以执行添加、删除、修改和搜索目录对象等操作。 **AD、Kerberos和LDAP的交互** 在Windows Server AD环境中,Kerberos和LDAP协同工作以提供安全的身份验证和目录服务。当用户尝试访问网络...

    JAVA使用Ldap操作AD域的方法示例

    在本文中,我们将深入探讨如何使用Java通过Ldap与Active Directory (AD)域进行交互。首先,我们需要了解AD域是一个集中式服务,用于管理网络中的用户、计算机和其他资源的身份和权限。Ldap(轻量级目录访问协议)是...

    JAVA ldap AD 域 免证书 查询 修改 删除 新增 启用 禁用 修改密码

    在这篇文章中,我们将探讨使用 JAVA 实现 LDAP 的 AD 域免证书查询、修改、删除、新增、启用、禁用和修改密码的操作。 首先,让我们了解什么是 LDAP 和 AD 域。LDAP(Lightweight Directory Access Protocol)是一...

    LDAP加密访问AD(overssl)(LDAPS )C++

    **LDAP加密访问AD(通过SSL,即LDAPS)在C++中的实现** LDAP(轻量级目录访问协议)是一种用于访问目录服务的标准网络协议,常用于管理用户身份验证和授权。在安全通信方面,LDAP over SSL(LDAPS)提供了一种加密...

    Laravel开发-adldap2-laravel

    通过 `adldap2-laravel`,你可以执行复杂的 LDAP 查询,例如查找特定组的成员、搜索用户、修改用户属性等。这个包提供了丰富的查询构建器,可以方便地构建和执行 LDAP 查询语句。 **7. 权限和角色** 结合 Laravel ...

Global site tag (gtag.js) - Google Analytics