为什么Spring LDAP的LdapTemplate不能返回标题,部门和公司属性?

问题描述:

我使用spring-ldap-core-2.3.1.RELEASE.jar超过JDK 1.8 & Tomcat 8.0通过LdapTemplate访问AD信息。 title,department & company等属性不会被ldapTemplate.search(..,.,..)方法返回。为什么Spring LDAP的LdapTemplate不能返回标题,部门和公司属性?

我使用下面的代码行搜索: -

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

以下是ADUserAttributesMapper类: -

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; 
    } 
} 

titledepartment & company属性属于组织 AD用户属性选项卡,如下图所示: - enter image description here

此外,从一般标签缩写(initials)属性没有被拾起/列由Spring-LDAP的ldapTemplateLdapQueryBuilder.query()对象有权访问attributes(...)方法,该方法接收要提取的属性名称的字符串数组。但即使在明确提及它们之后,也不会返回属性的值,如initials,title,department & company

在Eclipse IDE中的LDAP浏览器插件列出了组织选项卡下的titledepartment & company性能没有问题。

即使com4j API返回titledepartment & company属性。

是否有限制属性列表的配置,还是Spring-LDAP API本身的限制?这些属性不是BasicAttributes的一部分吗?如何通过Spring-LDAP获取这些属性?

UPDATE(01 - 8月 - 2017年): 平原的Java JNDI方法/代码不会返回departmentcompanytitle属性(即使这些属性在属性字符串数组被明确提及),但令人惊讶它确实返回initials属性值。

UPDATE(02 - 8月 - 2017年): 类似@皮埃尔的建议(下)试图用SearchControls对象下面的代码: -

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; 

即使这样回报initialstitlecompany & department属性值。

这是根据您的AttributesMapper。我不知道ADUserAttributesMapper是什么,所以你必须提供这个实现。

下面是该接口的javadoc。 http://docs.spring.io/spring-ldap/docs/current/apidocs/org/springframework/ldap/core/AttributesMapper.html

+0

嗨瑞安,thanx的回应。这里,'ADUserAttributesMapper'是一个实现'org.springframework.ldap.core.AttributesMapper'接口的类。它将获取的属性映射到Java POJO bean的属性。这是否会限制从LDAP查询搜索返回的属性数量?还有其他的映射器吗? – Shiva

+0

你可以更新你的问题来包含这个实现吗? – ryan2049

人员属性可能是默认情况下不会收回的内部属性。您可以明确指定要返回的属性,但不能使用您正在使用的搜索方法(您在LdapQuery对象中传递的那个方法)。如果您查看org.springframework.ldap.core.LdapTemplate类,看起来您似乎无法将SearchControls对象传递给您正在使用的方法签名。所以,为了能够指定的属性来获取,替换此:

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

有了这个:

 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()); 

以上应该工作。你也可以尝试这样的事情(我还没有试过尚未):

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

最后,要获得所有属性回来,要求取回在上面的代码中的所有属性(我上面的例子中只要求3个属性,这将返回所有人):

 String[] attrs = new String[]{"*","+"}; 
+0

嗨Perre,thanx回应。我尝试了你的建议代码,但是它抛出了'null'指针异常,而'DistinguishedName'类也被弃用了。 – Shiva

+0

请在问题区域查看** UPDATE(2017年8月2日)**。 – Shiva

+0

@Shiva:我试图想出其他的可能性,想到的一点是,也许你正在连接到没有所有这些属性的域控制器(DC)。你能否确认你用来连接LDAP的URL与你的LDAPBrowser截图中的URL一样?如果不是的话,看看那个。否则,我不知道有什么问题,该属性应该真的存在... – Pierre