浏览代码

Refactor EH-CACHE integration classes to work with Spring IoC provided Cache rather than manage our own cache internally.

Ben Alex 21 年之前
父节点
当前提交
76c82db196

+ 12 - 40
core/src/main/java/org/acegisecurity/acl/basic/cache/EhCacheBasedAclEntryCache.java

@@ -21,40 +21,43 @@ import net.sf.acegisecurity.acl.basic.BasicAclEntryCache;
 
 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 <code>BasicAclEntry</code>s using  <A
+ * Caches <code>BasicAclEntry</code>s using a Spring IoC defined <A
  * HREF="http://ehcache.sourceforge.net">EHCACHE</a>.
  *
  * @author Ben Alex
  * @version $Id$
  */
 public class EhCacheBasedAclEntryCache implements BasicAclEntryCache,
-    InitializingBean, DisposableBean {
+    InitializingBean {
     //~ Static fields/initializers =============================================
 
     private static final Log logger = LogFactory.getLog(EhCacheBasedAclEntryCache.class);
-    private static final String CACHE_NAME = "ehCacheBasedAclEntryCache";
 
     //~ Instance fields ========================================================
 
     private Cache cache;
-    private CacheManager manager;
-    private int minutesToIdle = 5;
 
     //~ Methods ================================================================
 
+    public void setCache(Cache cache) {
+        this.cache = cache;
+    }
+
+    public Cache getCache() {
+        return cache;
+    }
+
     public BasicAclEntry[] getEntriesFromCache(
         AclObjectIdentity aclObjectIdentity) {
         Element element = null;
@@ -85,43 +88,12 @@ public class EhCacheBasedAclEntryCache implements BasicAclEntryCache,
         return holder.getBasicAclEntries();
     }
 
-    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.
-     * 
-     * <P>
-     * Defaults to 5 minutes.
-     * </p>
-     *
-     * @return Returns the minutes an element remains in the cache
-     */
-    public int getMinutesToIdle() {
-        return minutesToIdle;
-    }
-
     public void afterPropertiesSet() throws Exception {
-        if (CacheManager.getInstance().cacheExists(CACHE_NAME)) {
-            // don’t remove the cache
-            cache = CacheManager.getInstance().getCache(CACHE_NAME);
-        } else {
-            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);
+        if (cache == null) {
+            throw new IllegalArgumentException("cache mandatory");
         }
     }
 
-    public void destroy() throws Exception {
-        manager.removeCache(CACHE_NAME);
-    }
-
     public void putEntriesInCache(BasicAclEntry[] basicAclEntry) {
         BasicAclEntryHolder holder = new BasicAclEntryHolder(basicAclEntry);
         Element element = new Element(basicAclEntry[0].getAclObjectIdentity(),

+ 9 - 36
core/src/main/java/org/acegisecurity/providers/cas/cache/EhCacheBasedTicketCache.java

@@ -20,36 +20,32 @@ import net.sf.acegisecurity.providers.cas.StatelessTicketCache;
 
 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 tickets using  <A HREF="http://ehcache.sourceforge.net">EHCACHE</a>.
+ * Caches tickets using a Spring IoC defined <A
+ * HREF="http://ehcache.sourceforge.net">EHCACHE</a>.
  *
  * @author Ben Alex
  * @version $Id$
  */
 public class EhCacheBasedTicketCache implements StatelessTicketCache,
-    InitializingBean, DisposableBean {
+    InitializingBean {
     //~ Static fields/initializers =============================================
 
     private static final Log logger = LogFactory.getLog(EhCacheBasedTicketCache.class);
-    private static final String CACHE_NAME = "ehCacheBasedTicketCache";
 
     //~ Instance fields ========================================================
 
     private Cache cache;
-    private CacheManager manager;
-    private int minutesToIdle = 20;
 
     //~ Methods ================================================================
 
@@ -75,43 +71,20 @@ public class EhCacheBasedTicketCache implements StatelessTicketCache,
         }
     }
 
-    public void setMinutesToIdle(int minutesToIdle) {
-        this.minutesToIdle = minutesToIdle;
+    public void setCache(Cache cache) {
+        this.cache = cache;
     }
 
-    /**
-     * Specifies how many minutes an entry will remain in the cache from  when
-     * it was last accessed. This is effectively the session duration.
-     * 
-     * <P>
-     * Defaults to 20 minutes.
-     * </p>
-     *
-     * @return Returns the minutes an element remains in the cache
-     */
-    public int getMinutesToIdle() {
-        return minutesToIdle;
+    public Cache getCache() {
+        return cache;
     }
 
     public void afterPropertiesSet() throws Exception {
-        if (CacheManager.getInstance().cacheExists(CACHE_NAME)) {
-            // don’t remove the cache
-            cache = CacheManager.getInstance().getCache(CACHE_NAME);
-        } else {
-            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);
+        if (cache == null) {
+            throw new IllegalArgumentException("cache mandatory");
         }
     }
 
-    public void destroy() throws Exception {
-        manager.removeCache(CACHE_NAME);
-    }
-
     public void putTicketInCache(CasAuthenticationToken token) {
         Element element = new Element(token.getCredentials().toString(), token);
 

+ 8 - 37
core/src/main/java/org/acegisecurity/providers/dao/cache/EhCacheBasedUserCache.java

@@ -20,56 +20,40 @@ 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 <code>User</code> objects using <A
+ * Caches <code>User</code> objects using a Spring IoC defined <A
  * HREF="http://ehcache.sourceforge.net">EHCACHE</a>.
  *
  * @author Ben Alex
  * @version $Id$
  */
-public class EhCacheBasedUserCache implements UserCache, InitializingBean,
-    DisposableBean {
+public class EhCacheBasedUserCache implements UserCache, InitializingBean {
     //~ 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;
+    public void setCache(Cache cache) {
+        this.cache = cache;
     }
 
-    /**
-     * Specifies how many minutes an entry will remain in the cache from when
-     * it was last accessed. This is effectively the session duration.
-     * 
-     * <P>
-     * Defaults to 5 minutes.
-     * </p>
-     *
-     * @return Returns the minutes an element remains in the cache
-     */
-    public int getMinutesToIdle() {
-        return minutesToIdle;
+    public Cache getCache() {
+        return cache;
     }
 
     public UserDetails getUserFromCache(String username) {
@@ -95,24 +79,11 @@ public class EhCacheBasedUserCache implements UserCache, InitializingBean,
     }
 
     public void afterPropertiesSet() throws Exception {
-        if (CacheManager.getInstance().cacheExists(CACHE_NAME)) {
-            // don’t remove the cache
-            cache = CacheManager.getInstance().getCache(CACHE_NAME);
-        } else {
-            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);
+        if (cache == null) {
+            throw new IllegalArgumentException("cache mandatory");
         }
     }
 
-    public void destroy() throws Exception {
-        manager.removeCache(CACHE_NAME);
-    }
-
     public void putUserInCache(UserDetails user) {
         Element element = new Element(user.getUsername(), user);
 

+ 26 - 8
core/src/test/java/org/acegisecurity/acl/basic/cache/EhCacheBasedAclEntryCacheTests.java

@@ -17,11 +17,16 @@ package net.sf.acegisecurity.acl.basic.cache;
 
 import junit.framework.TestCase;
 
+import net.sf.acegisecurity.MockApplicationContext;
 import net.sf.acegisecurity.acl.basic.AclObjectIdentity;
 import net.sf.acegisecurity.acl.basic.BasicAclEntry;
 import net.sf.acegisecurity.acl.basic.NamedEntityObjectIdentity;
 import net.sf.acegisecurity.acl.basic.SimpleAclEntry;
 
+import net.sf.ehcache.Cache;
+
+import org.springframework.context.ApplicationContext;
+
 
 /**
  * Tests {@link EhCacheBasedAclEntryCache}.
@@ -65,9 +70,7 @@ public class EhCacheBasedAclEntryCacheTests extends TestCase {
 
     public void testCacheOperation() throws Exception {
         EhCacheBasedAclEntryCache cache = new EhCacheBasedAclEntryCache();
-        cache.afterPropertiesSet();
-
-        // execute a second time to test detection of existing instance
+        cache.setCache(getCache());
         cache.afterPropertiesSet();
 
         cache.putEntriesInCache(new BasicAclEntry[] {OBJECT_100_SCOTT, OBJECT_100_MARISSA});
@@ -83,13 +86,28 @@ public class EhCacheBasedAclEntryCacheTests extends TestCase {
         assertEquals(OBJECT_200_PETER,
             cache.getEntriesFromCache(
                 new NamedEntityObjectIdentity("OBJECT", "200"))[0]);
-
-        cache.destroy();
+        assertNull(cache.getEntriesFromCache(
+                new NamedEntityObjectIdentity("OBJECT", "NOT_IN_CACHE")));
     }
 
-    public void testGettersSetters() {
+    public void testStartupDetectsMissingCache() throws Exception {
         EhCacheBasedAclEntryCache cache = new EhCacheBasedAclEntryCache();
-        cache.setMinutesToIdle(15);
-        assertEquals(15, cache.getMinutesToIdle());
+
+        try {
+            cache.afterPropertiesSet();
+            fail("Should have thrown IllegalArgumentException");
+        } catch (IllegalArgumentException expected) {
+            assertTrue(true);
+        }
+
+        Cache myCache = getCache();
+        cache.setCache(myCache);
+        assertEquals(myCache, cache.getCache());
+    }
+
+    private Cache getCache() {
+        ApplicationContext ctx = MockApplicationContext.getContext();
+
+        return (Cache) ctx.getBean("eHCacheBackend");
     }
 }

+ 24 - 6
core/src/test/java/org/acegisecurity/providers/cas/cache/EhCacheBasedTicketCacheTests.java

@@ -19,9 +19,14 @@ import junit.framework.TestCase;
 
 import net.sf.acegisecurity.GrantedAuthority;
 import net.sf.acegisecurity.GrantedAuthorityImpl;
+import net.sf.acegisecurity.MockApplicationContext;
 import net.sf.acegisecurity.providers.cas.CasAuthenticationToken;
 import net.sf.acegisecurity.providers.dao.User;
 
+import net.sf.ehcache.Cache;
+
+import org.springframework.context.ApplicationContext;
+
 import java.util.List;
 import java.util.Vector;
 
@@ -55,8 +60,8 @@ public class EhCacheBasedTicketCacheTests extends TestCase {
 
     public void testCacheOperation() throws Exception {
         EhCacheBasedTicketCache cache = new EhCacheBasedTicketCache();
+        cache.setCache(getCache());
         cache.afterPropertiesSet();
-        cache.afterPropertiesSet(); // second run for test coverage
 
         // Check it gets stored in the cache
         cache.putTicketInCache(getToken());
@@ -70,14 +75,27 @@ public class EhCacheBasedTicketCacheTests extends TestCase {
         // Check it doesn't return values for null or unknown service tickets
         assertNull(cache.getByTicketId(null));
         assertNull(cache.getByTicketId("UNKNOWN_SERVICE_TICKET"));
-
-        cache.destroy();
     }
 
-    public void testGettersSetters() {
+    public void testStartupDetectsMissingCache() throws Exception {
         EhCacheBasedTicketCache cache = new EhCacheBasedTicketCache();
-        cache.setMinutesToIdle(5);
-        assertEquals(5, cache.getMinutesToIdle());
+
+        try {
+            cache.afterPropertiesSet();
+            fail("Should have thrown IllegalArgumentException");
+        } catch (IllegalArgumentException expected) {
+            assertTrue(true);
+        }
+
+        Cache myCache = getCache();
+        cache.setCache(myCache);
+        assertEquals(myCache, cache.getCache());
+    }
+
+    private Cache getCache() {
+        ApplicationContext ctx = MockApplicationContext.getContext();
+
+        return (Cache) ctx.getBean("eHCacheBackend");
     }
 
     private CasAuthenticationToken getToken() {

+ 24 - 5
core/src/test/java/org/acegisecurity/providers/dao/cache/EhCacheBasedUserCacheTests.java

@@ -19,8 +19,13 @@ import junit.framework.TestCase;
 
 import net.sf.acegisecurity.GrantedAuthority;
 import net.sf.acegisecurity.GrantedAuthorityImpl;
+import net.sf.acegisecurity.MockApplicationContext;
 import net.sf.acegisecurity.providers.dao.User;
 
+import net.sf.ehcache.Cache;
+
+import org.springframework.context.ApplicationContext;
+
 
 /**
  * Tests {@link EhCacheBasedUserCache}.
@@ -51,6 +56,7 @@ public class EhCacheBasedUserCacheTests extends TestCase {
 
     public void testCacheOperation() throws Exception {
         EhCacheBasedUserCache cache = new EhCacheBasedUserCache();
+        cache.setCache(getCache());
         cache.afterPropertiesSet();
 
         // Check it gets stored in the cache
@@ -65,14 +71,27 @@ public class EhCacheBasedUserCacheTests extends TestCase {
         // 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() {
+    public void testStartupDetectsMissingCache() throws Exception {
         EhCacheBasedUserCache cache = new EhCacheBasedUserCache();
-        cache.setMinutesToIdle(15);
-        assertEquals(15, cache.getMinutesToIdle());
+
+        try {
+            cache.afterPropertiesSet();
+            fail("Should have thrown IllegalArgumentException");
+        } catch (IllegalArgumentException expected) {
+            assertTrue(true);
+        }
+
+        Cache myCache = getCache();
+        cache.setCache(myCache);
+        assertEquals(myCache, cache.getCache());
+    }
+
+    private Cache getCache() {
+        ApplicationContext ctx = MockApplicationContext.getContext();
+
+        return (Cache) ctx.getBean("eHCacheBackend");
     }
 
     private User getUser() {

+ 14 - 0
core/src/test/resources/org/acegisecurity/applicationContext.xml

@@ -26,4 +26,18 @@
    <!-- Automatically receives AuthenticationEvent messages from AbstractSecurityInterceptor -->
    <bean id="secureObjectLoggerListener" class="net.sf.acegisecurity.intercept.event.LoggerListener"/>
 
+   <!-- Setup a cache we can use in tests of the caching layer -->
+   <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
+   </bean>  
+
+   <bean id="eHCacheBackend" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
+      <property name="cacheManager">
+         <ref local="cacheManager"/>
+      </property>
+      <property name="cacheName">
+         <value>testingCache</value>
+      </property>
+   </bean>
+
+
 </beans>

+ 36 - 24
doc/docbook/index.xml

@@ -110,36 +110,17 @@
         release. These are:</para>
 
         <itemizedlist spacing="compact">
-          <listitem>
-            <para>Replacing the Ant build with a Maven build. When this
-            happens the <literal>lib</literal> directory will no longer be
-            distributed in ZIP releases or hosted in CVS.</para>
-          </listitem>
-
           <listitem>
             <para>"Remember me" functionality. Some discussion on this can be
             found at
             <literal>http://sourceforge.net/mailarchive/forum.php?thread_id=5177499&amp;forum_id=40659</literal>.</para>
           </listitem>
 
-          <listitem>
-            <para>A sample web application which demonstrates the access
-            control list package.</para>
-          </listitem>
-
           <listitem>
             <para>Implementation of an
             <literal>ObjectDefinitionSource</literal> that retrieves its
             details from a database.</para>
           </listitem>
-
-          <listitem>
-            <para>Deprecation of Acegi Security's various EH-CACHE-based cache
-            implementations. Instead Acegi Security will provide new cache
-            implementations which use Spring Framework's new (currently in
-            CVS) <literal>EhCacheManagerFactoryBean</literal> factory. The
-            deprecated classes may be removed from the 1.0.0 release.</para>
-          </listitem>
         </itemizedlist>
 
         <para>Whilst this list is subject to change and not in any particular
@@ -982,7 +963,7 @@ public aspect DomainObjectInstanceSecurityAspect implements InitializingBean {
         authorities that have been granted to the principal. The principal and
         its credentials are populated by the client code, whilst the granted
         authorities are populated by the
-        <literal>AuthenticationManager</literal>. </para>
+        <literal>AuthenticationManager</literal>.</para>
 
         <para><mediaobject>
             <imageobject role="html">
@@ -1232,10 +1213,30 @@ public aspect DomainObjectInstanceSecurityAspect implements InitializingBean {
   &lt;property name="userCache"&gt;&lt;ref bean="userCache"/&gt;&lt;/property&gt;
 &lt;/bean&gt;
 
+&lt;bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/&gt;
+    
+&lt;bean id="userCacheBackend" class="org.springframework.cache.ehcache.EhCacheFactoryBean"&gt;
+  &lt;property name="cacheManager"&gt;
+    &lt;ref local="cacheManager"/&gt;
+  &lt;/property&gt;
+  &lt;property name="cacheName"&gt;
+    &lt;value&gt;userCache&lt;/value&gt;
+  &lt;/property&gt;
+&lt;/bean&gt;
+   
 &lt;bean id="userCache" class="net.sf.acegisecurity.providers.dao.cache.EhCacheBasedUserCache"&gt;
-  &lt;property name="minutesToIdle"&gt;&lt;value&gt;5&lt;/value&gt;&lt;/property&gt;
+  &lt;property name="cache"&gt;&lt;ref local="userCacheBackend"/&gt;&lt;/property&gt;
 &lt;/bean&gt;</programlisting></para>
 
+        <para>All Acegi Security EH-CACHE implementations (including
+        <literal>EhCacheBasedUserCache</literal>) require an EH-CACHE
+        <literal>Cache</literal> object. The <literal>Cache</literal> object
+        can be obtained from wherever you like, although we recommend you use
+        Spring's factory classes as shown in the above configuration. If using
+        Spring's factory classes, please refer to the Spring documentation for
+        further details on how to optimise the cache storage location, memory
+        usage, eviction policies, timeouts etc.</para>
+
         <para>For a class to be able to provide the
         <literal>DaoAuthenticationProvider</literal> with access to an
         authentication repository, it must implement the
@@ -3415,8 +3416,19 @@ $CATALINA_HOME/bin/startup.sh</programlisting></para>
   &lt;!-- &lt;property name="trustStore"&gt;&lt;value&gt;/some/path/to/your/lib/security/cacerts&lt;/value&gt;&lt;/property&gt; --&gt;
 &lt;/bean&gt;
 
+&lt;bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/&gt;
+    
+&lt;bean id="ticketCacheBackend" class="org.springframework.cache.ehcache.EhCacheFactoryBean"&gt;
+  &lt;property name="cacheManager"&gt;
+    &lt;ref local="cacheManager"/&gt;
+  &lt;/property&gt;
+  &lt;property name="cacheName"&gt;
+    &lt;value&gt;ticketCache&lt;/value&gt;
+  &lt;/property&gt;
+&lt;/bean&gt;
+   
 &lt;bean id="statelessTicketCache" class="net.sf.acegisecurity.providers.cas.cache.EhCacheBasedTicketCache"&gt;
-  &lt;property name="minutesToIdle"&gt;&lt;value&gt;20&lt;/value&gt;&lt;/property&gt;
+  &lt;property name="cache"&gt;&lt;ref local="ticketCacheBackend"/&gt;&lt;/property&gt;
 &lt;/bean&gt;
 
 &lt;bean id="casAuthoritiesPopulator" class="net.sf.acegisecurity.providers.cas.populator.DaoCasAuthoritiesPopulator"&gt;
@@ -3785,7 +3797,7 @@ $CATALINA_HOME/bin/startup.sh</programlisting></para>
         <para>The <literal>net.sf.acegisecurity.acl</literal> package is very
         simple, comprising only a handful of interfaces and a single class, as
         shown in Figure 5. It provides the basic foundation for access control
-        list (ACL) lookups. </para>
+        list (ACL) lookups.</para>
 
         <para><mediaobject>
             <imageobject role="html">
@@ -3847,7 +3859,7 @@ public AclEntry[] getAcls(java.lang.Object domainInstance, Authentication authen
         <title>Integer Masked ACLs</title>
 
         <para>Acegi Security System for Spring includes a production-quality
-        ACL provider implementation, which is shown in Figure 6. </para>
+        ACL provider implementation, which is shown in Figure 6.</para>
 
         <para><mediaobject>
             <imageobject role="html">

+ 1 - 0
doc/xdocs/changes.xml

@@ -49,6 +49,7 @@
       <action dev="benalex" type="update">Improved performance of JBoss container adapter (see reference docs)</action>
       <action dev="benalex" type="update">Made DaoAuthenticationProvider detect null in Authentication.principal</action>
       <action dev="benalex" type="update">Improved JaasAuthenticationProvider startup error detection</action>
+      <action dev="benalex" type="update">Refactored EH-CACHE implementations to use Spring IoC defined caches instead</action>
       <action dev="benalex" type="fix">Fixed AbstractProcessingFilter to use removeAttribute (JRun compatibility)</action>
       <action dev="benalex" type="fix">Fixed GrantedAuthorityEffectiveAclResolver support of UserDetails principals</action>
       <action dev="benalex" type="update">Moved MethodSecurityInterceptor to ...intercept.method.aopalliance package</action>

+ 9 - 0
doc/xdocs/upgrade/upgrade-06-07.html

@@ -34,6 +34,15 @@ applications:
   net.sf.acegisecurity.intercept.method.MethodSecurityInterceptor to
   net.sf.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor.
   A simple find and replace will suffice to update your application contexts.</li>
+
+<li>All of the EH-CACHE cache implementations provided with Acegi Security have
+	now been refactored to use a net.sf.ehcache.Cache obtained from
+	EhCacheManagerFactoryBean, which is included with Spring 1.1.1 and above.
+	See http://opensource.atlassian.com/confluence/spring/display/DISC/Caching+the+result+of+methods+using+Spring+and+EHCache
+	for more about this bean, or the Contacts sample application for how to
+	configure the EH-CACHE implementations provided with Acegi Security.
+	Note the "cache" property is now required, and the old internally-managed
+	cache properties have been removed.</li>
 </ul>
 </body>
 </html>

+ 12 - 1
samples/contacts/src/main/webapp/cas/WEB-INF/applicationContext-acegi-security.xml

@@ -52,8 +52,19 @@
         <!-- <property name="trustStore"><value>/some/path/to/your/lib/security/cacerts</value></property> -->
 	</bean>
 
+    <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/>
+    
+    <bean id="ticketCacheBackend" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
+       <property name="cacheManager">
+          <ref local="cacheManager"/>
+       </property>
+       <property name="cacheName">
+          <value>ticketCache</value>
+       </property>
+    </bean>
+   
 	<bean id="statelessTicketCache" class="net.sf.acegisecurity.providers.cas.cache.EhCacheBasedTicketCache">
-		<property name="minutesToIdle"><value>20</value></property>
+      <property name="cache"><ref local="ticketCacheBackend"/></property>
 	</bean>
 
 	<bean id="casAuthoritiesPopulator" class="net.sf.acegisecurity.providers.cas.populator.DaoCasAuthoritiesPopulator">

+ 12 - 1
samples/contacts/src/main/webapp/filter/WEB-INF/applicationContext-acegi-security.xml

@@ -34,8 +34,19 @@
       <property name="passwordEncoder"><ref local="passwordEncoder"/></property>
    </bean>
 
+   <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/>
+    
+   <bean id="userCacheBackend" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
+      <property name="cacheManager">
+         <ref local="cacheManager"/>
+      </property>
+      <property name="cacheName">
+         <value>userCache</value>
+      </property>
+   </bean>
+   
    <bean id="userCache" class="net.sf.acegisecurity.providers.dao.cache.EhCacheBasedUserCache">
-      <property name="minutesToIdle"><value>5</value></property>
+      <property name="cache"><ref local="userCacheBackend"/></property>
    </bean>
 
    <!-- Automatically receives AuthenticationEvent messages from DaoAuthenticationProvider -->