3

I am trying to retrieve data from a LDAP server but it fails. (Connecting works). It is quite hard for me to understand which parameters are needed in the search() method in the last line... "mail" is the information I am trying to get, userName is the user which is authenticated.

 DirContext authContext = new InitialDirContext(authEnv);
 SearchControls constraints = new SearchControls();
 constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
 NamingEnumeration results = authContext.search("mail", userName, constraints);

This is my error message (comes up in the last line):

 javax.naming.directory.InvalidSearchFilterException: Missing 'equals'; remaining name 'mail'
at com.sun.jndi.ldap.Filter.encodeSimpleFilter(Unknown Source)
at com.sun.jndi.ldap.Filter.encodeFilter(Unknown Source)
at com.sun.jndi.ldap.Filter.encodeFilterString(Unknown Source)
at com.sun.jndi.ldap.LdapClient.search(Unknown Source)
at com.sun.jndi.ldap.LdapCtx.doSearch(Unknown Source)
at com.sun.jndi.ldap.LdapCtx.searchAux(Unknown Source)
at com.sun.jndi.ldap.LdapCtx.c_search(Unknown Source)
at com.sun.jndi.toolkit.ctx.ComponentDirContext.p_search(Unknown Source)
at com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.search(Unknown Source)
at com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.search(Unknown Source)
at javax.naming.directory.InitialDirContext.search(Unknown Source)
at Client.connect(Client.java:48)
at Client.main(Client.java:23)

Thanks for all the answers, if I change my code as requested, I get the following error:

  javax.naming.NamingException: [LDAP: error code 1 - 000004DC: LdapErr: DSID-0C0906E9, 
  comment: In order to perform this operation a successful bind must be completed on the 
  connection., data 0, v1db1

My code for connecting is this one:

    Properties authEnv = new Properties();
    String userName = "XXX";
    String passWord = "XXX";
    String base = "XXX";
    String dn = "uid=" + userName + "," + base;
    String ldapURL = "XXX";

    authEnv.put(Context.INITIAL_CONTEXT_FACTORY,
            "com.sun.jndi.ldap.LdapCtxFactory");
    authEnv.put(Context.PROVIDER_URL, ldapURL);
    authEnv.put(Context.SECURITY_AUTHENTICATION, "none");
    authEnv.put(Context.SECURITY_PRINCIPAL, dn);
    authEnv.put(Context.SECURITY_CREDENTIALS, passWord);
Brad Larson
  • 170,088
  • 45
  • 397
  • 571
Jane Doe
  • 409
  • 3
  • 6
  • 18

5 Answers5

3

It's not possible to give you exact answer without knowing your schema.

 LdapContext authContext = new InitialLdapContext(authEnv, null);
 SearchControls constraints = new SearchControls();
 String []returnedAttributes = {"mail"};
 String filter = "(userName={0})"; // You might want to limit search to user objects only based on objectClass
 String []filterAttributes = {userName};
 String baseDN = "CN=user,DC=company,DC=org"; // Replace this with the real baseDN
 constraints.setReturningAttributes(returnedAttributes)
 constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
 NamingEnumeration<SearchResult> results = authContext.search(baseDN, filter, filterAttributes, constraints);
Sami Korhonen
  • 1,254
  • 8
  • 17
  • Thanks, my schema looks like this: DC = aaa, ou = bbb, OU = ccc, ou = ddd, ou = eee, ou = fff. Then comes cn (my user for example) – Jane Doe Mar 06 '13 at 12:26
2

You have several issues in your code. You are using Active Directory so the use of uid is not going to work. You would need to use CN.

You do not show your baseDN, but are you sure you know what it is? Check "The Hard Part"

Likewise, the ldapURL. Do as suggested, get a known LDAP browser and make a connection. Using Microsoft LIBs (or VB) will not show LDAP communication properly as MS does a lot of work under the covers for you. My current favorite.

Try someone else's code that is know to work against AD.

user207421
  • 305,947
  • 44
  • 307
  • 483
jwilleke
  • 10,467
  • 1
  • 30
  • 51
1

you are doing wrong in this line:

NamingEnumeration results = authContext.search("mail", userName, constraints);

the first argument to authContext.search is the base, its should be your server's domain

ex:

ou=People,dc=google,dc=com

Note: use some graphical LDAP Browser to figure out the domain

codeMan
  • 5,730
  • 3
  • 27
  • 51
1

A search request consists of, at a minimum:

  • the base object, below which entries are candidates for being returned in the search result
  • the scope of the search (base, one, or sub)
  • a filter to determine which candidates are returned in the search result, for example, mail=* (present), cn=Stack Overflow (equality), cn=Stack* (substring)
  • a list of attributes to return

Entries are candidates for being returned:

  • if they are at or below the search base (with the exception of search scope one in which only the entries immediately subordinate to the base object are returned but not the base object itself)
  • the assertion in the filter matches attribute values in the entry, for example, the present filter mail=* would match all entries at or below the base object that have a mail attribute except for search scope one as noted

see also

Terry Gardner
  • 10,957
  • 2
  • 28
  • 38
1

Check Oracles tutorials on this: http://docs.oracle.com/javase/tutorial/jndi/ldap/jndi.html

In your example the first parameter should be the search base, means where your users are located within the directory, i.e. "ou=people". The second one is the search filter, in your example probably some attribute you can match the user against. i.e. "sn="+userName (<- Should be encoded).

The value of "mail" should be within the result, as this is the information you want to get.

Also see http://docs.oracle.com/javase/1.6/docs/api/javax/naming/directory/DirContext.html

LDAP is not easy, try to find some good tutorials to get started with.

Adrian
  • 2,233
  • 1
  • 22
  • 33