From e9b1d9452f3c80b94538ab15c5c824760346ed6f Mon Sep 17 00:00:00 2001 From: Ben Alex Date: Thu, 3 Nov 2005 11:31:23 +0000 Subject: [PATCH] SEC-9 and SEC-55: Refactor DaoAuthenticationProvider and deprecate PasswordDaoAuthenticationProvider. --- ...ractUserDetailsAuthenticationProvider.java | 280 ++++++++++++++++++ .../dao/DaoAuthenticationProvider.java | 209 +------------ .../ldap/LdapPasswordAuthenticationDao.java | 1 - .../dao/ldap}/PasswordAuthenticationDao.java | 5 +- .../PasswordDaoAuthenticationProvider.java | 5 +- .../LdapPassword2AuthenticationDao.java | 2 +- ...asswordDaoAuthenticationProviderTests.java | 12 +- 7 files changed, 310 insertions(+), 204 deletions(-) create mode 100644 core/src/main/java/org/acegisecurity/providers/dao/AbstractUserDetailsAuthenticationProvider.java rename {core/src/main/java/org/acegisecurity/providers/dao => sandbox/src/main/java/org/acegisecurity/providers/dao/ldap}/PasswordAuthenticationDao.java (94%) rename {core/src/main/java/org/acegisecurity/providers/dao => sandbox/src/main/java/org/acegisecurity/providers/dao/ldap}/PasswordDaoAuthenticationProvider.java (96%) rename {core/src/test/java/org/acegisecurity/providers/dao => sandbox/src/test/java/org/acegisecurity/providers/dao/ldap}/PasswordDaoAuthenticationProviderTests.java (98%) diff --git a/core/src/main/java/org/acegisecurity/providers/dao/AbstractUserDetailsAuthenticationProvider.java b/core/src/main/java/org/acegisecurity/providers/dao/AbstractUserDetailsAuthenticationProvider.java new file mode 100644 index 0000000000..8153fc80fc --- /dev/null +++ b/core/src/main/java/org/acegisecurity/providers/dao/AbstractUserDetailsAuthenticationProvider.java @@ -0,0 +1,280 @@ +/* Copyright 2004, 2005 Acegi Technology Pty Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.sf.acegisecurity.providers.dao; + +import net.sf.acegisecurity.AccountExpiredException; +import net.sf.acegisecurity.Authentication; +import net.sf.acegisecurity.AuthenticationException; +import net.sf.acegisecurity.CredentialsExpiredException; +import net.sf.acegisecurity.DisabledException; +import net.sf.acegisecurity.LockedException; +import net.sf.acegisecurity.UserDetails; +import net.sf.acegisecurity.providers.AuthenticationProvider; +import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken; +import net.sf.acegisecurity.providers.dao.cache.NullUserCache; + +import org.springframework.beans.factory.InitializingBean; + +import org.springframework.util.Assert; + + +/** + * A base {@link AuthenticationProvider} that allows subclasses to override and + * work with {@link net.sf.acegisecurity.UserDetails} objects. The class is + * designed to respond to {@link UsernamePasswordAuthenticationToken} + * authentication requests. + * + *

+ * Upon successful validation, a + * UsernamePasswordAuthenticationToken will be created and + * returned to the caller. The token will include as its principal either a + * String representation of the username, or the {@link + * UserDetails} that was returned from the authentication repository. Using + * String is appropriate if a container adapter is being used, as + * it expects String representations of the username. Using + * UserDetails is appropriate if you require access to additional + * properties of the authenticated user, such as email addresses, + * human-friendly names etc. As container adapters are not recommended to be + * used, and UserDetails implementations provide additional + * flexibility, by default a UserDetails is returned. To override + * this default, set the {@link #setForcePrincipalAsString} to + * true. + *

+ * + *

+ * Caching is handled via the UserDetails object being placed in + * the {@link UserCache}. This ensures that subsequent requests with the same + * username can be validated without needing to query the {@link + * AuthenticationDao}. It should be noted that if a user appears to present an + * incorrect password, the {@link AuthenticationDao} will be queried to + * confirm the most up-to-date password was used for comparison. + *

+ * + * @author Ben Alex + * @version $Id$ + */ +public abstract class AbstractUserDetailsAuthenticationProvider + implements AuthenticationProvider, InitializingBean { + //~ Instance fields ======================================================== + + private UserCache userCache = new NullUserCache(); + private boolean forcePrincipalAsString = false; + + //~ Methods ================================================================ + + public void setForcePrincipalAsString(boolean forcePrincipalAsString) { + this.forcePrincipalAsString = forcePrincipalAsString; + } + + public boolean isForcePrincipalAsString() { + return forcePrincipalAsString; + } + + public void setUserCache(UserCache userCache) { + this.userCache = userCache; + } + + public UserCache getUserCache() { + return userCache; + } + + public final void afterPropertiesSet() throws Exception { + Assert.notNull(this.userCache, "A user cache must be set"); + doAfterPropertiesSet(); + } + + public Authentication authenticate(Authentication authentication) + throws AuthenticationException { + Assert.isInstanceOf(UsernamePasswordAuthenticationToken.class, + authentication, + "Only UsernamePasswordAuthenticationToken is supported"); + + // Determine username + String username = (authentication.getPrincipal() == null) + ? "NONE_PROVIDED" : authentication.getName(); + + boolean cacheWasUsed = true; + UserDetails user = this.userCache.getUserFromCache(username); + + if (user == null) { + cacheWasUsed = false; + user = retrieveUser(username, + (UsernamePasswordAuthenticationToken) authentication); + Assert.notNull(user, + "retrieveUser returned null - a violation of the interface contract"); + } + + if (!user.isAccountNonLocked()) { + throw new LockedException("User account is locked"); + } + + if (!user.isEnabled()) { + throw new DisabledException("User is disabled"); + } + + if (!user.isAccountNonExpired()) { + throw new AccountExpiredException("User account has expired"); + } + + // This check must come here, as we don't want to tell users + // about account status unless they presented the correct credentials + try { + additionalAuthenticationChecks(user, + (UsernamePasswordAuthenticationToken) authentication); + } catch (AuthenticationException exception) { + // There was a problem, so try again after checking we're using latest data + cacheWasUsed = false; + user = retrieveUser(username, + (UsernamePasswordAuthenticationToken) authentication); + additionalAuthenticationChecks(user, + (UsernamePasswordAuthenticationToken) authentication); + } + + if (!user.isCredentialsNonExpired()) { + throw new CredentialsExpiredException( + "User credentials have expired"); + } + + if (!cacheWasUsed) { + this.userCache.putUserInCache(user); + } + + Object principalToReturn = user; + + if (forcePrincipalAsString) { + principalToReturn = user.getUsername(); + } + + return createSuccessAuthentication(principalToReturn, authentication, + user); + } + + public boolean supports(Class authentication) { + return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication)); + } + + /** + * Allows subclasses to perform any additional checks of a returned (or + * cached) UserDetails for a given authentication request. + * Generally a subclass will at least compare the {@link + * Authentication#getCredentials()} with a {@link + * UserDetails#getPassword()}. If custom logic is needed to compare + * additional properties of UserDetails and/or + * UsernamePasswordAuthenticationToken, these should also + * appear in this method. + * + * @param userDetails as retrieved from the {@link #retrieveUser(String, + * UsernamePasswordAuthenticationToken)} or UserCache + * @param authentication the current request that needs to be authenticated + * + * @throws AuthenticationException AuthenticationException if the + * credentials could not be validated (generally a + * BadCredentialsException, an + * AuthenticationServiceException) + */ + protected abstract void additionalAuthenticationChecks( + UserDetails userDetails, + UsernamePasswordAuthenticationToken authentication) + throws AuthenticationException; + + protected void doAfterPropertiesSet() throws Exception {} + + /** + * Allows subclasses to actually retrieve the UserDetails from + * an implementation-specific location, with the option of throwing an + * AuthenticationException immediately if the presented + * credentials are incorrect (this is especially useful if it is necessary + * to bind to a resource as the user in order to obtain or generate a + * UserDetails). + * + *

+ * Subclasses are not required to perform any caching, as the + * AbstractUserDetailsAuthenticationProvider will by default + * cache the UserDetails. The caching of + * UserDetails does present additional complexity as this + * means subsequent requests that rely on the cache will need to still + * have their credentials validated, even if the correctness of + * credentials was assured by subclasses adopting a binding-based strategy + * in this method. Accordingly it is important that subclasses either + * disable caching (if they want to ensure that this method is the only + * method that is capable of authenticating a request, as no + * UserDetails will ever be cached) or ensure subclasses + * implement {@link #additionalAuthenticationChecks(UserDetails, + * UsernamePasswordAuthenticationToken)} to compare the credentials of a + * cached UserDetails with subsequent authentication + * requests. + *

+ * + *

+ * Most of the time subclasses will not perform credentials inspection in + * this method, instead performing it in {@link + * #additionalAuthenticationChecks(UserDetails, + * UsernamePasswordAuthenticationToken)} so that code related to + * credentials validation need not be duplicated across two methods. + *

+ * + * @param username The username to retrieve + * @param authentication The authentication request, which subclasses + * may need to perform a binding-based retrieval of the + * UserDetails + * + * @return the user information (never null - instead an + * exception should the thrown) + * + * @throws AuthenticationException if the credentials could not be + * validated (generally a BadCredentialsException, an + * AuthenticationServiceException or + * UserNotFoundException) + */ + protected abstract UserDetails retrieveUser(String username, + UsernamePasswordAuthenticationToken authentication) + throws AuthenticationException; + + /** + * Creates a successful {@link Authentication} object. + * + *

+ * Protected so subclasses can override. + *

+ * + *

+ * Subclasses will usually store the original credentials the user supplied + * (not salted or encoded passwords) in the returned + * Authentication object. + *

+ * + * @param principal that should be the principal in the returned object + * (defined by the {@link #isForcePrincipalAsString()} method) + * @param authentication that was presented to the + * DaoAuthenticationProvider for validation + * @param user that was loaded by the AuthenticationDao + * + * @return the successful authentication token + */ + protected Authentication createSuccessAuthentication(Object principal, + Authentication authentication, UserDetails user) { + // Ensure we return the original credentials the user supplied, + // so subsequent attempts are successful even with encoded passwords. + // Also ensure we return the original getDetails(), so that future + // authentication events after cache expiry contain the details + UsernamePasswordAuthenticationToken result = new UsernamePasswordAuthenticationToken(principal, + authentication.getCredentials(), user.getAuthorities()); + result.setDetails((authentication.getDetails() != null) + ? authentication.getDetails() : null); + + return result; + } +} 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 a3b503f06d..132d5b3885 100644 --- a/core/src/main/java/org/acegisecurity/providers/dao/DaoAuthenticationProvider.java +++ b/core/src/main/java/org/acegisecurity/providers/dao/DaoAuthenticationProvider.java @@ -15,23 +15,15 @@ package net.sf.acegisecurity.providers.dao; -import net.sf.acegisecurity.AccountExpiredException; -import net.sf.acegisecurity.Authentication; import net.sf.acegisecurity.AuthenticationException; import net.sf.acegisecurity.AuthenticationServiceException; import net.sf.acegisecurity.BadCredentialsException; -import net.sf.acegisecurity.CredentialsExpiredException; -import net.sf.acegisecurity.DisabledException; -import net.sf.acegisecurity.LockedException; import net.sf.acegisecurity.UserDetails; import net.sf.acegisecurity.providers.AuthenticationProvider; import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken; -import net.sf.acegisecurity.providers.dao.cache.NullUserCache; import net.sf.acegisecurity.providers.encoding.PasswordEncoder; import net.sf.acegisecurity.providers.encoding.PlaintextPasswordEncoder; -import org.springframework.beans.factory.InitializingBean; - import org.springframework.dao.DataAccessException; import org.springframework.util.Assert; @@ -40,51 +32,17 @@ import org.springframework.util.Assert; /** * An {@link AuthenticationProvider} implementation that retrieves user details * from an {@link AuthenticationDao}. - * - *

- * This AuthenticationProvider is capable of validating {@link - * UsernamePasswordAuthenticationToken} requests contain the correct username, - * password and the user is not disabled. - *

- * - *

- * Upon successful validation, a - * UsernamePasswordAuthenticationToken will be created and - * returned to the caller. The token will include as its principal either a - * String representation of the username, or the {@link - * UserDetails} that was returned from the authentication repository. Using - * String is appropriate if a container adapter is being used, as - * it expects String representations of the username. Using - * UserDetails is appropriate if you require access to additional - * properties of the authenticated user, such as email addresses, - * human-friendly names etc. As container adapters are not recommended to be - * used, and UserDetails implementations provide additional - * flexibility, by default a UserDetails is returned. To override - * this default, set the {@link #setForcePrincipalAsString} to - * true. - *

- * - *

- * Caching is handled via the UserDetails object being placed in - * the {@link UserCache}. This ensures that subsequent requests with the same - * username can be validated without needing to query the {@link - * AuthenticationDao}. It should be noted that if a user appears to present an - * incorrect password, the {@link AuthenticationDao} will be queried to - * confirm the most up-to-date password was used for comparison. - *

* * @author Ben Alex * @version $Id$ */ -public class DaoAuthenticationProvider implements AuthenticationProvider, - InitializingBean { +public class DaoAuthenticationProvider + extends AbstractUserDetailsAuthenticationProvider { //~ Instance fields ======================================================== private AuthenticationDao authenticationDao; private PasswordEncoder passwordEncoder = new PlaintextPasswordEncoder(); private SaltSource saltSource; - private UserCache userCache = new NullUserCache(); - private boolean forcePrincipalAsString = false; private boolean hideUserNotFoundExceptions = true; //~ Methods ================================================================ @@ -97,14 +55,6 @@ public class DaoAuthenticationProvider implements AuthenticationProvider, return authenticationDao; } - public void setForcePrincipalAsString(boolean forcePrincipalAsString) { - this.forcePrincipalAsString = forcePrincipalAsString; - } - - public boolean isForcePrincipalAsString() { - return forcePrincipalAsString; - } - /** * By default the DaoAuthenticationProvider throws a * BadCredentialsException if a username is not found or the @@ -159,158 +109,29 @@ public class DaoAuthenticationProvider implements AuthenticationProvider, return saltSource; } - public void setUserCache(UserCache userCache) { - this.userCache = userCache; - } - - public UserCache getUserCache() { - return userCache; - } - - public void afterPropertiesSet() throws Exception { - Assert.notNull(this.authenticationDao, - "An Authentication DAO must be set"); - Assert.notNull(this.userCache, "A user cache must be set"); - } - - public Authentication authenticate(Authentication authentication) + protected void additionalAuthenticationChecks(UserDetails userDetails, + UsernamePasswordAuthenticationToken authentication) throws AuthenticationException { - // Determine username - String username = "NONE_PROVIDED"; - - if (authentication.getPrincipal() != null) { - username = authentication.getPrincipal().toString(); - } - - if (authentication.getPrincipal() instanceof UserDetails) { - username = ((UserDetails) authentication.getPrincipal()) - .getUsername(); - } - - boolean cacheWasUsed = true; - UserDetails user = this.userCache.getUserFromCache(username); - - if (user == null) { - cacheWasUsed = false; - user = getUserFromBackend(username); - } - - if (!user.isAccountNonLocked()) { - throw new LockedException("User account is locked"); - } - - if (!isPasswordCorrect(authentication, user)) { - // Password incorrect, so ensure we're using most current password - if (cacheWasUsed) { - cacheWasUsed = false; - user = getUserFromBackend(username); - } - - if (!isPasswordCorrect(authentication, user)) { - throw new BadCredentialsException("Bad credentials presented"); - } - } - - if (!user.isEnabled()) { - throw new DisabledException("User is disabled"); - } - - if (!user.isAccountNonExpired()) { - throw new AccountExpiredException("User account has expired"); - } - - if (!user.isCredentialsNonExpired()) { - throw new CredentialsExpiredException( - "User credentials have expired"); - } - - if (!cacheWasUsed) { - // Put into cache - this.userCache.putUserInCache(user); - } - - Object principalToReturn = user; - - if (forcePrincipalAsString) { - principalToReturn = user.getUsername(); - } - - return createSuccessAuthentication(principalToReturn, authentication, - user); - } - - public boolean supports(Class authentication) { - if (UsernamePasswordAuthenticationToken.class.isAssignableFrom( - authentication)) { - return true; - } else { - return false; - } - } - - /** - * Indicates whether the supplied Authentication object - * provided appropriate credentials. This method can be called several - * times throughout a single authentication request. - * - *

- * Protected so subclasses can override. - *

- * - * @param authentication that was presented to the - * DaoAuthenticationProvider for validation - * @param user that was loaded by the AuthenticationDao - * - * @return a boolean indicating whether the credentials were correct - */ - protected boolean isPasswordCorrect(Authentication authentication, - UserDetails user) { Object salt = null; if (this.saltSource != null) { - salt = this.saltSource.getSalt(user); + salt = this.saltSource.getSalt(userDetails); } - return passwordEncoder.isPasswordValid(user.getPassword(), - authentication.getCredentials().toString(), salt); + if (!passwordEncoder.isPasswordValid(userDetails.getPassword(), + authentication.getCredentials().toString(), salt)) { + throw new BadCredentialsException("Bad credentials"); + } } - /** - * Creates a successful {@link Authentication} object. - * - *

- * Protected so subclasses can override. - *

- * - *

- * Subclasses will usually store the original credentials the user supplied - * (not salted or encoded passwords) in the returned - * Authentication object. - *

- * - * @param principal that should be the principal in the returned object - * (defined by the {@link #isForcePrincipalAsString()} method) - * @param authentication that was presented to the - * DaoAuthenticationProvider for validation - * @param user that was loaded by the AuthenticationDao - * - * @return the successful authentication token - */ - protected Authentication createSuccessAuthentication(Object principal, - Authentication authentication, UserDetails user) { - // Ensure we return the original credentials the user supplied, - // so subsequent attempts are successful even with encoded passwords. - // Also ensure we return the original getDetails(), so that future - // authentication events after cache expiry contain the details - UsernamePasswordAuthenticationToken result = new UsernamePasswordAuthenticationToken(principal, - authentication.getCredentials(), user.getAuthorities()); - result.setDetails((authentication.getDetails() != null) - ? authentication.getDetails() : null); - - return result; + protected void doAfterPropertiesSet() throws Exception { + Assert.notNull(this.authenticationDao, + "An Authentication DAO must be set"); } - private UserDetails getUserFromBackend(String username) { + protected final UserDetails retrieveUser(String username, + UsernamePasswordAuthenticationToken authentication) + throws AuthenticationException { UserDetails loadedUser; try { diff --git a/sandbox/src/main/java/org/acegisecurity/providers/dao/ldap/LdapPasswordAuthenticationDao.java b/sandbox/src/main/java/org/acegisecurity/providers/dao/ldap/LdapPasswordAuthenticationDao.java index 2b13fe20a2..739f7a5b24 100644 --- a/sandbox/src/main/java/org/acegisecurity/providers/dao/ldap/LdapPasswordAuthenticationDao.java +++ b/sandbox/src/main/java/org/acegisecurity/providers/dao/ldap/LdapPasswordAuthenticationDao.java @@ -24,7 +24,6 @@ import net.sf.acegisecurity.BadCredentialsException; import net.sf.acegisecurity.GrantedAuthority; import net.sf.acegisecurity.GrantedAuthorityImpl; import net.sf.acegisecurity.UserDetails; -import net.sf.acegisecurity.providers.dao.PasswordAuthenticationDao; import net.sf.acegisecurity.providers.dao.User; /** diff --git a/core/src/main/java/org/acegisecurity/providers/dao/PasswordAuthenticationDao.java b/sandbox/src/main/java/org/acegisecurity/providers/dao/ldap/PasswordAuthenticationDao.java similarity index 94% rename from core/src/main/java/org/acegisecurity/providers/dao/PasswordAuthenticationDao.java rename to sandbox/src/main/java/org/acegisecurity/providers/dao/ldap/PasswordAuthenticationDao.java index fc56936873..11f802dbef 100644 --- a/core/src/main/java/org/acegisecurity/providers/dao/PasswordAuthenticationDao.java +++ b/sandbox/src/main/java/org/acegisecurity/providers/dao/ldap/PasswordAuthenticationDao.java @@ -13,7 +13,7 @@ * limitations under the License. */ -package net.sf.acegisecurity.providers.dao; +package net.sf.acegisecurity.providers.dao.ldap; import net.sf.acegisecurity.BadCredentialsException; import net.sf.acegisecurity.UserDetails; @@ -33,7 +33,8 @@ import org.springframework.dao.DataAccessException; * The interface requires only one read-only method, which simplifies support * of new data access strategies. *

- * + * + * @deprecated instead subclass {@link net.sf.acegisecurity.providers.dao.AbstractUserDetailsAuthenticationProvider} * @author Karel Miarka */ public interface PasswordAuthenticationDao { diff --git a/core/src/main/java/org/acegisecurity/providers/dao/PasswordDaoAuthenticationProvider.java b/sandbox/src/main/java/org/acegisecurity/providers/dao/ldap/PasswordDaoAuthenticationProvider.java similarity index 96% rename from core/src/main/java/org/acegisecurity/providers/dao/PasswordDaoAuthenticationProvider.java rename to sandbox/src/main/java/org/acegisecurity/providers/dao/ldap/PasswordDaoAuthenticationProvider.java index 06ef995793..86158d0c76 100644 --- a/core/src/main/java/org/acegisecurity/providers/dao/PasswordDaoAuthenticationProvider.java +++ b/sandbox/src/main/java/org/acegisecurity/providers/dao/ldap/PasswordDaoAuthenticationProvider.java @@ -13,7 +13,7 @@ * limitations under the License. */ -package net.sf.acegisecurity.providers.dao; +package net.sf.acegisecurity.providers.dao.ldap; import net.sf.acegisecurity.AccountExpiredException; import net.sf.acegisecurity.Authentication; @@ -25,6 +25,8 @@ import net.sf.acegisecurity.LockedException; import net.sf.acegisecurity.UserDetails; import net.sf.acegisecurity.providers.AuthenticationProvider; import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken; +import net.sf.acegisecurity.providers.dao.DaoAuthenticationProvider; +import net.sf.acegisecurity.providers.dao.UserCache; import net.sf.acegisecurity.providers.dao.cache.NullUserCache; import org.springframework.beans.factory.InitializingBean; @@ -83,6 +85,7 @@ import org.springframework.util.Assert; * further information. *

* + * @deprecated instead subclass {@link net.sf.acegisecurity.providers.dao.AbstractUserDetailsAuthenticationProvider} * @author Karel Miarka */ public class PasswordDaoAuthenticationProvider implements AuthenticationProvider, diff --git a/sandbox/src/main/java/org/acegisecurity/providers/dao/ldap/revised/LdapPassword2AuthenticationDao.java b/sandbox/src/main/java/org/acegisecurity/providers/dao/ldap/revised/LdapPassword2AuthenticationDao.java index cf5b836841..e9f0930bd2 100644 --- a/sandbox/src/main/java/org/acegisecurity/providers/dao/ldap/revised/LdapPassword2AuthenticationDao.java +++ b/sandbox/src/main/java/org/acegisecurity/providers/dao/ldap/revised/LdapPassword2AuthenticationDao.java @@ -24,7 +24,7 @@ import net.sf.acegisecurity.BadCredentialsException; import net.sf.acegisecurity.GrantedAuthority; import net.sf.acegisecurity.GrantedAuthorityImpl; import net.sf.acegisecurity.UserDetails; -import net.sf.acegisecurity.providers.dao.PasswordAuthenticationDao; +import net.sf.acegisecurity.providers.dao.ldap.PasswordAuthenticationDao; /** * Re-written version of the ACEGI LDAP code, diff --git a/core/src/test/java/org/acegisecurity/providers/dao/PasswordDaoAuthenticationProviderTests.java b/sandbox/src/test/java/org/acegisecurity/providers/dao/ldap/PasswordDaoAuthenticationProviderTests.java similarity index 98% rename from core/src/test/java/org/acegisecurity/providers/dao/PasswordDaoAuthenticationProviderTests.java rename to sandbox/src/test/java/org/acegisecurity/providers/dao/ldap/PasswordDaoAuthenticationProviderTests.java index da8aadeb3e..008fe490e5 100644 --- a/core/src/test/java/org/acegisecurity/providers/dao/PasswordDaoAuthenticationProviderTests.java +++ b/sandbox/src/test/java/org/acegisecurity/providers/dao/ldap/PasswordDaoAuthenticationProviderTests.java @@ -13,10 +13,12 @@ * limitations under the License. */ -package net.sf.acegisecurity.providers.dao; +package net.sf.acegisecurity.providers.dao.ldap; + +import java.util.HashMap; +import java.util.Map; import junit.framework.TestCase; - import net.sf.acegisecurity.AccountExpiredException; import net.sf.acegisecurity.Authentication; import net.sf.acegisecurity.AuthenticationServiceException; @@ -29,15 +31,15 @@ import net.sf.acegisecurity.LockedException; import net.sf.acegisecurity.UserDetails; import net.sf.acegisecurity.providers.TestingAuthenticationToken; import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken; +import net.sf.acegisecurity.providers.dao.User; +import net.sf.acegisecurity.providers.dao.UserCache; +import net.sf.acegisecurity.providers.dao.UsernameNotFoundException; import net.sf.acegisecurity.providers.dao.cache.EhCacheBasedUserCache; import net.sf.acegisecurity.providers.dao.cache.NullUserCache; import org.springframework.dao.DataAccessException; import org.springframework.dao.DataRetrievalFailureException; -import java.util.HashMap; -import java.util.Map; - /** * Tests {@link PasswordDaoAuthenticationProvider}.