java通过ldap同步ad域组织架构、人员信息

本文详细介绍了在Java开发中如何通过LDAP与AD域进行交互,包括使用SSL连接636端口,处理objectGUID的转换,解决部门查询和创建的问题,以及分页查询超过1000条记录的策略。此外,还提到了启用端点识别算法的注意事项,以及在IDEA中配置相关系统属性的步骤。
摘要由CSDN通过智能技术生成

踩坑点:

  1. 普通操作389端口就可以,如果需要操作用户密码等,需要ssl链接,636端口,可以用证书方式,也可以用免证书方式,免证书也需要在ad域服务器生成对应的证书,参考:AD域证书申请,导入Java密钥库,实现ldap修改AD用户密码_寒沨的博客-CSDN博客_ad证书导出
  2. objectGUID是ad域里信息的唯一id,但是存储时16进制,需要进行转换,转换方式见下方代码
  3. 根据objectGUID进行查询的时候,也需要进行转换
  4. 部门查询时,如果查询的上级部门也不存在时,会报错
  5. 部门新增时,如果部门名称有'/',用public DirContext createSubcontext(String name, Attributes attrs);这个方法创建,会创建失败,可以用CompositeName自动转义,public DirContext createSubcontext(Name name, Attributes attrs);这个方法进行创建就可以
    1. //用string类型创建部门的时候,有特殊字符‘/’会创建失败,借用CompositeName可以自动转义‘/’
      Name composite = new CompositeName().add(distinguishedName);
      
      //添加
      ldapContext.createSubcontext(composite, attributes);
  6. 用ldapContext.search(searchBase, searchFilter,searchCtls)查询列表时,默认的分页列表最大1000条记录,如果要查询超过1000条数据,可以通过更改域的分页限制实现;通过env.put(Context.BATCHSIZE,"10000");也可以设置默认的查询条数,但是仅限于代码里设置的查询条数小于域里设置的条数
    1. 1.在“开始”——>“运行”——>输入“ ntdsutil”——>回车;
      
      2.输入:“ldap policies”,回车;
      
      3.输入:“connections”,回车;
      
      4.输入:“connect to domain yourDomainName”,例如(connect to domain baidu.com)
      
      5.连接提示出现后,输入:“quit”,回车;
      
      6.输入:“show values”,确认当前的最大返回数;(默认是1000)
      
      7.输入:“set MaxPageSize to 10000”,将最大返回数改为10000。(最大返回数可以根据实际情况自行定义)。
      
      8.再度输入:“show values”,确认当前的最大返回数(显示为:1000(10000))。
      
      9.输入“commit changes”以确认修改。
      
      10.
      再次输入:“show values”,确认当前的最大返回数为10000。
      
      11.
      输入“quit”,退出设置状态;
      
      12.
      输入“quit”,退出当前命令
  1. 用636端口ssl链接时很关键的一步,启动类上加,不然启动会报错javax.naming.CommunicationException: simple bind failed
    //ldap ssl链接很关键的
    System.setProperty("com.sun.jndi.ldap.object.disableEndpointIdentification","true");
    1. 原因:为了提高LDAP(secureldap over TLS)连接的健壮性,默认情况下启用了端点识别算法。在某些情况下,以前能够成功连接到LDAPS服务器的某些应用程序可能不再能够这样做。如果这些应用程序认为合适,可以使用新的系统属性禁用端点标识:com.sun.jndi.ldap.object.disableEndpointIdentification。定义此系统属性(或将其设置为true)以禁用端点识别算法
    2. 本地idea启动的时候,idea vm options里设置”-Dcom.sun.jndi.ldap.object.disableEndpointIdentification=true“

代码:

  1. 登录
     /**
         * ssl方式免证书登录
         * System.setProperty("com.sun.jndi.ldap.object.disableEndpointIdentification","true");这句很关键,将他放在启动类的main方法李
         * @return
         */
        private LdapContext adLogin() {
    
            LdapContext ldapContext = null;
            Hashtable<String, Object> env = new Hashtable<String, Object>();
            env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
            //验证类型
            env.put(Context.SECURITY_AUTHENTICATION, "simple");
            //用户名称,cn,ou,dc 分别:用户,组,域
            env.put(Context.SECURITY_PRINCIPAL, "username");
            //用户密码 cn 的密码
            env.put(Context.SECURITY_CREDENTIALS, "password");
            //url 格式:协议://ip:端口/组,域   ,直接连接到域或者组上面
            env.put(Context.PROVIDER_URL, "ldapurl");
            //协议
            env.put(Context.SECURITY_PROTOCOL, "ssl");
            env.put("java.naming.ldap.factory.socket", "DummySSLSocketFactory类全路径");
            //objectGUID 转换,很关键
            env.put("java.naming.ldap.attributes.binary","objectGUID");
            try {
                Control[] so
  • 2
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
要通过Java使用LDAP获取AD用户和组织信息,需要使用Java的JNDI API。 以下是一个简单的Java程序,演示如何使用JNDI API连接到AD获取用户和组织信息: ``` import java.util.*; import javax.naming.*; import javax.naming.directory.*; public class ADInfo { public static void main(String[] args) { String ldapURL = "ldap://AD服务器地址:389"; String ldapUser = "CN=LDAP查询用户,OU=xxx,DC=xxx,DC=xxx"; String ldapPassword = "LDAP查询用户密码"; String searchBase = "OU=xxx,DC=xxx,DC=xxx"; Hashtable<String, String> env = new Hashtable<String, String>(); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); env.put(Context.PROVIDER_URL, ldapURL); env.put(Context.SECURITY_AUTHENTICATION, "simple"); env.put(Context.SECURITY_PRINCIPAL, ldapUser); env.put(Context.SECURITY_CREDENTIALS, ldapPassword); try { DirContext ctx = new InitialDirContext(env); SearchControls searchControls = new SearchControls(); searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE); String filter = "(objectCategory=user)"; NamingEnumeration<SearchResult> results = ctx.search(searchBase, filter, searchControls); while (results.hasMore()) { SearchResult searchResult = results.next(); Attributes attributes = searchResult.getAttributes(); Attribute attribute = attributes.get("cn"); String cn = (String) attribute.get(); System.out.println(cn); } filter = "(objectCategory=organizationalUnit)"; results = ctx.search(searchBase, filter, searchControls); while (results.hasMore()) { SearchResult searchResult = results.next(); Attributes attributes = searchResult.getAttributes(); Attribute attribute = attributes.get("ou"); String ou = (String) attribute.get(); System.out.println(ou); } ctx.close(); } catch (NamingException e) { e.printStackTrace(); } } } ``` 在上面的代码中,替换以下变量: - ldapURL:AD服务器地址和端口号 - ldapUser:用于查询ADLDAP用户的DN - ldapPassword:用于查询ADLDAP用户的密码 - searchBase:要搜索的AD的基本DN 该程序连接到AD并搜索用户和组织。它使用过滤器来限制搜索结果,只搜索用户和组织单位对象。它还使用SearchControls对象来设置搜索范围。 对于每个搜索结果,程序从属性中提取cn或ou,并将其打印到控制台上。 请注意,此代码需要在Java应用程序中包含JNDI API类路径。如果您使用Maven或Gradle之类的构建工具,则可以将以下依赖项添加到项目中: ``` <dependency> <groupId>com.sun.jndi</groupId> <artifactId>ldap</artifactId> <version>1.2.1</version> </dependency> ```
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值