java - 使用 java 使用另一个 AD 中的用户在 AD 中进行搜索

标签 java active-directory ldap-query

我在两个域中有两个 Active Directory:domain1.xx 和 domain2.xx 我有一个属于domain1.xx 的用户,名为user1。 我可以使用 user1 对domain1 进行LDAP 查询。 user1 对domain2.xx 有读取权限,我已经使用 AD Explorer 对其进行了测试,并且它有效。 问题是当我使用java时,它返回给我这个异常: 错误:[LDAP:错误代码 49 - 80090308:LdapErr:DSID-0C090334,注释:AcceptSecurityContext 错误,数据 525,vece

这是连接域1中的查询的代码并且它有效:

package ad;

import java.util.Enumeration;
import java.util.Hashtable;
import javax.naming.AuthenticationException;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.directory.Attribute;
import javax.naming.directory.DirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;

public class AD {


    static DirContext ldapAuthenticate(String password, String userdn) throws Exception {
        Hashtable env = new Hashtable();
        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        //set security credentials, note using simple cleartext authentication
        env.put(Context.SECURITY_AUTHENTICATION, "simple");
        env.put(Context.SECURITY_PRINCIPAL, userdn);
        env.put(Context.SECURITY_CREDENTIALS, password);
        //connect to my domain controller
        env.put(Context.PROVIDER_URL, "ldap://domain1.xx");
        //Create the initial directory context
        DirContext ctx = null;
        try {

            ctx =  new javax.naming.directory.InitialDirContext(env);

        } catch (AuthenticationException e) {

            System.out.println("ERROR: "+e.getMessage());
        } catch (Exception e) {
            System.out.println("ERROR: "+e.getMessage());
                       //something went wrong
            ///handle in some way
        }
        return ctx;
    }

    public static void main(String[] args) throws Exception {
        DirContext context = ldapAuthenticate("xxxxxx","user01@domain1.xx");
        String userdn = "dc=domain1,dc=xx";
        SearchControls searchCtrls = new SearchControls();
        searchCtrls.setSearchScope(SearchControls.SUBTREE_SCOPE);
        String[] attributes = {"member"};
        searchCtrls.setReturningAttributes(attributes);

        //Change the NameOfGroup for the group name you would like to retrieve the members of.
        String filter ="objectclass=*";
        NamingEnumeration values = context.search(userdn, filter, null);

        //Loop through the search results
        while (values.hasMoreElements()) {
            SearchResult sr = (SearchResult) values.next();
            System.out.println(">>>" + sr.getName());
            javax.naming.directory.Attributes attrs = sr.getAttributes();

            if (null != attrs) {
                for (NamingEnumeration ae = attrs.getAll(); ae.hasMoreElements();) {
                    Attribute atr = (Attribute) ae.next();
                    String attributeID = atr.getID();
                    Enumeration vals = atr.getAll();

                    if (vals.hasMoreElements()) {
                        String username = (String) vals.nextElement();
                        System.out.println("Username: " + username);

                    }
                }
            } else {
                System.out.println("No members for groups found");
            }
        }
    }
}

当我想查询domain2.xx时,我遇到了异常:

package ad;

import java.util.Enumeration;
import java.util.Hashtable;
import javax.naming.AuthenticationException;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.directory.Attribute;
import javax.naming.directory.DirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;

public class AD {


    static DirContext ldapAuthenticate(String password, String userdn) throws Exception {
        Hashtable env = new Hashtable();
        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        //set security credentials, note using simple cleartext authentication
        env.put(Context.SECURITY_AUTHENTICATION, "simple");
        env.put(Context.SECURITY_PRINCIPAL, userdn);
        env.put(Context.SECURITY_CREDENTIALS, password);
        //connect to my domain controller
        env.put(Context.PROVIDER_URL, "ldap://domain2.xx");
        //Create the initial directory context
        DirContext ctx = null;
        try {

            ctx =  new javax.naming.directory.InitialDirContext(env);

        } catch (AuthenticationException e) {

            System.out.println("ERROR: "+e.getMessage());
        } catch (Exception e) {
            System.out.println("ERROR: "+e.getMessage());
                       //something went wrong
            ///handle in some way
        }
        return ctx;
    }

    public static void main(String[] args) throws Exception {
        DirContext context = ldapAuthenticate("xxxxxx","user01@domain1.xx");
        String userdn = "dc=domain2,dc=xx";
        SearchControls searchCtrls = new SearchControls();
        searchCtrls.setSearchScope(SearchControls.SUBTREE_SCOPE);
        String[] attributes = {"member"};
        searchCtrls.setReturningAttributes(attributes);

        //Change the NameOfGroup for the group name you would like to retrieve the members of.
        String filter ="objectclass=*";
        NamingEnumeration values = context.search(userdn, filter, null);

        //Loop through the search results
        while (values.hasMoreElements()) {
            SearchResult sr = (SearchResult) values.next();
            System.out.println(">>>" + sr.getName());
            javax.naming.directory.Attributes attrs = sr.getAttributes();

            if (null != attrs) {
                for (NamingEnumeration ae = attrs.getAll(); ae.hasMoreElements();) {
                    Attribute atr = (Attribute) ae.next();
                    String attributeID = atr.getID();
                    Enumeration vals = atr.getAll();

                    if (vals.hasMoreElements()) {
                        String username = (String) vals.nextElement();
                        System.out.println("Username: " + username);

                    }
                }
            } else {
                System.out.println("No members for groups found");
            }
        }
    }
}

任何人都可以帮忙解决这个案子吗? user01@domain1.xx 可以读取 domain2.xx 中的所有 OU,我已经使用 AD 资源管理器尝试过。

最佳答案

您发布的身份验证错误包含可能有用的特殊代码。在您的例子中,代码为 525(AcceptSecurityContext 错误,数据 525)。代码 525 表示“未找到用户”。根据您的代码判断,您正在重复使用同一用户 - user1@domain1。该用户仅存在于域 1 中。域 2 不知道该用户,因此 AD 域 Controller 拒绝身份验证尝试。

问题附带的代码示例针对特定域 Controller 而不是全局编录运行。尝试执行以下操作:

  • 使用InitialLdapContext代替InitialDirContext
  • 绑定(bind)到全局编录而不是域 Controller 。为此,请使用 URL ldap://FQDN:3268。请注意端口是 3268。

请注意,端口 3268 不安全。

希望这有帮助。

关于java - 使用 java 使用另一个 AD 中的用户在 AD 中进行搜索,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33482393/

相关文章:

powershell - 如何使用 PowerShell 将当前日期计算为自 1601-01-01 以来的毫秒数

ldap - 如何在 LDAP3 中创建一个新的对象类?

java - OSGi 服务未实现接口(interface)

java.lang.IllegalStateException : You must either set a text or a view

java - Spring FactoryBean 和 Autowiring 不起作用 : expected single matching bean but found 2

c++ - 如何在未使用 C++ 连接到 DC 时获取成员计算机的专有名称

c# - 为什么 User.Invoke ("SetPassword") 使用我计算机的当前凭据以及我如何指定它们?

azure - 我想要具有多个范围的访问 token ,包括 http

java - Apache POI Powerpoint 替代方案

filter - 编写 LDAP 查询过滤器