2010-06-22 72 views
5

我們的開發人員在Linux上使用Java進行各種操作(如檢查組的成員身份等)。它的工作 - 沒有問題!我不是一個如此裸露在我身邊的開發者。使用LDAP從Java(Linux)向Active Directory進行身份驗證無需servername

問題是,他們已經在其代碼中硬編碼了我們的域控制器(LDAP-服務器)的服務器名稱。所以現在當我們需要用新的DC替換它們時,他們需要更改代碼。

活動目錄本質上是多餘的。域名(例如:domain.local)是我們AD可用的所有DC的循環法。

開發人員是否有任何方法不指定域控制器服務器名稱,而只是指定Active Directory域名,然後他們的Linux服務器將找到可用的DC:並使用哪個啓動並運行?

示例/鏈接讚賞。謝謝!

回答

8

顯然,服務器名稱應該至少是可配置的,而不是硬編碼到應用程序中。

但是,您應該能夠通過查找特殊DNS記錄(即_ldap._tcp.DOMAINNAME的SRV記錄)來查找服務器。 Linux服務器必須配置爲使用與AD更新相同的DNS服務器。

要確定這是否是可行的,你的Linux服務器

又見Querying the DNS service records to find the hostname and TCP/IP提供了有關如何查找SRV記錄在java中的一些信息上運行命令host -t srv _ldap._tcp.DOMAINNAME,並https://community.oracle.com/blogs/kohsuke/2008/06/12/more-active-directory-integration-java

2

我們使用如下代碼在大量系統上工作:

/** 
* Detect the default LDAP server 
* @return server:port or null 
*/ 
String getDefaultLdapHost() { 
    try { 
     Hashtable<String, String> env = new Hashtable(); 
     env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory"); 
     DirContext dns = new InitialDirContext(env); 

     InetAddress address = InetAddress.getLocalHost(); 
     String domain = address.getCanonicalHostName(); 

     if(domain.equals(address.getHostAddress())) { 
      //domain is a ip address 
      domain = getDnsPtr(dns); 
     } 

     int idx = domain.indexOf('.'); 
     if(idx < 0) { 
      //computer is not in a domain? We will look in the DNS self. 
      domain = getDnsPtr(dns); 
      idx = domain.indexOf('.'); 
      if(idx < 0) { 
       //computer is not in a domain 
       return null; 
      } 
     } 
     domain = domain.substring(idx + 1); 

     Attributes attrs = dns.getAttributes("_ldap._tcp." + domain, new String[] { "SRV" }); 

     Attribute attr = attrs.getAll().nextElement(); 
     String srv = attr.get().toString(); 

     String[] parts = srv.split(" "); 
     return parts[3] + ":" + parts[2]; 
    } catch(Exception ex) { 
     ex.printStackTrace(); 
     return null; 
    } 
} 

/** 
* Look for a reverse PTR record on any available ip address 
* @param dns DNS context 
* @return the PTR value 
* @throws Exception if the PTR entry was not found 
*/ 
private String getDnsPtr(DirContext dns) throws Exception { 
    Exception exception = null; 
    Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces(); 
    while(interfaces.hasMoreElements()) { 
     NetworkInterface nif = interfaces.nextElement(); 
     if(nif.isLoopback()) { 
      continue; 
     } 
     Enumeration<InetAddress> adresses = nif.getInetAddresses(); 
     while(adresses.hasMoreElements()) { 
      InetAddress address = adresses.nextElement(); 
      if(address.isLoopbackAddress() || address instanceof Inet6Address) { 
       continue; 
      } 
      String domain = address.getCanonicalHostName(); 
      if(!domain.equals(address.getHostAddress()) && (domain.indexOf('.') > 0)) { 
       return domain; 
      } 

      String ip = address.getHostAddress(); 
      String[] digits = ip.split("\\."); 
      StringBuilder builder = new StringBuilder(); 
      builder.append(digits[3]).append('.'); 
      builder.append(digits[2]).append('.'); 
      builder.append(digits[1]).append('.'); 
      builder.append(digits[0]).append(".in-addr.arpa."); 
      try { 
       Attributes attrs = dns.getAttributes(builder.toString(), new String[] { "PTR" }); 
       return attrs.get("PTR").get().toString(); 
      } catch(Exception ex) { 
       exception = ex; 
      } 
     } 
    } 
    if(exception != null) { 
     throw exception; 
    } 
    throw new IllegalStateException("No network"); 
} 
相關問題