搜索LDAP用户

时间:2017-08-17 18:31:57

标签: spring-security spring-ldap

迁移到Spring security 4.2.2(从3.1开始)后,我在LDAP用户搜索中遇到以下错误:

java.lang.ClassCastException: com.sun.jndi.ldap.LdapCtx cannot be cast to org.springframework.ldap.core.DirContextAdapter
  at org.springframework.security.ldap.SpringSecurityLdapTemplate.searchForSingleEntryInternal(SpringSecurityLdapTemplate.java:345)
  at org.springframework.security.ldap.SpringSecurityLdapTemplate$3.executeWithContext(SpringSecurityLdapTemplate.java:318)
  at org.springframework.ldap.core.LdapTemplate.executeWithContext(LdapTemplate.java:817)
  at org.springframework.ldap.core.LdapTemplate.executeReadOnly(LdapTemplate.java:803)
  at org.springframework.security.ldap.SpringSecurityLdapTemplate.searchForSingleEntry(SpringSecurityLdapTemplate.java:316)
  at org.springframework.security.ldap.search.FilterBasedLdapUserSearch.searchForUser(FilterBasedLdapUserSearch.java:127)
  ...
  ...

感谢您解决问题的任何帮助。如果它有任何不同,我正在使用OpenLDAP服务器进行测试。

谢谢, Raghu

1 个答案:

答案 0 :(得分:0)

旧问题,但我遇到了同样的问题,并设法以某种方式解决了这个问题,所以我认为应该分享。

我正在使用Spring Security 4.2.3,并且有类似的东西:

public AdvisorResponse getAdvisorInfo(final String uid) {
    return cdsLdapTemplate.searchForObject(
            createCriteria(uid), this::mapAdvisorResponse
    );
}

private AdvisorResponse mapAdvisorResponse(final Object ctx) {
    final DirContextAdapter context = (DirContextAdapter) ctx;
    final AdvisorResponse advisor = new AdvisorResponse();
    advisor.setUid(context.getStringAttribute("uid"));
    return advisor;
}

private ContainerCriteria createCriteria(final String uid) {
    return query()
            .base("ou=people")
            .countLimit(1)
            .searchScope(SUBTREE)
            .timeLimit(TIMEOUT)
            .where("uid").is(uid);
}

它曾经可以完美地工作,直到必须在@Async线程中运行它,然后才开始具有相同的类强制转换异常。 如建议here所示,该错误似乎是由于线程中使用了不同的类加载器引起的。我的解决方案是将正确的类加载器强制进入执行线程:

public AdvisorResponse getAdvisorInfo(final String uid) {
    Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());

    return cdsLdapTemplate.searchForObject(
            createCriteria(uid), this::mapAdvisorResponse
    );
}