Reputation: 371
After migrating to Spring security 4.2.2 (from 3.1), I am hitting the following error in LDAP user search:
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)
...
...
I would appreciate any help in resolving the issue. I am using OpenLDAP server for the test if it makes any difference.
Thanks, Raghu
Upvotes: 1
Views: 1796
Reputation: 90
Old question, but I had the same issue and manage to solve it somehow, so I thought I should share.
I'm using Spring Security 4.2.3 and I had something similar:
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);
}
It used to work flawlessly until I had to run it in an @Async thread, then I started to have the same class cast exception. As suggested here the error seems to be due to a different classloader used in the thread. My solution was to force the correct classloader into the execution thread:
public AdvisorResponse getAdvisorInfo(final String uid) {
Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
return cdsLdapTemplate.searchForObject(
createCriteria(uid), this::mapAdvisorResponse
);
}
Upvotes: 4