问题描述

在使用 LDAP 协议从 Active Directory 等目录管理服务获取组织结构数据时,一般总是需要对目录的检索路径进行配置。但是由于实际使用中的目录组织结构通常会比较复杂,往往会出现有多个树(或者 AD 中的网域)的情况。如果配置人员对所需访问路径不熟悉,或者目录组织结构特别庞大的情况下,直接人工设置容易出现配置错误或是检索效率低下的问题。所以在设计相关的配置功能时,如果能够自动获取各目录树的根路径列表,可为配置 LDAP 连接带来较大的便利。

现有案例

在此方面,常见的 LDAP 管理工具 LDAP Administrator 就提供了一个很好的方案。在设置服务器信息时,提供了一个 Fetch Base DNs 的按钮(参见下图),以帮助用户从服务器获取基准 DN 信息,作为设置检索 RootDSE,也就是目录信息树的根。

实现原理

要获取目录树的基准 DN 其实并不复杂,首先注意到 RFC 2252 文档第 13 页中针对 LDAP 的 namingContexts 属性给出了如下说明:

5.2.1. namingContexts

The values of this attribute correspond to naming contexts which this server masters or shadows. If the server does not master any information (e.g. it is an LDAP gateway to a public X.500 directory) this attribute will be absent. If the server believes it contains the entire directory, the attribute will have a single value, and that value will be the empty string (indicating the null DN of the root). This attribute will allow a client to choose suitable base objects for searching when it has contacted a server.

RFC 2252, LDAPv3: Attribute Syntax Definitions, Page 13

这段内容的最后一句就直接指出,该属性能够允许客户端在与服务器联系时选择用于检索信息的基准对象。基于文档中的表述,实际操作中,仅需要从服务器上通过查询对象的方式获得 namingContexts 属性值,即可整理出基准 DN 列表。

除此以外,通常在获取服务器 Base DN 的过程中,并不需要用户提供连接服务器的用户登录信息,一般都可以直接获取。在 LDAP Administrator 中也仅需提供服务器的访问地址、端口以及加密选项,便可直接抓取。

代码实现

获取 LDAP 基准 DN 列表的具体实现可参考下面的 Java 代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Hashtable<String,String> env = new Hashtable<String,String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://" + ldapServer + ":" + ldapPort);
env.put(Context.REFERRAL, "follow");
 
// 初始化 LDAP 上下文
LdapContext context = new InitialLdapContext(env, null);
String base = "";
String filter = "(objectclass=*)";
SearchControls controls = new SearchControls();
controls.setSearchScope(SearchControls.OBJECT_SCOPE);
 
// 通过获取 namingContexts 属性值得到基准 DN
NamingEnumeration<SearchResult> results = context.search(base, filter, controls);
List<String> namingContextsList = new ArrayList<String>();
 
// 处理结果
if(results.hasMore()) {
    Attributes attrs = results.next().getAttributes();
    if (attrs != null) {
        Attribute namingContexts = attrs.get("namingContexts");
        NamingEnumeration enumeration = namingContexts.getAll();
        while(enumeration.hasMore()) {
            namingContextsList.add((String) enumeration.next());
        }
    }
}
context.close();
System.out.println(namingContextsList);
 
https://blog.huhamhire.com/viewpost-1184.html

最新文章

  1. Mybatis - 动态sql
  2. (转)小心FPGA的JTAG口(上电和下电顺序)
  3. 关于MVC中View使用自定义方法
  4. CSS基础知识之文本属性二三事
  5. 9.28 Java基本数据类型作业
  6. priority_queue 优先队列用法
  7. Linux编辑器vim键盘详解
  8. Linux centOS7 下安装mysql5.7.10
  9. thinkphp 行为扩展
  10. 解决apache启动问题:httpd: Could not reliably determine the server&#39;s fully
  11. [置顶] js中如何复制一个对象,如何获取所有属性和属性对应的值
  12. asp.net 验证码技术
  13. JAVA日常练习—程序输入string转化为int并求和
  14. jzoj3760. 【BJOI2014】Euler
  15. Java基础---String类和基本数据类型包装类
  16. 用javascript和html5做一个音乐播放器,附带源码
  17. python3 第八章 - 完善九九乘法表
  18. PHP 函数漏洞总结
  19. C#中dll调用方法
  20. win 10 在vs2017下对mpi的安装以及认识

热门文章

  1. python3 库pandas写入csv格式文件出现中文乱码问题解决方法
  2. WebCollector2.7爬虫框架——在Eclipse项目中配置
  3. 20145311 《Java程序设计》第5周学习总结
  4. 【日志过滤】Nginx日志过滤 使用ngx_log_if不记录特定日志
  5. luogu P1029 最大公约数和最小公倍数问题
  6. (转载)CUDA、tensorflow与cuDNN的版本匹配问题
  7. 机器学习-ID3决策树算法(附matlab/octave代码)
  8. css3 导入字体
  9. 谈谈刚接触sea.js框架得看法
  10. angular的路由和监听路由的变化和用户超时的监听