diff --git a/changelog.txt b/changelog.txt index c084ece3..cb58de30 100644 --- a/changelog.txt +++ b/changelog.txt @@ -34,6 +34,12 @@ Changes in version 1.3.1 (October 2010) * Added authentication methods that provide a possible authentication exception through an AuthenticationErrorCallback. (LDAP-192) +* Authentication methods now treat a search result of more than one user as + an error and throw IncorrectResultSizeDataAccessException. (LDAP-170) + +* Authentication methods now log problems at level INFO rather than ERROR. + (LDAP-170) + * DefaultDirObjectFactory calls a Java5 version of the IllegalArgumentException constructor. (LDAP 196). diff --git a/core/src/main/java/org/springframework/ldap/core/LdapOperations.java b/core/src/main/java/org/springframework/ldap/core/LdapOperations.java index 5cac046a..2c9ae7d0 100644 --- a/core/src/main/java/org/springframework/ldap/core/LdapOperations.java +++ b/core/src/main/java/org/springframework/ldap/core/LdapOperations.java @@ -1482,6 +1482,7 @@ public interface LdapOperations { * @param errorCallback the callback that will be called if an exception is caught. * @return true if the authentication was successful, * false otherwise. + * @throws IncorrectResultSizeDataAccessException if more than one users were found * @see #authenticate(String, String, String, AuthenticatedLdapEntryContextCallback, AuthenticationErrorCallback) * @since 1.3.1 */ diff --git a/core/src/main/java/org/springframework/ldap/core/LdapTemplate.java b/core/src/main/java/org/springframework/ldap/core/LdapTemplate.java index 586ff145..00e48310 100644 --- a/core/src/main/java/org/springframework/ldap/core/LdapTemplate.java +++ b/core/src/main/java/org/springframework/ldap/core/LdapTemplate.java @@ -1480,10 +1480,13 @@ public class LdapTemplate implements LdapOperations, InitializingBean { final AuthenticatedLdapEntryContextCallback callback, final AuthenticationErrorCallback errorCallback) { List result = search(base, filter, new LdapEntryIdentificationContextMapper()); - if (result.size() != 1) { - log.error("Unable to find unique entry matching in authentication; base: '" + base + "'; filter: '" - + filter + "'. Found " + result.size() + " matching entries"); + if (result.size() == 0) { + String msg = "No results found for search, base: '" + base + "'; filter: '" + filter + "'."; + log.info(msg); return false; + } else if (result.size() > 1) { + String msg = "base: '" + base + "'; filter: '" + filter + "'."; + throw new IncorrectResultSizeDataAccessException(msg, 1, result.size()); } final LdapEntryIdentification entryIdentification = (LdapEntryIdentification) result.get(0); @@ -1499,7 +1502,7 @@ public class LdapTemplate implements LdapOperations, InitializingBean { return true; } catch (Exception e) { - log.error("Authentication failed for entry with DN '" + entryIdentification.getAbsoluteDn() + "'", e); + log.info("Authentication failed for entry with DN '" + entryIdentification.getAbsoluteDn() + "'", e); errorCallback.execute(e); return false; } diff --git a/test/integration-tests/src/test/java/org/springframework/ldap/LdapTemplateAuthenticationITest.java b/test/integration-tests/src/test/java/org/springframework/ldap/LdapTemplateAuthenticationITest.java index 78ba3dfe..3d3e4f9b 100644 --- a/test/integration-tests/src/test/java/org/springframework/ldap/LdapTemplateAuthenticationITest.java +++ b/test/integration-tests/src/test/java/org/springframework/ldap/LdapTemplateAuthenticationITest.java @@ -26,6 +26,7 @@ import javax.naming.directory.DirContext; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.IncorrectResultSizeDataAccessException; import org.springframework.ldap.core.AuthenticatedLdapEntryContextCallback; import org.springframework.ldap.core.DirContextAdapter; import org.springframework.ldap.core.LdapEntryIdentification; @@ -101,13 +102,13 @@ public class LdapTemplateAuthenticationITest extends AbstractLdapTemplateIntegra assertFalse(tested.authenticate("", filter.toString(), "password")); } - @Test + @Test(expected=IncorrectResultSizeDataAccessException.class) public void testAuthenticateWithFilterThatMatchesSeveralEntries() { AndFilter filter = new AndFilter(); - filter.and(new EqualsFilter("objectclass", "person")).and(new WhitespaceWildcardsFilter("uid", "some.person")); - assertFalse(tested.authenticate("", filter.toString(), "password")); + filter.and(new EqualsFilter("objectclass", "person")).and(new EqualsFilter("cn", "Some Person")); + tested.authenticate("", filter.toString(), "password"); } - + @Test public void testLookupAttemptingCallback() { AndFilter filter = new AndFilter();