使用LDAP从Active Directory中检索用户属性 - JAVA

问题描述:

编辑:我已经发布了下面的解决方案。使用LDAP从Active Directory中检索用户属性 - JAVA

我知道你不喜欢这类问题,但我一直在为这个问题奋斗半天了。

我写了一个C#代码,它使用LDAP从我们的Active Directory中获取用户属性,代码运行良好。

的代码如下:

 DirectoryEntry dirEnt = new DirectoryEntry("LDAP://dc=dom,dc=int"); 
     DirectorySearcher adSearch = new DirectorySearcher(dirEnt); 
     adSearch.SearchScope = SearchScope.Subtree; 
     adSearch.PageSize = 10000; 
     adSearch.Filter = "(&(objectClass=user))"; 
     SearchResultCollection sColl = adSearch.FindAll(); 

     foreach (SearchResult sResult in sColl) 
     { 
      string sConn = sResult.Properties["distinguishedName"][0].ToString(); 
      DirectoryEntry dirEnt2 = new DirectoryEntry("LDAP://" + sConn); 
      ... 
      // dirEnt2 contains ALL attributes for the user 
     } 

我试图端口的代码到Java,但似乎我在C#中使用的技术并不在Java的工作也很好。

使用以下代码

DirContext context; 
ArrayList<String> nList = new ArrayList<String>(); 
Hashtable env = new Hashtable(); 
String username = ...; 
String password = ...; 

try { 
    env.put(Context.SECURITY_PRINCIPAL, username); 
    env.put(Context.SECURITY_CREDENTIALS, password); 

    env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); 
    env.put(Context.PROVIDER_URL, ldapUri); 

    try { 
     context = new InitialDirContext(env); 
    } catch (NamingException e) { 
     throw new RuntimeException(e); 
    } 

    SearchControls ctrl = new SearchControls(); 
    ctrl.setSearchScope(SearchControls.SUBTREE_SCOPE); 

    NamingEnumeration enumeration = context.search("", "(objectClass=user)", 
                ctrl); 
    while (enumeration.hasMore()) { 
     SearchResult result = (SearchResult) enumeration.next(); 
     Attributes attribs = result.getAttributes(); 
     NamingEnumeration values = ((BasicAttribute) 
            attribs.get("distinguishedName")).getAll(); 
     while (values.hasMore()) { 
      nList.add(values.next().toString()); 
      } 
     } 

    } catch (NamingException e) { 
     e.printStackTrace(); 
    } 

    for (String sVar : nList){ 
     Hashtable env2 = new Hashtable(); 
     env2.put(Context.SECURITY_PRINCIPAL, username); 
     env2.put(Context.SECURITY_CREDENTIALS, password); 
     env2.put(Context.INITIAL_CONTEXT_FACTORY, 
       "com.sun.jndi.ldap.LdapCtxFactory"); 
     env2.put(Context.PROVIDER_URL, "ldap://DOM/" + sVar); 
     Attributes attrs = null; 
     try { 
      context = new InitialDirContext(env2); 
      attrs = context.getAttributes(sVar); 
     } catch (NamingException e) { 
      System.out.println(e.toString()); 
      continue; 
     } 

     System.out.println(attrs.toString()); 
    } 

产量该ATTRS仅包含关于用户(如Sam帐户,显示名称等)基本属性 和没有“电子邮件”,“电话”或任何其它类似的属性。

在这个问题上的任何帮助是有福的!

这里的解决方案,比较遗憾的是乱码设置返回的属性/格式化

import java.util.Hashtable; 
import javax.naming.Context; 
import javax.naming.NamingEnumeration; 
import javax.naming.NamingException; 
import javax.naming.directory.*; 
import javax.naming.ldap.*; 

public class UserFetch { 
    public static void main(String[] args) { 
     try{ 
      // Activate paged results 
      byte[] cookie = null; 
      int count=0; 
      int total; 

      Hashtable env = new Hashtable(); 

      env.put(Context.INITIAL_CONTEXT_FACTORY, 
      "com.sun.jndi.ldap.LdapCtxFactory"); 
      env.put(Context.REFERRAL, "follow"); 
      env.put(Context.SECURITY_AUTHENTICATION, "Simple"); 
      env.put(Context.SECURITY_PRINCIPAL, "[email protected]"); 
      env.put(Context.SECURITY_CREDENTIALS, "PASSWORD"); 
      env.put(Context.PROVIDER_URL, "ldap://DOM.COM:389"); 
      LdapContext ctx = new InitialLdapContext(env, null); 

      ctx.setRequestControls(new Control[]{ 
       new PagedResultsControl(10000, Control.CRITICAL) }); 

      do { 
       // Perform the search 
       NamingEnumeration results = 
       ctx.search("dc=DOM,dc=COM", "(&(objectclass=user)(employeeNumber=*))", getSimpleSearchControls()); 

       // Iterate over a batch of search results 
       while (results != null && results.hasMore()) { 
        // Display an entry 
        SearchResult entry = (SearchResult)results.next(); 
        Attributes attrs = entry.getAttributes(); 
        System.out.println(attrs.get("SAMAccountName")); // Username 
        System.out.println("Firstname: " + 
        attrs.get("givenname")); // firstname 
        System.out.println("Lastname: " + attrs.get("sn")); // lastname 
        System.out.println("EmployeeID " + attrs.get("employeeID")); 
        System.out.println("EmployeeNumber: " + 
        attrs.get("employeeNumber")); 
        // Handle the entry's response controls (if any) 
       } 
       // Examine the paged results control response 
       Control[] controls = ctx.getResponseControls(); 
       if (controls != null) { 
        for (int i = 0; i < controls.length; i++) { 
         if (controls[i] instanceof PagedResultsResponseControl) { 
          PagedResultsResponseControl prrc = 
          (PagedResultsResponseControl)controls[i]; 
          total = prrc.getResultSize(); 
          cookie = prrc.getCookie(); 
         } else { 
          // Handle other response controls (if any) 
         } 
        } 
       } 

       // Re-activate paged results 
       ctx.setRequestControls(new Control[]{ 
        new PagedResultsControl(10000, cookie, Control.CRITICAL) }); 
      } while (cookie != null); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    public static SearchControls getSimpleSearchControls() { 
     SearchControls searchControls = new SearchControls(); 
     searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE); 
     searchControls.setTimeLimit(30000); 
     String[] attrIDs = 
     { "SAMAccountName", "sn", "givenname", "employeeID", 
      "employeeNumber" }; 

     searchControls.setReturningAttributes(attrIDs); 
     return searchControls; 
    } 


} 
+0

嗨,我试图使用此代码,但我得到“javax.naming.NamingException:LDAP响应读取超时,超时使用:-1ms。”我无法找到这个来源。有什么建议么 ? – 2015-10-06 16:07:33

+0

@BhanuKaushik您是否正确设置了PROVIDER_URL? – Shai 2015-10-06 16:08:26

+0

是的。当我将身份验证设置为无时,我使用同一个Url获取上下文。 (这让我相信它不是一个“简单”)。 – 2015-10-06 16:51:21

尝试在您SearchControls

ctrl.setReturningAttributes(new String[] {"email", "telephone"}); 
+0

谢谢您的回答,没有运气.. – Shai 2012-02-01 06:34:06