Поиск в AD, используя пользователя из другого AD с Java
У меня есть два Active Directory в двух доменах: domain1.xx и domain2.xx У меня есть пользователь, который принадлежит domain1.xx с именем user1. Я могу делать запросы LDAP на domain1, используя user1. Пользователь user1 имеет право на чтение на domain2.xx, и я проверил это с помощью AD Explorer, и это сработало. Проблема в том, что когда я использую Java, он возвращает мне это исключение: ОШИБКА: [LDAP: код ошибки 49 - 80090308: LdapErr: DSID-0C090334, комментарий: ошибка AcceptSecurityContext, данные 525, vece
этот код, соединяющий запросы в domain1 и что он работает:
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 может прочитать все OU в domain2.xx я пробовал это с AD Explorer.
1 ответ
Отправленная вами ошибка аутентификации содержит специальный код, который может быть полезен. В вашем случае код 525 (ошибка AcceptSecurityContext, данные 525). Код 525 означает "Пользователь не найден". Судя по вашему коду, вы повторно используете одного и того же пользователя - user1 @ domain1. Этот пользователь СУЩЕСТВУЕТ только в домене 1. Домен 2 не знает об этом пользователе, поэтому контроллер домена AD отклоняет попытку аутентификации.
Примеры кода, прилагаемые к вопросу, работают с определенными контроллерами домена, а не с глобальными каталогами. Попробуйте сделать следующее:
- использовать InitialLdapContext вместо InitialDirContext
- привязка к глобальному каталогу вместо контроллера домена. Для этого используйте URL-адрес ldap: // FQDN: 3268. Пожалуйста, не порт 3268.
Обратите внимание, что порт 3268 не является безопасным.
Надеюсь это поможет.