diff --git a/core/src/main/java/org/acegisecurity/providers/ldap/DefaultInitialDirContextFactory.java b/core/src/main/java/org/acegisecurity/providers/ldap/DefaultInitialDirContextFactory.java index 20eebf8908..4fb2e01e6b 100644 --- a/core/src/main/java/org/acegisecurity/providers/ldap/DefaultInitialDirContextFactory.java +++ b/core/src/main/java/org/acegisecurity/providers/ldap/DefaultInitialDirContextFactory.java @@ -24,9 +24,12 @@ import javax.naming.CommunicationException; import javax.naming.directory.InitialDirContext; import javax.naming.directory.DirContext; -import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.util.Assert; +import org.springframework.context.MessageSourceAware; +import org.springframework.context.MessageSource; +import org.springframework.context.support.MessageSourceAccessor; import org.acegisecurity.BadCredentialsException; +import org.acegisecurity.AcegiMessageSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -60,7 +63,8 @@ import org.apache.commons.logging.LogFactory; * @version $Id$ * */ -public class DefaultInitialDirContextFactory implements InitialDirContextFactory { +public class DefaultInitialDirContextFactory implements InitialDirContextFactory, + MessageSourceAware { //~ Static fields/initializers ============================================= @@ -72,6 +76,8 @@ public class DefaultInitialDirContextFactory implements InitialDirContextFactory //~ Instance fields ======================================================== + protected MessageSourceAccessor messages = AcegiMessageSource.getAccessor(); + /** * The LDAP url of the server (and root context) to connect to. * TODO: Allow a backup URL for a replication server. @@ -213,11 +219,17 @@ public class DefaultInitialDirContextFactory implements InitialDirContextFactory return new InitialDirContext(env); } catch(CommunicationException ce) { - throw new DataAccessResourceFailureException("Unable to connect to LDAP Server.", ce); + throw new LdapDataAccessException(messages.getMessage( + "DefaultIntitalDirContextFactory.communicationFailure", + "Unable to connect to LDAP server"), ce); } catch(javax.naming.AuthenticationException ae) { - throw new BadCredentialsException("Authentication to LDAP server failed.", ae); + throw new BadCredentialsException(messages.getMessage( + "DefaultIntitalDirContextFactory.badCredentials", + "Bad credentials"), ae); } catch (NamingException nx) { - throw new LdapDataAccessException("Failed to obtain InitialDirContext", nx); + throw new LdapDataAccessException(messages.getMessage( + "DefaultIntitalDirContextFactory.unexpectedException", + "Failed to obtain InitialDirContext due to unexpected exception"), nx); } } @@ -265,4 +277,8 @@ public class DefaultInitialDirContextFactory implements InitialDirContextFactory Assert.notNull(extraEnvVars, "Extra environment map cannot be null."); this.extraEnvVars = extraEnvVars; } + + public void setMessageSource(MessageSource messageSource) { + this.messages = new MessageSourceAccessor(messageSource); + } } diff --git a/core/src/main/java/org/acegisecurity/providers/ldap/LdapAuthenticationProvider.java b/core/src/main/java/org/acegisecurity/providers/ldap/LdapAuthenticationProvider.java index 7601460c90..c869b45d0f 100644 --- a/core/src/main/java/org/acegisecurity/providers/ldap/LdapAuthenticationProvider.java +++ b/core/src/main/java/org/acegisecurity/providers/ldap/LdapAuthenticationProvider.java @@ -138,10 +138,12 @@ public class LdapAuthenticationProvider extends AbstractUserDetailsAuthenticatio } protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException { - logger.debug("Retrieving user " + username); + if(logger.isDebugEnabled()) { + logger.debug("Retrieving user " + username); + } String password = (String)authentication.getCredentials(); - Assert.notNull(password, "Null password was supplied in authentication token"); + Assert.hasLength(password, "Null or empty password was supplied in authentication token"); LdapUserInfo ldapUser = authenticator.authenticate(username, password); diff --git a/core/src/main/java/org/acegisecurity/providers/ldap/authenticator/AbstractLdapAuthenticator.java b/core/src/main/java/org/acegisecurity/providers/ldap/authenticator/AbstractLdapAuthenticator.java index ef56357ae8..f5d5624dda 100644 --- a/core/src/main/java/org/acegisecurity/providers/ldap/authenticator/AbstractLdapAuthenticator.java +++ b/core/src/main/java/org/acegisecurity/providers/ldap/authenticator/AbstractLdapAuthenticator.java @@ -18,8 +18,12 @@ package org.acegisecurity.providers.ldap.authenticator; import org.acegisecurity.providers.ldap.LdapAuthenticator; import org.acegisecurity.providers.ldap.InitialDirContextFactory; import org.acegisecurity.providers.ldap.LdapUserSearch; +import org.acegisecurity.AcegiMessageSource; import org.springframework.beans.factory.InitializingBean; import org.springframework.util.Assert; +import org.springframework.context.support.MessageSourceAccessor; +import org.springframework.context.MessageSourceAware; +import org.springframework.context.MessageSource; import java.text.MessageFormat; import java.util.List; @@ -32,10 +36,11 @@ import java.util.ArrayList; * @version $Id$ */ public abstract class AbstractLdapAuthenticator implements LdapAuthenticator, - InitializingBean { + InitializingBean, MessageSourceAware { //~ Instance fields ======================================================== + protected MessageSourceAccessor messages = AcegiMessageSource.getAccessor(); private InitialDirContextFactory initialDirContextFactory; //private String[] userDnPattern = null; @@ -139,6 +144,11 @@ public abstract class AbstractLdapAuthenticator implements LdapAuthenticator, return initialDirContextFactory; } + public void setMessageSource(MessageSource messageSource) { + Assert.notNull("Message source must not be null"); + this.messages = new MessageSourceAccessor(messageSource); + } + public void afterPropertiesSet() throws Exception { Assert.isTrue(userDnFormat != null || userSearch != null, "Either an LdapUserSearch or DN pattern (or both) must be supplied."); diff --git a/core/src/main/java/org/acegisecurity/providers/ldap/authenticator/BindAuthenticator.java b/core/src/main/java/org/acegisecurity/providers/ldap/authenticator/BindAuthenticator.java index 253a5728e0..848ffff0e4 100644 --- a/core/src/main/java/org/acegisecurity/providers/ldap/authenticator/BindAuthenticator.java +++ b/core/src/main/java/org/acegisecurity/providers/ldap/authenticator/BindAuthenticator.java @@ -66,7 +66,9 @@ public final class BindAuthenticator extends AbstractLdapAuthenticator { } if(user == null) { - throw new BadCredentialsException("Failed to authenticate as " + username); + throw new BadCredentialsException(messages.getMessage( + "BindAuthenticator.badCredentials", + "Bad credentials")); } return user; @@ -90,11 +92,15 @@ public final class BindAuthenticator extends AbstractLdapAuthenticator { user = new LdapUserInfo(userDn, attributes); } catch(NamingException ne) { - throw new LdapDataAccessException("Failed to load attributes for user " + userDn, ne); + throw new LdapDataAccessException(messages.getMessage( + "BindAuthenticator.failedToLoadAttributes", new String[] {userDn}, + "Failed to load attributes for user {0}"), ne); } catch(BadCredentialsException e) { // This will be thrown if an invalid user name is used and the method may - // be called multiple times to try different names, so we trap the exception. - logger.debug("Failed to bind as " + userDn + ", " + e.getMessage()); + // be called multiple times to try different names, so we trap the exception. + if(logger.isDebugEnabled()) { + logger.debug("Failed to bind as " + userDn + ": " + e.getCause()); + } } finally { LdapUtils.closeContext(ctx); } diff --git a/core/src/main/java/org/acegisecurity/providers/ldap/authenticator/PasswordComparisonAuthenticator.java b/core/src/main/java/org/acegisecurity/providers/ldap/authenticator/PasswordComparisonAuthenticator.java index 03bc93d741..cf64299f05 100644 --- a/core/src/main/java/org/acegisecurity/providers/ldap/authenticator/PasswordComparisonAuthenticator.java +++ b/core/src/main/java/org/acegisecurity/providers/ldap/authenticator/PasswordComparisonAuthenticator.java @@ -110,7 +110,9 @@ public final class PasswordComparisonAuthenticator extends AbstractLdapAuthentic } if(!verifyPassword(password, (String)retrievedPassword)) { - throw new BadCredentialsException("Invalid password."); + throw new BadCredentialsException(messages.getMessage( + "PasswordComparisonAuthenticator.badCredentials", + "Bad credentials")); } } else { @@ -161,7 +163,9 @@ public final class PasswordComparisonAuthenticator extends AbstractLdapAuthentic new Object[]{passwordBytes}, ctls); if(!results.hasMore()) { - throw new BadCredentialsException("Password comparison failed"); + throw new BadCredentialsException(messages.getMessage( + "PasswordComparisonAuthenticator.badCredentials", + "Bad credentials")); } } @@ -172,7 +176,7 @@ public final class PasswordComparisonAuthenticator extends AbstractLdapAuthentic } public void setPasswordEncoder(PasswordEncoder passwordEncoder) { - Assert.notNull(passwordEncoder, "Password Encoder must not be null."); + Assert.notNull(passwordEncoder, "passwordEncoder must not be null."); this.passwordEncoder = passwordEncoder; } } diff --git a/core/src/main/java/org/acegisecurity/providers/ldap/authenticator/package.html b/core/src/main/java/org/acegisecurity/providers/ldap/authenticator/package.html new file mode 100644 index 0000000000..c97c3889a0 --- /dev/null +++ b/core/src/main/java/org/acegisecurity/providers/ldap/authenticator/package.html @@ -0,0 +1,5 @@ + + +LDAP authenticator implementations. + + diff --git a/core/src/main/resources/org/acegisecurity/messages.properties b/core/src/main/resources/org/acegisecurity/messages.properties index 7b70e0c659..921247d52d 100644 --- a/core/src/main/resources/org/acegisecurity/messages.properties +++ b/core/src/main/resources/org/acegisecurity/messages.properties @@ -37,3 +37,9 @@ SwitchUserProcessingFilter.disabled=User is disabled SwitchUserProcessingFilter.expired=User account has expired SwitchUserProcessingFilter.credentialsExpired=User credentials have expired AbstractAccessDecisionManager.accessDenied=Access is denied +DefaultIntitalDirContextFactory.communicationFailure=Unable to connect to LDAP server +DefaultIntitalDirContextFactory.badCredentials=Bad credentials +DefaultIntitalDirContextFactory.unexpectedException=Failed to obtain InitialDirContext due to unexpected exception +PasswordComparisonAuthenticator.badCredentials=Bad credentials +BindAuthenticator.badCredentials=Bad credentials +BindAuthenticator.failedToLoadAttributes=Bad credentials