I've done a lot of Googling and seen several similar answers on this site, but nothing is working for me.
I have been trying to do a search of ActiveDirectory using LDAP. The search runs okay, but it never returns results. I am searching on userPrincipalName, and this user absolutely exists in ActiveDirectory.
String securityPrincipal;
securityPrincipal = "{0}@" +"ourcompany";
securityPrincipal = MessageFormat.format(securityPrincipal, username);
Hashtable<String,Object> env = new Hashtable<>();
env.put(Context.PROVIDER_URL, "ldaps://OURCOMPANY:636");
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
//Internal and external the same
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, securityPrincipal);
env.put(Context.SECURITY_CREDENTIALS, password);
env.put(Context.REFERRAL,"follow");
boolean success;
LdapContext ldapCtx = null;
try {
ldapCtx = new InitialLdapContext(env, null);
success = true;
} catch (NamingException ex) {
ex.printStackTrace();
success = false;
if(ldapCtx != null){
doSearch(ldapCtx)
}
private static final void doSearch(LdapContext ctx) throws NamingException{
NamingEnumeration results = null;
String domain = "DC=ourcompany,DC=com";
String organizationalUnit = "ou=external";
String searchUser;
searchUser = "[email protected]";
try {
DirContext schema = ctx.getSchema("");
String[] returning = {"userPrincipalName"};
SearchControls ctrls = new SearchControls();
ctrls.setSearchScope(SearchControls.SUBTREE_SCOPE);
ctrls.setReturningAttributes(returning);
Attributes attributes = new BasicAttributes(true);
attributes.put("userPrincipalName",searchUser);
results = ctx.search(organizationalUnit +"," +domain,attributes);
while (results.hasMoreElements()){
System.out.println("...");
}
System.out.println(results.hasMore());
}catch (NamingException ex){
ex.printStackTrace();
} finally {
results.close();
}
In addition to what is above, I've tried:
results = ctx.search(organizationalUnit +"," +domain,"(& (userPrincipalName=" +searchUser +"))",ctrls);
results = ctx.search(domain,"(& (userPrincipalName=" +searchUser +"))",ctrls);
ctrls.setReturningAttributes()
ctrls.setSearchScope(SearchControls.OBJECT_SCOPE);
This should be returning results. Results is not null, but results.entries() is empty.
Since AD is a Microsoft tool, its responses are not driven to help. Are driven to be impossible to understand and to require a payed support. Here a response sample if you are sending something that AD don't understand or support. It is so complex to figure out the error reason/cause.
[LDAP: error code 16 - 000016515: LdapErr: DSID-066675D87, data 0, v64xyz]
You need to find the exact context object or location in which your user exist.
image source: https://www.informit.com/articles/article.aspx?p=101405&seqNum=7
option #1
What helped me was to access to the AD Admin GUI and put the mouse over the user and then a popup will appear with the exact context of this object. Also at the top of ui appear the required context. If user don't exist, create a new one.
option #2
Also you can obtain the same value using the Distinguished attribute, editing the user as Admin
Source: https://windowstechno.com/how-to-check-the-distinguished-name-dn/
Just to try, you could design a request with these values:
Field | Sample Value |
---|---|
objectLocation | OU=users,DC=foo,DC=bar,etc=wtf |
searchQuery | ([email protected]) |
And I use these values in my code:
LdapContext ctx = new InitialLdapContext(environment, null);
ctx.setRequestControls(null);
NamingEnumeration<?> searchResultEnum =
ctx.search(objectLocation, searchQuery, getSimpleSearchControls());
This will help you to try dozens of combinations until you find the exact objectLocation