【问题标题】:Retrieving user attributes from Active Directory using LDAP - JAVA使用 LDAP 从 Active Directory 检索用户属性 - JAVA
【发布时间】:2013-03-24 17:30:11
【问题描述】:

编辑:我在下面发布了解决方案。

我知道你不喜欢这类问题,但我已经为这个问题苦苦挣扎了半天了。

我编写了一个 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 只包含有关用户的 BASIC 属性(例如 samaccountname、displayname 等) 并且没有“电子邮件”、“电话”或任何其他类似属性。

对这个问题的任何帮助都是有福的!

【问题讨论】:

    标签: c# java active-directory ldap


    【解决方案1】:

    这是解决方案,抱歉代码/格式混乱

    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, "USERNAME@DOM.COM");
                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;
        }
    
    
    }
    

    【讨论】:

    • 嗨,我正在尝试使用此代码,但我得到“javax.naming.NamingException:LDAP 响应读取超时,使用超时:-1ms。”我无法找到这个的来源。有什么建议吗?
    • @BhanuKaushik 您是否正确设置了 PROVIDER_URL?
    • 是的。当我将身份验证设置为无时,我会使用相同的 Url 获得上下文。 (这让我相信它不是“简单”)。
    【解决方案2】:

    尝试在您的 SearchControls 上设置返回的属性

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-05
      • 1970-01-01
      • 1970-01-01
      • 2017-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多