|
[
Permalink
| « Hide
]
Jakub Jozwicki added a comment - 14/May/08 09:26 AM
org.springframework.security.ldap.SpringSecurityLdapTemplate
This sounds like the recurring issue related to AD and LDAP referrals. Could you explain the reasoning behind your proposed changes? i.e. hasMore() can potentially raise an exception (as it does here with AD) - can we justify hiding those exceptions in all possible cases that might arise. Also why have you inserted the try/catch(Exception ) block?
Also, have you tried the various workarounds you can find for issues with AD and referrals?
The workaround is to use 'ou=container,dc=example,dc=com' instead of 'dc=example,dc=com'.
However I've got many organizational units at the root level and I need to search inside all of them. PartialResultException is thrown on accessing domainDNS objects located at the root level. This happens always with W2K3 acting as a ActiveDirectory and DNS server. The only workaround in this case is to use hasMoreElements instead of hasMore. Catching and ignoring PartialResultException causes following results.hasMore() and results.next() to return object already returned in previous step: hasMore, next() -> object1 hasMore -> exception, ignored hasMore -> object1 It is also a solution provided that the code checking for single result looks like this: if (results.hasMoreElements()) { if (!searchResult.equals((SearchResult) results.next())) throw new IncorrectResultSizeDataAccessException(1, 2); } However we might not detect here real incorrect results. --- Maybe there could be some boolean switch for different behavior on AD (to use hasMoreElements instead of hasMore). I'm also not happy with making hacks because of badly written MS software. The try/catch was for debugging purposes and can be deleted. There are other workarounds depending on what the exact error is. Setting java.naming.referral=follow is one, editing the /etc/hosts file on the machine:
http://www.mail-archive.com/cas@tp.its.yale.edu/msg00797.html Spring's LDAP template already has a flag which allows PartialResultExceptions to be ignored, so we might be able to make use of that. With -Djava.naming.referral=follow I still have exception on
'ldap://192.168.1.191:389/dc=ForestDnsZones,dc=pld1,dc=net' domainDNS objectClass: [28812] authentication.LoggerListener Authentication event AuthenticationFailure ServiceExceptionEvent: Jozwicki, Jakub; details: org.springframework.security.ui .WebAuthenticationDetails@fffc7f0c: RemoteIpAddress: 127.0.0.1; SessionId: ybom8 a44alkv; exception: Unprocessed Continuation Reference(s); nested exception is j avax.naming.PartialResultException: Unprocessed Continuation Reference(s); remai ning name 'dc=pld1,dc=net'; nested exception is org.springframework.ldap.Partial ResultException: Unprocessed Continuation Reference(s); nested exception is java x.naming.PartialResultException: Unprocessed Continuation Reference(s); remainin g name 'dc=pld1,dc=net' --- Also code in ldap.core.LdapTemplate is wrong, because while(results.hasMore()) is inside try/catch(PartialResultException), and exception breaks while loop, but it shouldn't. The try/catch(PartialResultException) should be located inside while loop. Like this: public void search(SearchExecutor se, NameClassPairCallbackHandler handler, DirContextProcessor processor) { DirContext ctx = contextSource.getReadOnlyContext(); NamingEnumeration results = null; RuntimeException ex = null; try { processor.preProcess(ctx); results = se.executeSearch(ctx); log.debug("results are="+results); while(true) { try { if (!results.hasMore()) break; NameClassPair result = (NameClassPair) results.next(); log.debug("result="+result); log.debug("result="+result.getName()+", "+result.getClassName()); handler.handleNameClassPair(result); } catch (PartialResultException e) { if (ignorePartialResultException) { log.debug("PartialResultException encountered and ignored: ["+e.getResolvedName()+"] "+ e.getRemainingName()); } else { ex = LdapUtils.convertLdapException(e); } continue; } catch (NullPointerException npe) { break; } } } catch (NameNotFoundException e) { // The base context was not found, which basically means // that the search did not return any results. Just clean up and // exit. // Note that this may present problems if a DirContextProcessor was // supplied - there's no guarantee that the postProcess() operation // will go well after a NamingException has been thrown. It is // however quite possible that information will be available for // retrieval either way. e.printStackTrace(); } catch (javax.naming.NamingException e) { ex = LdapUtils.convertLdapException(e); } finally { try { processor.postProcess(ctx); } catch (javax.naming.NamingException e) { if (ex == null) { ex = LdapUtils.convertLdapException(e); } else { // We already had an exception from above and should ignore // this one. log.debug("Ignoring Exception from postProcess, " + "main exception thrown instead", e); } } closeContextAndNamingEnumeration(ctx, results); // If we got an exception it should be thrown. if (ex != null) { throw ex; } } } Please raise any issues with Spring LDAP in that project or in the Spring LDAP forum.
I've modified the searchForSingleEntry method to ignore a PartialResultException if thrown, in the same way that LdapTemplate does if ignorePartialResultException is set to true. Given your comment in issue
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||