diff --git a/adapters/cas/src/test/java/org/acegisecurity/adapters/cas/applicationContext-invalid.xml b/adapters/cas/src/test/java/org/acegisecurity/adapters/cas/applicationContext-invalid.xml index f48ec3281c..872d1f5977 100644 --- a/adapters/cas/src/test/java/org/acegisecurity/adapters/cas/applicationContext-invalid.xml +++ b/adapters/cas/src/test/java/org/acegisecurity/adapters/cas/applicationContext-invalid.xml @@ -33,7 +33,6 @@ - my_password diff --git a/adapters/cas/src/test/java/org/acegisecurity/adapters/cas/applicationContext-valid.xml b/adapters/cas/src/test/java/org/acegisecurity/adapters/cas/applicationContext-valid.xml index 66c709eebb..33132386f3 100644 --- a/adapters/cas/src/test/java/org/acegisecurity/adapters/cas/applicationContext-valid.xml +++ b/adapters/cas/src/test/java/org/acegisecurity/adapters/cas/applicationContext-valid.xml @@ -33,7 +33,6 @@ - my_password 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 288ce23910..a863be2387 100644 --- a/core/src/main/java/org/acegisecurity/providers/dao/DaoAuthenticationProvider.java +++ b/core/src/main/java/org/acegisecurity/providers/dao/DaoAuthenticationProvider.java @@ -22,6 +22,7 @@ import net.sf.acegisecurity.BadCredentialsException; import net.sf.acegisecurity.DisabledException; 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.dao.event.AuthenticationFailureDisabledEvent; import net.sf.acegisecurity.providers.dao.event.AuthenticationFailurePasswordEvent; import net.sf.acegisecurity.providers.dao.event.AuthenticationSuccessEvent; @@ -36,32 +37,26 @@ import org.springframework.context.ApplicationContextAware; import org.springframework.dao.DataAccessException; -import java.util.Date; - /** * An {@link AuthenticationProvider} implementation that retrieves user details * from an {@link AuthenticationDao}. * *

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

* *

- * Upon successful validation, a DaoAuthenticationToken will be - * created and returned to the caller. This token will be signed with the key - * configured by {@link #getKey()} and expire {@link - * #getRefreshTokenInterval()} milliseconds into the future. The token will be - * assumed to remain valid whilstever it has not expired, and no requests of - * the AuthenticationProvider will need to be made. Once the - * token has expired, the relevant AuthenticationProvider will be - * called again to provide an updated enabled/disabled status, and list of - * granted authorities. It should be noted the credentials will not be - * revalidated, as the user presented correct credentials in the originial - * UsernamePasswordAuthenticationToken. This avoids complications - * if the user changes their password during the session. + * Upon successful validation, a + * UsernamePasswordAuthenticationToken will be created and + * returned to the caller. In addition, the {@link User} will be placed in the + * {@link UserCache} so 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. *

* *

@@ -83,8 +78,7 @@ public class DaoAuthenticationProvider implements AuthenticationProvider, private AuthenticationDao authenticationDao; private PasswordEncoder passwordEncoder = new PlaintextPasswordEncoder(); private SaltSource saltSource; - private String key; - private long refreshTokenInterval = 60000; // 60 seconds + private UserCache userCache = new NullUserCache(); //~ Methods ================================================================ @@ -101,14 +95,6 @@ public class DaoAuthenticationProvider implements AuthenticationProvider, return authenticationDao; } - public void setKey(String key) { - this.key = key; - } - - public String getKey() { - return key; - } - /** * Sets the PasswordEncoder instance to be used to encode and validate * passwords. If not set, {@link PlaintextPasswordEncoder} will be used by @@ -124,22 +110,6 @@ public class DaoAuthenticationProvider implements AuthenticationProvider, return passwordEncoder; } - public void setRefreshTokenInterval(long refreshTokenInterval) { - this.refreshTokenInterval = refreshTokenInterval; - } - - /** - * Indicates the number of seconds a created - * DaoAuthenticationToken will remain valid for. Whilstever - * the token is valid, the DaoAuthenticationProvider will - * only check it presents the expected key hash code. - * - * @return Returns the refreshTokenInterval. - */ - public long getRefreshTokenInterval() { - return refreshTokenInterval; - } - /** * The source of salts to use when decoding passwords. null * is a valid value, meaning the DaoAuthenticationProvider @@ -157,46 +127,36 @@ 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 { if (this.authenticationDao == null) { throw new IllegalArgumentException( "An Authentication DAO must be set"); } - if ((this.key == null) || "".equals(key)) { - throw new IllegalArgumentException("A key must be set"); + if (this.userCache == null) { + throw new IllegalArgumentException("A user cache must be set"); } } public Authentication authenticate(Authentication authentication) throws AuthenticationException { - // If an existing DaoAuthenticationToken, check we created it and it hasn't expired - if (authentication instanceof DaoAuthenticationToken) { - if (this.key.hashCode() == ((DaoAuthenticationToken) authentication) - .getKeyHash()) { - if (((DaoAuthenticationToken) authentication).getExpires() - .after(new Date())) { - return authentication; - } - } else { - throw new BadCredentialsException( - "The presented DaoAuthenticationToken does not contain the expected key"); - } + boolean cacheWasUsed = true; + User user = this.userCache.getUserFromCache(authentication.getPrincipal() + .toString()); + + if (user == null) { + cacheWasUsed = false; + user = getUserFromBackend(authentication); } - // We need to authenticate or refresh the token - User user = null; - - try { - user = this.authenticationDao.loadUserByUsername(authentication.getPrincipal() - .toString()); - } catch (UsernameNotFoundException notFound) { - throw new BadCredentialsException("Bad credentials presented"); - } catch (DataAccessException repositoryProblem) { - throw new AuthenticationServiceException(repositoryProblem - .getMessage(), repositoryProblem); - } - if (!user.isEnabled()) { if (this.ctx != null) { ctx.publishEvent(new AuthenticationFailureDisabledEvent( @@ -206,16 +166,14 @@ public class DaoAuthenticationProvider implements AuthenticationProvider, throw new DisabledException("User is disabled"); } - if (!(authentication instanceof DaoAuthenticationToken)) { - // Must validate credentials, as this is not simply a token refresh - Object salt = null; - - if (this.saltSource != null) { - salt = this.saltSource.getSalt(user); + if (!isPasswordCorrect(authentication, user)) { + // Password incorrect, so ensure we're using most current password + if (cacheWasUsed) { + cacheWasUsed = false; + user = getUserFromBackend(authentication); } - if (!passwordEncoder.isPasswordValid(user.getPassword(), - authentication.getCredentials().toString(), salt)) { + if (!isPasswordCorrect(authentication, user)) { if (this.ctx != null) { ctx.publishEvent(new AuthenticationFailurePasswordEvent( authentication, user)); @@ -225,24 +183,50 @@ public class DaoAuthenticationProvider implements AuthenticationProvider, } } - Date expiry = new Date(new Date().getTime() - + this.getRefreshTokenInterval()); + if (!cacheWasUsed) { + // Put into cache + this.userCache.putUserInCache(user); - if (this.ctx != null) { - ctx.publishEvent(new AuthenticationSuccessEvent(authentication, user)); + // As this appears to be an initial login, publish the event + if (this.ctx != null) { + ctx.publishEvent(new AuthenticationSuccessEvent( + authentication, user)); + } } - return new DaoAuthenticationToken(this.getKey(), expiry, - user.getUsername(), user.getPassword(), user.getAuthorities()); + return new UsernamePasswordAuthenticationToken(user.getUsername(), + user.getPassword(), user.getAuthorities()); } public boolean supports(Class authentication) { if (UsernamePasswordAuthenticationToken.class.isAssignableFrom( - authentication) - || (DaoAuthenticationToken.class.isAssignableFrom(authentication))) { + authentication)) { return true; } else { return false; } } + + private boolean isPasswordCorrect(Authentication authentication, User user) { + Object salt = null; + + if (this.saltSource != null) { + salt = this.saltSource.getSalt(user); + } + + return passwordEncoder.isPasswordValid(user.getPassword(), + authentication.getCredentials().toString(), salt); + } + + private User getUserFromBackend(Authentication authentication) { + try { + return this.authenticationDao.loadUserByUsername(authentication.getPrincipal() + .toString()); + } catch (UsernameNotFoundException notFound) { + throw new BadCredentialsException("Bad credentials presented"); + } catch (DataAccessException repositoryProblem) { + throw new AuthenticationServiceException(repositoryProblem + .getMessage(), repositoryProblem); + } + } } diff --git a/core/src/main/java/org/acegisecurity/providers/dao/DaoAuthenticationToken.java b/core/src/main/java/org/acegisecurity/providers/dao/DaoAuthenticationToken.java deleted file mode 100644 index b9cbc4ec54..0000000000 --- a/core/src/main/java/org/acegisecurity/providers/dao/DaoAuthenticationToken.java +++ /dev/null @@ -1,156 +0,0 @@ -/* Copyright 2004 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.GrantedAuthority; -import net.sf.acegisecurity.providers.AbstractAuthenticationToken; - -import java.io.Serializable; - -import java.util.Date; - - -/** - * Represents a successful DAO-based Authentication. - * - * @author Ben Alex - * @version $Id$ - */ -public class DaoAuthenticationToken extends AbstractAuthenticationToken - implements Serializable { - //~ Instance fields ======================================================== - - private Date expires; - private Object credentials; - private Object principal; - private GrantedAuthority[] authorities; - private int keyHash; - - //~ Constructors =========================================================== - - /** - * Constructor. - * - * @param key to identify if this object made by a given {@link - * DaoAuthenticationProvider} - * @param expires when the token is due to expire - * @param principal the username from the {@link User} object - * @param credentials the password from the {@link User} object - * @param authorities the authorities granted to the user, from the {@link - * User} object - * - * @throws IllegalArgumentException if a null was passed - */ - public DaoAuthenticationToken(String key, Date expires, Object principal, - Object credentials, GrantedAuthority[] authorities) { - if ((key == null) || ("".equals(key)) || (expires == null) - || (principal == null) || "".equals(principal) - || (credentials == null) || "".equals(credentials) - || (authorities == null)) { - throw new IllegalArgumentException( - "Cannot pass null or empty values to constructor"); - } - - for (int i = 0; i < authorities.length; i++) { - if (authorities[i] == null) { - throw new IllegalArgumentException("Granted authority element " - + i - + " is null - GrantedAuthority[] cannot contain any null elements"); - } - } - - this.keyHash = key.hashCode(); - this.expires = expires; - this.principal = principal; - this.credentials = credentials; - this.authorities = authorities; - } - - protected DaoAuthenticationToken() { - throw new IllegalArgumentException("Cannot use default constructor"); - } - - //~ Methods ================================================================ - - /** - * Ignored (always true). - * - * @param isAuthenticated ignored - */ - public void setAuthenticated(boolean isAuthenticated) { - // ignored - } - - /** - * Always returns true. - * - * @return true - */ - public boolean isAuthenticated() { - return true; - } - - public GrantedAuthority[] getAuthorities() { - return this.authorities; - } - - public Object getCredentials() { - return this.credentials; - } - - public Date getExpires() { - return this.expires; - } - - public int getKeyHash() { - return this.keyHash; - } - - public Object getPrincipal() { - return this.principal; - } - - public boolean equals(Object obj) { - if (!super.equals(obj)) { - return false; - } - - if (obj instanceof DaoAuthenticationToken) { - DaoAuthenticationToken test = (DaoAuthenticationToken) obj; - - if (this.getKeyHash() != test.getKeyHash()) { - return false; - } - - // expires never null due to constructor - if (this.getExpires() != test.getExpires()) { - return false; - } - - return true; - } - - return false; - } - - public String toString() { - StringBuffer sb = new StringBuffer(); - sb.append(super.toString()); - sb.append("; Expires: " + this.expires.toString()); - - return sb.toString(); - } -} diff --git a/core/src/main/java/org/acegisecurity/providers/dao/UserCache.java b/core/src/main/java/org/acegisecurity/providers/dao/UserCache.java new file mode 100644 index 0000000000..9daa3fc2c8 --- /dev/null +++ b/core/src/main/java/org/acegisecurity/providers/dao/UserCache.java @@ -0,0 +1,53 @@ +/* Copyright 2004 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; + +/** + * Provides a cache of {@link User} objects. + * + *

+ * Implementations should provide appropriate methods to set their cache + * parameters (eg time-to-live) and/or force removal of entities before their + * normal expiration. These are not part of the UserCache + * interface contract because they vary depending on the type of caching + * system used (eg in-memory vs disk vs cluster vs hybrid). + *

+ * + * @author Ben Alex + * @version $Id$ + */ +public interface UserCache { + //~ Methods ================================================================ + + /** + * Obtains a {@link User} from the cache. + * + * @param username the {@link User#getUsername()} used to place the user in + * the cache + * + * @return the populated User or null if the user + * could not be found or if the cache entry has expired + */ + public User getUserFromCache(String username); + + /** + * Places a {@link User} in the cache. The username is the key + * used to subsequently retrieve the User. + * + * @param user the fully populated User to place in the cache + */ + public void putUserInCache(User user); +} diff --git a/core/src/main/java/org/acegisecurity/providers/dao/cache/EhCacheBasedUserCache.java b/core/src/main/java/org/acegisecurity/providers/dao/cache/EhCacheBasedUserCache.java new file mode 100644 index 0000000000..7f248667ed --- /dev/null +++ b/core/src/main/java/org/acegisecurity/providers/dao/cache/EhCacheBasedUserCache.java @@ -0,0 +1,135 @@ +/* Copyright 2004 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.cache; + +import net.sf.acegisecurity.providers.dao.User; +import net.sf.acegisecurity.providers.dao.UserCache; + +import net.sf.ehcache.Cache; +import net.sf.ehcache.CacheException; +import net.sf.ehcache.CacheManager; +import net.sf.ehcache.Element; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.springframework.beans.factory.DisposableBean; +import org.springframework.beans.factory.InitializingBean; + +import org.springframework.dao.DataRetrievalFailureException; + + +/** + * Caches User objects using EHCACHE. + * + * @author Ben Alex + * @version $Id$ + */ +public class EhCacheBasedUserCache implements UserCache, InitializingBean, + DisposableBean { + //~ Static fields/initializers ============================================= + + private static final Log logger = LogFactory.getLog(EhCacheBasedUserCache.class); + private static final String CACHE_NAME = "ehCacheBasedUserCache"; + + //~ Instance fields ======================================================== + + private Cache cache; + private CacheManager manager; + private int minutesToIdle = 5; + + //~ Methods ================================================================ + + public void setMinutesToIdle(int minutesToIdle) { + this.minutesToIdle = minutesToIdle; + } + + /** + * Specifies how many minutes an entry will remain in the cache from when + * it was last accessed. This is effectively the session duration. + * + *

+ * Defaults to 5 minutes. + *

+ * + * @return Returns the minutes an element remains in the cache + */ + public int getMinutesToIdle() { + return minutesToIdle; + } + + public User getUserFromCache(String username) { + Element element = null; + + try { + element = cache.get(username); + } catch (CacheException cacheException) { + throw new DataRetrievalFailureException("Cache failure: " + + cacheException.getMessage()); + } + + if (logger.isDebugEnabled()) { + logger.debug("Cache hit: " + (element != null) + "; username: " + + username); + } + + if (element == null) { + return null; + } else { + return (User) element.getValue(); + } + } + + public void afterPropertiesSet() throws Exception { + if (CacheManager.getInstance().cacheExists(CACHE_NAME)) { + CacheManager.getInstance().removeCache(CACHE_NAME); + } + + manager = CacheManager.create(); + + // Cache name, max memory, overflowToDisk, eternal, timeToLive, timeToIdle + cache = new Cache(CACHE_NAME, Integer.MAX_VALUE, false, false, + minutesToIdle * 60, minutesToIdle * 60); + manager.addCache(cache); + } + + public void destroy() throws Exception { + manager.removeCache(CACHE_NAME); + } + + public void putUserInCache(User user) { + Element element = new Element(user.getUsername(), user); + + if (logger.isDebugEnabled()) { + logger.debug("Cache put: " + element.getKey()); + } + + cache.put(element); + } + + public void removeUserFromCache(User user) { + if (logger.isDebugEnabled()) { + logger.debug("Cache remove: " + user.getUsername()); + } + + this.removeUserFromCache(user.getUsername()); + } + + public void removeUserFromCache(String username) { + cache.remove(username); + } +} diff --git a/core/src/main/java/org/acegisecurity/providers/dao/cache/NullUserCache.java b/core/src/main/java/org/acegisecurity/providers/dao/cache/NullUserCache.java new file mode 100644 index 0000000000..26357d959e --- /dev/null +++ b/core/src/main/java/org/acegisecurity/providers/dao/cache/NullUserCache.java @@ -0,0 +1,36 @@ +/* Copyright 2004 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.cache; + +import net.sf.acegisecurity.providers.dao.User; +import net.sf.acegisecurity.providers.dao.UserCache; + + +/** + * Does not perform any caching. + * + * @author Ben Alex + * @version $Id$ + */ +public class NullUserCache implements UserCache { + //~ Methods ================================================================ + + public User getUserFromCache(String username) { + return null; + } + + public void putUserInCache(User user) {} +} diff --git a/core/src/main/java/org/acegisecurity/providers/dao/cache/package.html b/core/src/main/java/org/acegisecurity/providers/dao/cache/package.html new file mode 100644 index 0000000000..b59b1e93f2 --- /dev/null +++ b/core/src/main/java/org/acegisecurity/providers/dao/cache/package.html @@ -0,0 +1,5 @@ + + +Caches User objects for the DaoAuthenticationProvider. + + diff --git a/core/src/test/java/org/acegisecurity/adapters/adaptertest-valid.xml b/core/src/test/java/org/acegisecurity/adapters/adaptertest-valid.xml index 7f0c51c608..38a23ee9ca 100644 --- a/core/src/test/java/org/acegisecurity/adapters/adaptertest-valid.xml +++ b/core/src/test/java/org/acegisecurity/adapters/adaptertest-valid.xml @@ -36,7 +36,6 @@ - my_password 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 4404da03ee..6941bc4d6d 100644 --- a/core/src/test/java/org/acegisecurity/providers/dao/DaoAuthenticationProviderTests.java +++ b/core/src/test/java/org/acegisecurity/providers/dao/DaoAuthenticationProviderTests.java @@ -25,13 +25,16 @@ import net.sf.acegisecurity.GrantedAuthority; import net.sf.acegisecurity.GrantedAuthorityImpl; import net.sf.acegisecurity.providers.TestingAuthenticationToken; import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken; +import net.sf.acegisecurity.providers.dao.cache.EhCacheBasedUserCache; +import net.sf.acegisecurity.providers.dao.cache.NullUserCache; import net.sf.acegisecurity.providers.dao.salt.SystemWideSaltSource; import net.sf.acegisecurity.providers.encoding.ShaPasswordEncoder; import org.springframework.dao.DataAccessException; import org.springframework.dao.DataRetrievalFailureException; -import java.util.Date; +import java.util.HashMap; +import java.util.Map; /** @@ -56,8 +59,8 @@ public class DaoAuthenticationProviderTests extends TestCase { "KOala"); DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); - provider.setKey("x"); provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa()); + provider.setUserCache(new MockUserCache()); try { provider.authenticate(token); @@ -72,8 +75,8 @@ public class DaoAuthenticationProviderTests extends TestCase { "opal"); DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); - provider.setKey("x"); provider.setAuthenticationDao(new MockAuthenticationDaoUserPeter()); + provider.setUserCache(new MockUserCache()); try { provider.authenticate(token); @@ -88,8 +91,8 @@ public class DaoAuthenticationProviderTests extends TestCase { "koala"); DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); - provider.setKey("x"); provider.setAuthenticationDao(new MockAuthenticationDaoSimulateBackendError()); + provider.setUserCache(new MockUserCache()); try { provider.authenticate(token); @@ -104,8 +107,8 @@ public class DaoAuthenticationProviderTests extends TestCase { "INVALID_PASSWORD"); DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); - provider.setKey("x"); provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa()); + provider.setUserCache(new MockUserCache()); try { provider.authenticate(token); @@ -120,8 +123,8 @@ public class DaoAuthenticationProviderTests extends TestCase { "koala"); DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); - provider.setKey("x"); provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa()); + provider.setUserCache(new MockUserCache()); try { provider.authenticate(token); @@ -136,8 +139,8 @@ public class DaoAuthenticationProviderTests extends TestCase { "koala"); DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); - provider.setKey("x"); provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa()); + provider.setUserCache(new MockUserCache()); try { provider.authenticate(token); @@ -152,55 +155,21 @@ public class DaoAuthenticationProviderTests extends TestCase { "koala"); DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); - provider.setKey("x"); provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa()); + provider.setUserCache(new MockUserCache()); Authentication result = provider.authenticate(token); - if (!(result instanceof DaoAuthenticationToken)) { - fail("Should have returned instance of DaoAuthenticationToken"); + if (!(result instanceof UsernamePasswordAuthenticationToken)) { + fail( + "Should have returned instance of UsernamePasswordAuthenticationToken"); } - DaoAuthenticationToken castResult = (DaoAuthenticationToken) result; + UsernamePasswordAuthenticationToken castResult = (UsernamePasswordAuthenticationToken) result; assertEquals("marissa", castResult.getPrincipal()); assertEquals("koala", castResult.getCredentials()); assertEquals("ROLE_ONE", castResult.getAuthorities()[0].getAuthority()); assertEquals("ROLE_TWO", castResult.getAuthorities()[1].getAuthority()); - assertEquals(provider.getKey().hashCode(), castResult.getKeyHash()); - } - - public void testAuthenticatesThenAcceptsCreatedTokenAutomatically() { - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("marissa", - "koala"); - - DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); - provider.setKey("x"); - provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa()); - - Authentication result = provider.authenticate(token); - - if (!(result instanceof DaoAuthenticationToken)) { - fail("Should have returned instance of DaoAuthenticationToken"); - } - - DaoAuthenticationToken castResult = (DaoAuthenticationToken) result; - assertEquals("marissa", castResult.getPrincipal()); - assertEquals(provider.getKey().hashCode(), castResult.getKeyHash()); - assertTrue(castResult.getExpires().after(new Date())); - - // Now try to re-authenticate - // Set provider to null, so we get a NullPointerException if it tries to re-authenticate - provider.setAuthenticationDao(null); - - Authentication secondResult = provider.authenticate(result); - - if (!(secondResult instanceof DaoAuthenticationToken)) { - fail("Should have returned instance of DaoAuthenticationToken"); - } - - // Should still have the same expiry time as original - assertEquals(castResult.getExpires(), - ((DaoAuthenticationToken) secondResult).getExpires()); } public void testAuthenticatesWhenASaltIsUsed() { @@ -211,77 +180,22 @@ public class DaoAuthenticationProviderTests extends TestCase { salt.setSystemWideSalt("SYSTEM_SALT_VALUE"); DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); - provider.setKey("x"); provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissaWithSalt()); provider.setSaltSource(salt); + provider.setUserCache(new MockUserCache()); Authentication result = provider.authenticate(token); - if (!(result instanceof DaoAuthenticationToken)) { + if (!(result instanceof UsernamePasswordAuthenticationToken)) { fail( - "Should have returned instance of DaoPasswordAuthenticationToken"); + "Should have returned instance of UsernamePasswordAuthenticationToken"); } - DaoAuthenticationToken castResult = (DaoAuthenticationToken) result; + UsernamePasswordAuthenticationToken castResult = (UsernamePasswordAuthenticationToken) result; assertEquals("marissa", castResult.getPrincipal()); assertEquals("koala{SYSTEM_SALT_VALUE}", castResult.getCredentials()); assertEquals("ROLE_ONE", castResult.getAuthorities()[0].getAuthority()); assertEquals("ROLE_TWO", castResult.getAuthorities()[1].getAuthority()); - assertEquals(provider.getKey().hashCode(), castResult.getKeyHash()); - } - - public void testDaoAuthenticationTokensThatHaveExpiredAreRefreshed() - throws Exception { - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("marissa", - "koala"); - - DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); - provider.setKey("x"); - provider.setRefreshTokenInterval(0); // never cache - provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa()); - - Authentication result = provider.authenticate(token); - - if (!(result instanceof DaoAuthenticationToken)) { - fail("Should have returned instance of DaoAuthenticationToken"); - } - - DaoAuthenticationToken castResult = (DaoAuthenticationToken) result; - assertEquals("marissa", castResult.getPrincipal()); - assertEquals(provider.getKey().hashCode(), castResult.getKeyHash()); - Thread.sleep(1000); - assertTrue(castResult.getExpires().before(new Date())); // already expired - - // Now try to re-authenticate - Authentication secondResult = provider.authenticate(result); - - if (!(secondResult instanceof DaoAuthenticationToken)) { - fail("Should have returned instance of DaoAuthenticationToken"); - } - - // Should still have a later expiry time than original - assertTrue(castResult.getExpires().before(((DaoAuthenticationToken) secondResult) - .getExpires())); - } - - public void testDaoAuthenticationTokensWithWrongKeyAreRejected() - throws Exception { - DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); - provider.setKey("x"); - provider.setRefreshTokenInterval(0); // never cache - provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa()); - - DaoAuthenticationToken token = new DaoAuthenticationToken("key", - new Date(), "Test", "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); - - try { - provider.authenticate(token); - fail("Should have thrown BadCredentialsException"); - } catch (BadCredentialsException expected) { - assertTrue(true); - } } public void testGettersSetters() { @@ -293,12 +207,15 @@ public class DaoAuthenticationProviderTests extends TestCase { provider.setSaltSource(new SystemWideSaltSource()); assertEquals(SystemWideSaltSource.class, provider.getSaltSource().getClass()); + + provider.setUserCache(new EhCacheBasedUserCache()); + assertEquals(EhCacheBasedUserCache.class, + provider.getUserCache().getClass()); } public void testStartupFailsIfNoAuthenticationDao() throws Exception { DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); - provider.setKey("xxx"); try { provider.afterPropertiesSet(); @@ -308,9 +225,11 @@ public class DaoAuthenticationProviderTests extends TestCase { } } - public void testStartupFailsIfNoKeySet() throws Exception { + public void testStartupFailsIfNoUserCacheSet() throws Exception { DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa()); + assertEquals(NullUserCache.class, provider.getUserCache().getClass()); + provider.setUserCache(null); try { provider.afterPropertiesSet(); @@ -323,8 +242,8 @@ public class DaoAuthenticationProviderTests extends TestCase { public void testStartupSuccess() throws Exception { DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); AuthenticationDao dao = new MockAuthenticationDaoUserMarissa(); - provider.setKey("x"); provider.setAuthenticationDao(dao); + provider.setUserCache(new MockUserCache()); assertEquals(dao, provider.getAuthenticationDao()); provider.afterPropertiesSet(); assertTrue(true); @@ -334,7 +253,6 @@ public class DaoAuthenticationProviderTests extends TestCase { DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); assertTrue(provider.supports(UsernamePasswordAuthenticationToken.class)); assertTrue(!provider.supports(TestingAuthenticationToken.class)); - assertTrue(provider.supports(DaoAuthenticationToken.class)); } //~ Inner Classes ========================================================== @@ -390,4 +308,16 @@ public class DaoAuthenticationProviderTests extends TestCase { } } } + + private class MockUserCache implements UserCache { + private Map cache = new HashMap(); + + public User getUserFromCache(String username) { + return (User) cache.get(username); + } + + public void putUserInCache(User user) { + cache.put(user.getUsername(), user); + } + } } diff --git a/core/src/test/java/org/acegisecurity/providers/dao/DaoAuthenticationTokenTests.java b/core/src/test/java/org/acegisecurity/providers/dao/DaoAuthenticationTokenTests.java deleted file mode 100644 index 0ce784c038..0000000000 --- a/core/src/test/java/org/acegisecurity/providers/dao/DaoAuthenticationTokenTests.java +++ /dev/null @@ -1,226 +0,0 @@ -/* Copyright 2004 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 junit.framework.TestCase; - -import net.sf.acegisecurity.GrantedAuthority; -import net.sf.acegisecurity.GrantedAuthorityImpl; -import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken; - -import java.util.Date; - - -/** - * Tests {@link DaoAuthenticationToken}. - * - * @author Ben Alex - * @version $Id$ - */ -public class DaoAuthenticationTokenTests extends TestCase { - //~ Constructors =========================================================== - - public DaoAuthenticationTokenTests() { - super(); - } - - public DaoAuthenticationTokenTests(String arg0) { - super(arg0); - } - - //~ Methods ================================================================ - - public final void setUp() throws Exception { - super.setUp(); - } - - public static void main(String[] args) { - junit.textui.TestRunner.run(DaoAuthenticationTokenTests.class); - } - - public void testConstructorRejectsNulls() { - try { - new DaoAuthenticationToken(null, new Date(), "Test", "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); - fail("Should have thrown IllegalArgumentException"); - } catch (IllegalArgumentException expected) { - assertTrue(true); - } - - try { - new DaoAuthenticationToken("key", null, "Test", "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); - fail("Should have thrown IllegalArgumentException"); - } catch (IllegalArgumentException expected) { - assertTrue(true); - } - - try { - new DaoAuthenticationToken("key", new Date(), null, "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); - fail("Should have thrown IllegalArgumentException"); - } catch (IllegalArgumentException expected) { - assertTrue(true); - } - - try { - new DaoAuthenticationToken("key", new Date(), "Test", null, - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); - fail("Should have thrown IllegalArgumentException"); - } catch (IllegalArgumentException expected) { - assertTrue(true); - } - - try { - new DaoAuthenticationToken("key", new Date(), "Test", "Password", - null); - fail("Should have thrown IllegalArgumentException"); - } catch (IllegalArgumentException expected) { - assertTrue(true); - } - - try { - new DaoAuthenticationToken("key", new Date(), "Test", "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), null}); - fail("Should have thrown IllegalArgumentException"); - } catch (IllegalArgumentException expected) { - assertTrue(true); - } - } - - public void testEqualsWhenEqual() { - Date date = new Date(); - - DaoAuthenticationToken token1 = new DaoAuthenticationToken("key", date, - "Test", "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); - - DaoAuthenticationToken token2 = new DaoAuthenticationToken("key", date, - "Test", "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); - - assertEquals(token1, token2); - } - - public void testGetters() { - Date date = new Date(); - DaoAuthenticationToken token = new DaoAuthenticationToken("key", date, - "Test", "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); - assertEquals("key".hashCode(), token.getKeyHash()); - assertEquals("Test", token.getPrincipal()); - assertEquals("Password", token.getCredentials()); - assertEquals("ROLE_ONE", token.getAuthorities()[0].getAuthority()); - assertEquals("ROLE_TWO", token.getAuthorities()[1].getAuthority()); - assertEquals(date, token.getExpires()); - } - - public void testNoArgConstructor() { - try { - new DaoAuthenticationToken(); - fail("Should have thrown IllegalArgumentException"); - } catch (IllegalArgumentException expected) { - assertTrue(true); - } - } - - public void testNotEqualsDueToAbstractParentEqualsCheck() { - Date date = new Date(); - - DaoAuthenticationToken token1 = new DaoAuthenticationToken("key", date, - "Test", "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); - - DaoAuthenticationToken token2 = new DaoAuthenticationToken("key", date, - "DIFFERENT_PRINCIPAL", "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); - - assertTrue(!token1.equals(token2)); - } - - public void testNotEqualsDueToDifferentAuthenticationClass() { - DaoAuthenticationToken token1 = new DaoAuthenticationToken("key", - new Date(), "Test", "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); - - UsernamePasswordAuthenticationToken token2 = new UsernamePasswordAuthenticationToken("Test", - "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); - token2.setAuthenticated(true); - - assertTrue(!token1.equals(token2)); - } - - public void testNotEqualsDueToDifferentExpiresDate() { - DaoAuthenticationToken token1 = new DaoAuthenticationToken("key", - new Date(50000), "Test", "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); - - DaoAuthenticationToken token2 = new DaoAuthenticationToken("key", - new Date(60000), "Test", "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); - - assertTrue(!token1.equals(token2)); - } - - public void testNotEqualsDueToKey() { - Date date = new Date(); - - DaoAuthenticationToken token1 = new DaoAuthenticationToken("key", date, - "Test", "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); - - DaoAuthenticationToken token2 = new DaoAuthenticationToken("DIFFERENT_KEY", - date, "Test", "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); - - assertTrue(!token1.equals(token2)); - } - - public void testSetAuthenticatedIgnored() { - DaoAuthenticationToken token = new DaoAuthenticationToken("key", - new Date(), "Test", "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); - assertTrue(token.isAuthenticated()); - token.setAuthenticated(false); // ignored - assertTrue(token.isAuthenticated()); - } - - public void testToString() { - DaoAuthenticationToken token = new DaoAuthenticationToken("key", - new Date(), "Test", "Password", - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( - "ROLE_TWO")}); - String result = token.toString(); - assertTrue(result.lastIndexOf("Expires:") != -1); - } -} diff --git a/core/src/test/java/org/acegisecurity/providers/dao/cache/EhCacheBasedUserCacheTests.java b/core/src/test/java/org/acegisecurity/providers/dao/cache/EhCacheBasedUserCacheTests.java new file mode 100644 index 0000000000..4c99535dd1 --- /dev/null +++ b/core/src/test/java/org/acegisecurity/providers/dao/cache/EhCacheBasedUserCacheTests.java @@ -0,0 +1,83 @@ +/* Copyright 2004 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.cache; + +import junit.framework.TestCase; + +import net.sf.acegisecurity.GrantedAuthority; +import net.sf.acegisecurity.GrantedAuthorityImpl; +import net.sf.acegisecurity.providers.dao.User; + + +/** + * Tests {@link EhCacheBasedUserCache}. + * + * @author Ben Alex + * @version $Id$ + */ +public class EhCacheBasedUserCacheTests extends TestCase { + //~ Constructors =========================================================== + + public EhCacheBasedUserCacheTests() { + super(); + } + + public EhCacheBasedUserCacheTests(String arg0) { + super(arg0); + } + + //~ Methods ================================================================ + + public final void setUp() throws Exception { + super.setUp(); + } + + public static void main(String[] args) { + junit.textui.TestRunner.run(EhCacheBasedUserCacheTests.class); + } + + public void testCacheOperation() throws Exception { + EhCacheBasedUserCache cache = new EhCacheBasedUserCache(); + cache.afterPropertiesSet(); + + // Check it gets stored in the cache + cache.putUserInCache(getUser()); + assertEquals(getUser().getPassword(), + cache.getUserFromCache(getUser().getUsername()).getPassword()); + + // Check it gets removed from the cache + cache.removeUserFromCache(getUser()); + assertNull(cache.getUserFromCache(getUser().getUsername())); + + // Check it doesn't return values for null or unknown users + assertNull(cache.getUserFromCache(null)); + assertNull(cache.getUserFromCache("UNKNOWN_USER")); + + cache.destroy(); + } + + public void testGettersSetters() { + EhCacheBasedUserCache cache = new EhCacheBasedUserCache(); + cache.setMinutesToIdle(15); + assertEquals(15, cache.getMinutesToIdle()); + } + + private User getUser() { + return new User("john", "password", true, + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( + "ROLE_TWO")}); + } +} diff --git a/core/src/test/java/org/acegisecurity/providers/dao/cache/NullUserCacheTests.java b/core/src/test/java/org/acegisecurity/providers/dao/cache/NullUserCacheTests.java new file mode 100644 index 0000000000..477cace3bd --- /dev/null +++ b/core/src/test/java/org/acegisecurity/providers/dao/cache/NullUserCacheTests.java @@ -0,0 +1,63 @@ +/* Copyright 2004 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.cache; + +import junit.framework.TestCase; + +import net.sf.acegisecurity.GrantedAuthority; +import net.sf.acegisecurity.GrantedAuthorityImpl; +import net.sf.acegisecurity.providers.dao.User; + + +/** + * Tests {@link NullUserCache}. + * + * @author Ben Alex + * @version $Id$ + */ +public class NullUserCacheTests extends TestCase { + //~ Constructors =========================================================== + + public NullUserCacheTests() { + super(); + } + + public NullUserCacheTests(String arg0) { + super(arg0); + } + + //~ Methods ================================================================ + + public final void setUp() throws Exception { + super.setUp(); + } + + public static void main(String[] args) { + junit.textui.TestRunner.run(NullUserCacheTests.class); + } + + public void testCacheOperation() throws Exception { + NullUserCache cache = new NullUserCache(); + cache.putUserInCache(getUser()); + assertNull(cache.getUserFromCache(null)); + } + + private User getUser() { + return new User("john", "password", true, + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( + "ROLE_TWO")}); + } +} diff --git a/core/src/test/java/org/acegisecurity/ui/basicauth/filtertest-valid.xml b/core/src/test/java/org/acegisecurity/ui/basicauth/filtertest-valid.xml index b9bd6b67bc..08c20c8af0 100644 --- a/core/src/test/java/org/acegisecurity/ui/basicauth/filtertest-valid.xml +++ b/core/src/test/java/org/acegisecurity/ui/basicauth/filtertest-valid.xml @@ -36,7 +36,6 @@ - my_password diff --git a/docs/reference/src/index.xml b/docs/reference/src/index.xml index 9ffb267c9b..da514e821d 100644 --- a/docs/reference/src/index.xml +++ b/docs/reference/src/index.xml @@ -892,7 +892,6 @@ <bean id="daoAuthenticationProvider" class="net.sf.acegisecurity.providers.dao.DaoAuthenticationProvider"> <property name="authenticationDao"><ref bean="inMemoryDaoImpl"/></property> - <property name="key"><value>my_password</value></property> <property name="refreshTokenInterval"><value>60000</value></property> <property name="saltSource"><ref bean="saltSource"/></property> <property name="passwordEncoder"><ref bean="passwordEncoder"/></property> @@ -910,23 +909,30 @@ SaltSource implementations are also provided: SystemWideSaltSource which encodes all passwords with the same salt, and ReflectionSaltSource, which - inspects a given property of the returned User object to obtain the - salt. Please refer to the JavaDocs for further details on these - optional features. + inspects a given property of the returned User + object to obtain the salt. Please refer to the JavaDocs for further + details on these optional features. - The key property permits the - DaoAuthenticationProvider to build a - DaoAuthenticationToken that represents the - successful authentication request. This allows the - DaoAuthenticationProvider to avoid repeated lookups - of the backend authentication repository. For a presented - DaoAuthenticationToken to be accepted as valid, it - needs to both present the expected key (to prove it was created by the - DaoAuthenticationProvider) and that is has not - expired. DaoAuthenticationTokens by default expire - 60 seconds after they have been created, although this can be set to - any other millisecond value via the - refreshTokenInterval property. + In addition to the properties above, the + DaoAuthenticationProvider supports optional caching + of User objects. The UserCache + interface enables the DaoAuthenticationProvider to + place a User object into the cache, and retrieve it + from the cache upon subsequent authentication attempts for the same + username. By default the DaoAuthenticationProvider + uses the NullUserCache, which performs no caching. + A usable caching implementation is also provided, + EhCacheBasedUserCache, which is configured as + follows: + + <bean id="daoAuthenticationProvider" class="net.sf.acegisecurity.providers.dao.DaoAuthenticationProvider"> + <property name="authenticationDao"><ref bean="authenticationDao"/></property> + <property name="userCache"><ref bean="userCache"/></property> +</bean> + +<bean id="userCache" class="net.sf.acegisecurity.providers.dao.cache.EhCacheBasedUserCache"> + <property name="minutesToIdle"><value>5</value></property> +</bean> For a class to be able to provide the DaoAuthenticationProvider with access to an diff --git a/samples/contacts/build.xml b/samples/contacts/build.xml index 70077351e4..0578331421 100644 --- a/samples/contacts/build.xml +++ b/samples/contacts/build.xml @@ -152,6 +152,8 @@ + + diff --git a/samples/contacts/etc/ca/applicationContext.xml b/samples/contacts/etc/ca/applicationContext.xml index 48906619eb..46802b2516 100644 --- a/samples/contacts/etc/ca/applicationContext.xml +++ b/samples/contacts/etc/ca/applicationContext.xml @@ -48,7 +48,6 @@ - my_password diff --git a/samples/contacts/etc/filter/applicationContext.xml b/samples/contacts/etc/filter/applicationContext.xml index ffbce7886e..ddbb18a1ab 100644 --- a/samples/contacts/etc/filter/applicationContext.xml +++ b/samples/contacts/etc/filter/applicationContext.xml @@ -43,7 +43,11 @@ - my_password + + + + + 5 diff --git a/samples/quick-start/war-root/WEB-INF/applicationContext.xml b/samples/quick-start/war-root/WEB-INF/applicationContext.xml index b3f4e2362d..3ac87fe5b6 100644 --- a/samples/quick-start/war-root/WEB-INF/applicationContext.xml +++ b/samples/quick-start/war-root/WEB-INF/applicationContext.xml @@ -42,11 +42,14 @@ - - my_password + + + + + 5