Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Spring LDAP's LdapTemplate not return title, department & company attributes?

I'm using spring-ldap-core-2.3.1.RELEASE.jar over JDK 1.8 & Tomcat 8.0 to access AD information through LdapTemplate. The attributes such as title,department & company are not being returned by the ldapTemplate.search(..,.,..) method.

I'm using the following lines of code to search :-

LdapQuery ldapQuery = LdapQueryBuilder.query()
                                       .where("objectclass").is("user")
                                       .and("objectcategory").is("person")
                                       .and("cn").like(strWildcardText+"*");
ldapTemplate.search(ldapQuery, new ADUserAttributesMapper());

Following is the ADUserAttributesMapper class :-

public class ADUserAttributesMapper implements AttributesMapper<ADUserBean> {
    @Override
    public ADUserBean mapFromAttributes(Attributes attributes) throws NamingException {
        if(attributes==null) {
            return null;
        }

        adUserBean.setName((attributes.get("name")!=null) ? attributes.get("name").get().toString() : null);
        adUserBean.setCommonName((attributes.get("cn")!=null) ? attributes.get("cn").get().toString() : null);
        adUserBean.setDisplayName((attributes.get("displayname")!=null) ? attributes.get("displayname").get().toString() : null);
        adUserBean.setGivenName((attributes.get("givenname")!=null) ? attributes.get("givenname").get().toString() : null); // for FIRST NAME
        adUserBean.setMiddleName((attributes.get("initials")!=null) ? attributes.get("initials").get().toString() : null); // for MIDDLE NAME / INITIALS
        adUserBean.setLastName((attributes.get("sn")!=null) ? attributes.get("sn").get().toString() : null); // for LAST NAME
        adUserBean.setDepartment((attributes.get("department")!=null) ? attributes.get("department").get().toString() : null);
        adUserBean.setUserPrincipalName((attributes.get("userprincipalname")!=null) ? attributes.get("userprincipalname").get().toString() : null); // Logon Name
        adUserBean.setsAMAccountName((attributes.get("samaccountname")!=null) ? attributes.get("samaccountname").get().toString() : null); // Logon Name (pre-Windows 2000)
        adUserBean.setDistinguishedName((attributes.get("distinguishedname")!=null) ? attributes.get("distinguishedname").get().toString() : null);
        adUserBean.setMailID((attributes.get("mail")!=null) ? attributes.get("mail").get().toString() : null);
        adUserBean.setTitle((attributes.get("title")!=null) ? attributes.get("title").get().toString() : null); // Job Title
        adUserBean.setTelephoneNumber((attributes.get("telephonenumber")!=null) ? attributes.get("telephonenumber").get().toString() : null);
        adUserBean.setObjectCategory((attributes.get("objectcategory")!=null) ? attributes.get("objectcategory").get().toString() : null);

        return adUserBean;
    }
}

The title,department & company attributes belong to the Organization tab of the AD user properties as shown in the below image :- enter image description here

Also, from the General tab the initials(initials) attribute is not being picked up/listed by Spring-LDAP's ldapTemplate. The LdapQueryBuilder.query() object has access to attributes(...) method that takes a string array of attribute names that are to be fetched. But even after mentioning them there explicitly, values for attributes such as initials, title, department & company are not returned.

The LDAP Browser plugin within the Eclipse IDE lists the title,department & company properties under the Organization tab without a problem.

Even the com4j API returns the title, department & company attributes.

Is there any configuration that is limiting the attribute(s) listing or is it a limitation with Spring-LDAP API itself? Are these attributes not part of BasicAttributes? How to fetch these attributes through Spring-LDAP?

UPDATE (01-Aug-2017): The plain Java JNDI approach/code does NOT return department,company,title attributes (even with these attributes being explicitly mentioned in attributes string array), but surprisingly it does return the initials attribute value.

UPDATE (02-Aug-2017): Similar to @Pierre's suggestion (below) tried the following code using SearchControls object :-

String strFilter= "(&(objectclass=top)(cn=cgma*))";
String[] attrs = new String[] {"cn","givenName","sn","initials","title","department","company"};
long maxResults = 10; // for example 
SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
searchControls.setReturningAttributes(attrs);
searchControls.setCountLimit(maxResults);
List<String> aLstOfADUsers = ldapTemplate.search("",strFilter,searchControls,new AttributesMapper<String>() 
                                                                     {
                                                                        public String mapFromAttributes(Attributes attrs) throws NamingException {
                                                                            try
                                                                            {
                                                                                System.out.println(attrs.toString());
                                                                                return attrs.get("cn").get().toString();
                                                                            }
                                                                            catch(Exception ex) {
                                                                                ex.printStackTrace();
                                                                                return null;
                                                                            }
                                                                        }
                                                                     });

return aLstOfADUsers;

Even this does not return the initials, title, company & department attribute values.

like image 228
Shiva Avatar asked Jul 25 '17 06:07

Shiva


1 Answers

The person attributes might be internal attributes which you wouldn't get back by default. You can specify explicitly which attributes you want returned BUT not in the search method you're using (the one where you pass in an LdapQuery object). If you take a look at the org.springframework.ldap.core.LdapTemplate class, it doesn't seem like you can pass in the SearchControls object to the method signature you're using. So, to be able to specify attributes to fetch, replace this:

LdapQuery ldapQuery = LdapQueryBuilder.query()
                                       .where("objectclass").is("user")
                                       .and("objectcategory").is("person")
                                       .and("cn").like(strWildcardText+"*");
ldapTemplate.search(ldapQuery, new ADUserAttributesMapper());

With this:

        LikeFilter filter = new LikeFilter("cn", strWildcardText+"*");

        // list of attributes to retrieve
        String[] attrs = new String[] {"title","department","company"};
        long maxResults = 10; // for example 

        SearchControls searchControls = new SearchControls();
        searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
        searchControls.setReturningAttributes(attrs);
        searchControls.setCountLimit(numResults);

        ldapTemplate.search(DistinguishedName.EMPTY_PATH, filter.encode(), searchControls, new ADUserAttributesMapper());

The above should work. You could also try something like this (I haven't tried that yet):

ldapTemplate.search( "dc=yourorg,dc=com", 
        "(&(cn=" +strWildcardText + "*)(&(objectClass=person)(objectcategory=person)))",
        SearchControls.SUBTREE_SCOPE,
        new String[]{ "title","department","company" },
        new ADUserAttributesMapper() );

Finally, to get ALL attributes back, ask to retrieve ALL attributes in the code above (my above example only asked for 3 attributes, this would return ALL of them):

        String[] attrs = new String[]{"*","+"};
like image 187
Pierre Avatar answered Oct 02 '22 16:10

Pierre