ADLdapAnonymousConnector.java 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. package com.admanager;
  2. import javax.naming.Context;
  3. import javax.naming.NamingEnumeration;
  4. import javax.naming.NamingException;
  5. import javax.naming.directory.SearchControls;
  6. import javax.naming.directory.SearchResult;
  7. import javax.naming.ldap.InitialLdapContext;
  8. import javax.naming.ldap.LdapContext;
  9. import java.util.ArrayList;
  10. import java.util.Hashtable;
  11. import java.util.List;
  12. public class ADLdapAnonymousConnector implements AutoCloseable {
  13. private LdapContext ldapContext;
  14. private final String domain;
  15. private final String ldapUrl;
  16. private final String baseDn;
  17. public ADLdapAnonymousConnector(String domain, String ldapUrl) {
  18. this.domain = domain;
  19. this.ldapUrl = ldapUrl;
  20. this.baseDn = convertDomainToDn(domain);
  21. }
  22. public void connect() throws NamingException {
  23. Hashtable<String, Object> env = new Hashtable<>();
  24. env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
  25. env.put(Context.PROVIDER_URL, ldapUrl);
  26. env.put(Context.SECURITY_AUTHENTICATION, "none");
  27. // 重要:添加连接池和超时设置
  28. env.put("com.sun.jndi.ldap.connect.pool", "true"); // 启用连接池
  29. env.put("com.sun.jndi.ldap.connect.timeout", "3000");
  30. env.put("com.sun.jndi.ldap.read.timeout", "5000");
  31. this.ldapContext = new InitialLdapContext(env, null);
  32. System.out.println("成功匿名连接到: " + domain);
  33. }
  34. public List<SearchResult> search(String filter) throws NamingException {
  35. return search(baseDn, filter, null);
  36. }
  37. public List<SearchResult> search(String searchBase, String filter, String[] attributes)
  38. throws NamingException {
  39. checkConnected();
  40. SearchControls controls = new SearchControls();
  41. controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
  42. controls.setCountLimit(100); // 限制返回数量
  43. if (attributes != null) {
  44. controls.setReturningAttributes(attributes);
  45. }
  46. // 使用新上下文避免连接被关闭
  47. try {
  48. LdapContext searchContext = (LdapContext) ldapContext.lookup("");
  49. List<SearchResult> results = new ArrayList<>();
  50. NamingEnumeration<SearchResult> searchResults =
  51. searchContext.search(searchBase, filter, controls);
  52. while (searchResults.hasMore()) {
  53. results.add(searchResults.next());
  54. }
  55. return results;
  56. } catch (Exception e) {
  57. e.printStackTrace();
  58. return null;
  59. }
  60. }
  61. @Override
  62. public void close() throws NamingException {
  63. if (ldapContext != null) {
  64. ldapContext.close();
  65. ldapContext = null;
  66. System.out.println("连接已关闭");
  67. }
  68. }
  69. private void checkConnected() throws NamingException {
  70. if (ldapContext == null) {
  71. throw new NamingException("未建立连接");
  72. }
  73. }
  74. private static String convertDomainToDn(String domain) {
  75. return "dc=" + domain.replace(".", ",dc=");
  76. }
  77. public static void main(String[] args) {
  78. String domain = "tlct.com.cn";
  79. String ldapUrl = "ldap://admserver.tlct.com.cn:389";
  80. try (ADLdapAnonymousConnector connector = new ADLdapAnonymousConnector(domain, ldapUrl)) {
  81. connector.connect();
  82. // 测试查询
  83. List<SearchResult> users = connector.search("(objectClass=user)");
  84. System.out.println("找到 " + users.size() + " 个用户");
  85. for (SearchResult user : users) {
  86. System.out.println("DN: " + user.getNameInNamespace());
  87. }
  88. } catch (NamingException e) {
  89. System.err.println("操作失败: " + e.getMessage());
  90. if (e.getRootCause() != null) {
  91. System.err.println("根本原因: " + e.getRootCause().getMessage());
  92. }
  93. e.printStackTrace();
  94. }
  95. }
  96. }