diff --git a/changelog.txt b/changelog.txt
index 2f98f29ad2..793cf542d3 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -3,6 +3,7 @@ Changes in version 0.x (2004-xx-xx)
* Added additional DaoAuthenticationProvider event when user not found
* Added Authentication.getDetails() to DaoAuthenticationProvider response
+* Added DaoAuthenticationProvider.hideUserNotFoundExceptions (default=true)
* Extracted removeUserFromCache(String) to UserCache interface
* Improved ConfigAttributeEditor so it trims preceding and trailing spaces
* Fixed EH-CACHE-based caching implementation behaviour when cache exists
diff --git a/core/src/main/java/org/acegisecurity/providers/dao/DaoAuthenticationProvider.java b/core/src/main/java/org/acegisecurity/providers/dao/DaoAuthenticationProvider.java
index 0638fc3514..83e460cc5f 100644
--- a/core/src/main/java/org/acegisecurity/providers/dao/DaoAuthenticationProvider.java
+++ b/core/src/main/java/org/acegisecurity/providers/dao/DaoAuthenticationProvider.java
@@ -98,6 +98,7 @@ public class DaoAuthenticationProvider implements AuthenticationProvider,
private SaltSource saltSource;
private UserCache userCache = new NullUserCache();
private boolean forcePrincipalAsString = false;
+ private boolean hideUserNotFoundExceptions = true;
//~ Methods ================================================================
@@ -126,6 +127,28 @@ public class DaoAuthenticationProvider implements AuthenticationProvider,
return forcePrincipalAsString;
}
+ /**
+ * By default the DaoAuthenticationProvider
throws a
+ * BadCredentialsException
if a username is not found or the
+ * password is incorrect. Setting this property to false
will
+ * cause UsernameNotFoundException
s to be thrown instead for
+ * the former. Note this is considered less secure than throwing
+ * BadCredentialsException
for both events.
+ *
+ * @param hideUserNotFoundExceptions set to false
if you wish
+ * UsernameNotFoundException
s to be thrown instead of
+ * the non-specific BadCredentialsException
(defaults
+ * to true
)
+ */
+ public void setHideUserNotFoundExceptions(
+ boolean hideUserNotFoundExceptions) {
+ this.hideUserNotFoundExceptions = hideUserNotFoundExceptions;
+ }
+
+ public boolean isHideUserNotFoundExceptions() {
+ return hideUserNotFoundExceptions;
+ }
+
/**
* Sets the PasswordEncoder instance to be used to encode and validate
* passwords. If not set, {@link PlaintextPasswordEncoder} will be used by
@@ -335,7 +358,11 @@ public class DaoAuthenticationProvider implements AuthenticationProvider,
try {
return this.authenticationDao.loadUserByUsername(username);
} catch (UsernameNotFoundException notFound) {
- throw new BadCredentialsException("Bad credentials presented");
+ if (hideUserNotFoundExceptions) {
+ throw new BadCredentialsException("Bad credentials presented");
+ } else {
+ throw notFound;
+ }
} catch (DataAccessException repositoryProblem) {
throw new AuthenticationServiceException(repositoryProblem
.getMessage(), repositoryProblem);
diff --git a/core/src/main/java/org/acegisecurity/providers/dao/UsernameNotFoundException.java b/core/src/main/java/org/acegisecurity/providers/dao/UsernameNotFoundException.java
index 31f441508f..a0362a621f 100644
--- a/core/src/main/java/org/acegisecurity/providers/dao/UsernameNotFoundException.java
+++ b/core/src/main/java/org/acegisecurity/providers/dao/UsernameNotFoundException.java
@@ -15,7 +15,7 @@
package net.sf.acegisecurity.providers.dao;
-import net.sf.acegisecurity.AuthenticationException;
+import net.sf.acegisecurity.BadCredentialsException;
/**
@@ -25,7 +25,7 @@ import net.sf.acegisecurity.AuthenticationException;
* @author Ben Alex
* @version $Id$
*/
-public class UsernameNotFoundException extends AuthenticationException {
+public class UsernameNotFoundException extends BadCredentialsException {
//~ Constructors ===========================================================
/**
diff --git a/core/src/test/java/org/acegisecurity/providers/dao/DaoAuthenticationProviderTests.java b/core/src/test/java/org/acegisecurity/providers/dao/DaoAuthenticationProviderTests.java
index 186e8cffe9..e57338397f 100644
--- a/core/src/test/java/org/acegisecurity/providers/dao/DaoAuthenticationProviderTests.java
+++ b/core/src/test/java/org/acegisecurity/providers/dao/DaoAuthenticationProviderTests.java
@@ -119,11 +119,29 @@ public class DaoAuthenticationProviderTests extends TestCase {
}
}
- public void testAuthenticateFailsWithInvalidUsername() {
+ public void testAuthenticateFailsWithInvalidUsernameAndHideUserNotFoundExceptionFalse() {
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("INVALID_USER",
"koala");
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
+ provider.setHideUserNotFoundExceptions(false); // we want UsernameNotFoundExceptions
+ provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa());
+ provider.setUserCache(new MockUserCache());
+
+ try {
+ provider.authenticate(token);
+ fail("Should have thrown UsernameNotFoundException");
+ } catch (UsernameNotFoundException expected) {
+ assertTrue(true);
+ }
+ }
+
+ public void testAuthenticateFailsWithInvalidUsernameAndHideUserNotFoundExceptionsWithDefaultOfTrue() {
+ UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("INVALID_USER",
+ "koala");
+
+ DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
+ assertTrue(provider.isHideUserNotFoundExceptions());
provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa());
provider.setUserCache(new MockUserCache());