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