[SCM] Spring Security: Java libraries that provide security services for the Spring Framework branch, upstream, updated. upstream/3.0.4.RELEASE-1-g6ae0d88

Miguel Landaeta miguel at miguel.cc
Fri May 11 01:54:47 UTC 2012


The following commit has been merged in the upstream branch:
commit 6ae0d888c04a9fe5c3d6f0aad9ae739cd84bb033
Author: Miguel Landaeta <miguel at miguel.cc>
Date:   Tue Aug 23 20:30:02 2011 -0430

    upstream import 3.0.5.RELEASE

diff --git a/dist/spring-security-samples-contacts/META-INF/MANIFEST.MF b/dist/spring-security-aspects/META-INF/MANIFEST.MF
similarity index 100%
rename from dist/spring-security-samples-contacts/META-INF/MANIFEST.MF
rename to dist/spring-security-aspects/META-INF/MANIFEST.MF
diff --git a/dist/spring-security-aspects/META-INF/aop.xml b/dist/spring-security-aspects/META-INF/aop.xml
new file mode 100644
index 0000000..a9d76e8
--- /dev/null
+++ b/dist/spring-security-aspects/META-INF/aop.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+
+    <!--
+        AspectJ load-time weaving config file to install common Spring
+        aspects.
+    -->
+<aspectj>
+
+    <!--
+  <weaver options="-showWeaveInfo"/>
+  -->
+
+    <aspects>
+        <aspect
+            name="org.springframework.security.access.intercept.aspectj.aspect.AnnotationSecurityAspect" />
+    </aspects>
+
+</aspectj>
diff --git a/dist/spring-security-aspects/org/springframework/security/access/intercept/aspectj/aspect/AnnotationSecurityAspect.aj b/dist/spring-security-aspects/org/springframework/security/access/intercept/aspectj/aspect/AnnotationSecurityAspect.aj
new file mode 100644
index 0000000..f219406
--- /dev/null
+++ b/dist/spring-security-aspects/org/springframework/security/access/intercept/aspectj/aspect/AnnotationSecurityAspect.aj
@@ -0,0 +1,76 @@
+package org.springframework.security.access.intercept.aspectj.aspect;
+
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.security.access.annotation.Secured;
+import org.springframework.security.access.prepost.*;
+import org.springframework.security.access.intercept.aspectj.AspectJCallback;
+import org.springframework.security.access.intercept.aspectj.AspectJMethodSecurityInterceptor;
+
+/**
+ * Concrete AspectJ aspect using Spring Security @Secured annotation
+ * for JDK 1.5+.
+ *
+ * <p>
+ * When using this aspect, you <i>must</i> annotate the implementation class
+ * (and/or methods within that class), <i>not</i> the interface (if any) that
+ * the class implements. AspectJ follows Java's rule that annotations on
+ * interfaces are <i>not</i> inherited. This will vary from Spring AOP.
+ *
+ * @author Mike Wiesner
+ * @author Luke Taylor
+ * @since 3.1
+ */
+public aspect AnnotationSecurityAspect implements InitializingBean {
+
+    /**
+     * Matches the execution of any public method in a type with the Secured
+     * annotation, or any subtype of a type with the Secured annotation.
+     */
+    private pointcut executionOfAnyPublicMethodInAtSecuredType() :
+        execution(public * ((@Secured *)+).*(..)) && @this(Secured);
+
+    /**
+     * Matches the execution of any method with the Secured annotation.
+     */
+    private pointcut executionOfSecuredMethod() :
+        execution(* *(..)) && @annotation(Secured);
+
+    /**
+     * Matches the execution of any method with Pre/Post annotations.
+     */
+    private pointcut executionOfPrePostAnnotatedMethod() :
+        execution(* *(..)) && (@annotation(PreAuthorize) || @annotation(PreFilter)
+                || @annotation(PostAuthorize) || @annotation(PostFilter));
+
+    private pointcut securedMethodExecution() :
+        executionOfAnyPublicMethodInAtSecuredType() ||
+        executionOfSecuredMethod() ||
+        executionOfPrePostAnnotatedMethod();
+
+    private AspectJMethodSecurityInterceptor securityInterceptor;
+
+    Object around(): securedMethodExecution() {
+        if (this.securityInterceptor == null) {
+            return proceed();
+        }
+
+        AspectJCallback callback = new AspectJCallback() {
+            public Object proceedWithObject() {
+                return proceed();
+            }
+        };
+
+        return this.securityInterceptor.invoke(thisJoinPoint, callback);
+    }
+
+    public void setSecurityInterceptor(AspectJMethodSecurityInterceptor securityInterceptor) {
+        this.securityInterceptor = securityInterceptor;
+    }
+
+    public void afterPropertiesSet() throws Exception {
+        if (this.securityInterceptor == null) {
+            throw new IllegalArgumentException("securityInterceptor required");
+        }
+    }
+
+}
diff --git a/dist/spring-security-config/org/springframework/security/config/http/HttpFirewallBeanDefinitionParser.java b/dist/spring-security-config/org/springframework/security/config/http/HttpFirewallBeanDefinitionParser.java
index 6f5f134..5565ff2 100644
--- a/dist/spring-security-config/org/springframework/security/config/http/HttpFirewallBeanDefinitionParser.java
+++ b/dist/spring-security-config/org/springframework/security/config/http/HttpFirewallBeanDefinitionParser.java
@@ -21,7 +21,6 @@ import java.util.*;
  */
 public class HttpFirewallBeanDefinitionParser implements BeanDefinitionParser {
 
-    @Override
     public BeanDefinition parse(Element element, ParserContext pc) {
         String ref = element.getAttribute("ref");
 
diff --git a/dist/spring-security-core/org/springframework/security/core/SpringSecurityCoreVersion.java b/dist/spring-security-core/org/springframework/security/core/SpringSecurityCoreVersion.java
index 3607cd3..434d89b 100644
--- a/dist/spring-security-core/org/springframework/security/core/SpringSecurityCoreVersion.java
+++ b/dist/spring-security-core/org/springframework/security/core/SpringSecurityCoreVersion.java
@@ -19,9 +19,10 @@ public class SpringSecurityCoreVersion {
 
         if (springVersion != null) {
             // TODO: Generate version class and information dynamically from a template in the build file
-            logger.info("You are running with Spring Security Core " + springVersion);
+            logger.info("You are running with Spring Security Core " + version);
             if (!springVersion.startsWith("3")) {
-                logger.error("Spring Major version '3' expected, but you are running with version: " + springVersion);
+                logger.error("Spring Major version '3' expected, but you are running with version: "
+                        + springVersion + ". Please check your classpath for unwanted jar files.");
             }
 
             if (springVersion.compareTo("3.0.3") < 0) {
diff --git a/dist/spring-security-samples-contacts/applicationContext-common-authorization.xml b/dist/spring-security-samples-contacts/applicationContext-common-authorization.xml
deleted file mode 100644
index 820a8c3..0000000
--- a/dist/spring-security-samples-contacts/applicationContext-common-authorization.xml
+++ /dev/null
@@ -1,58 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<beans xmlns="http://www.springframework.org/schema/beans"
-    xmlns:security="http://www.springframework.org/schema/security"
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
-                        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.1.xsd">
-
-<!--
-  - Application context containing the ACL beans.
-  -
-  -->
-
-  <!-- ========= ACL SERVICE  DEFINITIONS ========= -->
-
-  <bean id="aclCache" class="org.springframework.security.acls.domain.EhCacheBasedAclCache">
-    <constructor-arg>
-      <bean class="org.springframework.cache.ehcache.EhCacheFactoryBean">
-        <property name="cacheManager">
-          <bean class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/>
-        </property>
-        <property name="cacheName" value="aclCache"/>
-      </bean>
-    </constructor-arg>
-  </bean>
-
-  <bean id="lookupStrategy" class="org.springframework.security.acls.jdbc.BasicLookupStrategy">
-    <constructor-arg ref="dataSource"/>
-    <constructor-arg ref="aclCache"/>
-    <constructor-arg>
-        <bean class="org.springframework.security.acls.domain.AclAuthorizationStrategyImpl">
-            <constructor-arg>
-            <list>
-                <bean class="org.springframework.security.core.authority.GrantedAuthorityImpl">
-                    <constructor-arg value="ROLE_ADMINISTRATOR"/>
-                </bean>
-                <bean class="org.springframework.security.core.authority.GrantedAuthorityImpl">
-                    <constructor-arg value="ROLE_ADMINISTRATOR"/>
-                </bean>
-                <bean class="org.springframework.security.core.authority.GrantedAuthorityImpl">
-                    <constructor-arg value="ROLE_ADMINISTRATOR"/>
-                </bean>
-            </list>
-            </constructor-arg>
-        </bean>
-    </constructor-arg>
-    <constructor-arg>
-      <bean class="org.springframework.security.acls.domain.ConsoleAuditLogger"/>
-    </constructor-arg>
-  </bean>
-
-  <bean id="aclService" class="org.springframework.security.acls.jdbc.JdbcMutableAclService">
-    <constructor-arg ref="dataSource"/>
-    <constructor-arg ref="lookupStrategy"/>
-    <constructor-arg ref="aclCache"/>
-  </bean>
-
-</beans>
diff --git a/dist/spring-security-samples-contacts/applicationContext-common-business.xml b/dist/spring-security-samples-contacts/applicationContext-common-business.xml
deleted file mode 100644
index 6cbfb9a..0000000
--- a/dist/spring-security-samples-contacts/applicationContext-common-business.xml
+++ /dev/null
@@ -1,45 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
-  - Application context containing business beans.
-  -
-  - Used by all artifacts.
-  -
-  -->
-
-<beans xmlns="http://www.springframework.org/schema/beans"
-    xmlns:tx="http://www.springframework.org/schema/tx"
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
-                        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
-
-    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
-        <property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
-        <property name="url" value="jdbc:hsqldb:mem:test"/>
-        <!-- <value>jdbc:hsqldb:hsql://localhost/acl</value> -->
-        <property name="username" value="sa"/>
-        <property name="password" value=""/>
-    </bean>
-
-    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
-        <property name="dataSource" ref="dataSource"/>
-    </bean>
-
-    <tx:annotation-driven transaction-manager="transactionManager" />
-
-    <bean id="dataSourcePopulator" class="sample.contact.DataSourcePopulator">
-        <property name="dataSource" ref="dataSource"/>
-        <property name="mutableAclService" ref="aclService"/>
-        <property name="platformTransactionManager" ref="transactionManager"/>
-    </bean>
-
-    <bean id="contactManager" class="sample.contact.ContactManagerBackend">
-       <property name="contactDao">
-            <bean class="sample.contact.ContactDaoSpring">
-               <property name="dataSource" ref="dataSource"/>
-            </bean>
-        </property>
-        <property name="mutableAclService" ref="aclService"/>
-   </bean>
-
-</beans>
diff --git a/dist/spring-security-samples-contacts/sample/contact/AddDeleteContactController.java b/dist/spring-security-samples-contacts/sample/contact/AddDeleteContactController.java
deleted file mode 100644
index 35e88e0..0000000
--- a/dist/spring-security-samples-contacts/sample/contact/AddDeleteContactController.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package sample.contact;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Controller;
-import org.springframework.validation.BindingResult;
-import org.springframework.validation.Validator;
-import org.springframework.web.bind.WebDataBinder;
-import org.springframework.web.bind.annotation.InitBinder;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.servlet.ModelAndView;
-
-/**
- *
- * @author Luke Taylor
- * @since 3.0
- */
- at Controller
-public class AddDeleteContactController {
-    @Autowired
-    private ContactManager contactManager;
-    private Validator validator = new WebContactValidator();
-
-    /**
-     * Displays the "add contact" form.
-     */
-    @RequestMapping(value="/secure/add.htm", method=RequestMethod.GET)
-    public ModelAndView addContactDisplay() {
-        return new ModelAndView("add", "webContact", new WebContact());
-    }
-
-    @InitBinder
-    public void initBinder(WebDataBinder binder) {
-        System.out.println("A binder for object: " + binder.getObjectName());
-    }
-
-    /**
-     * Handles the submission of the contact form, creating a new instance if
-     * the username and email are valid.
-     */
-    @RequestMapping(value="/secure/add.htm", method=RequestMethod.POST)
-    public String addContact(WebContact form, BindingResult result) {
-        validator.validate(form, result);
-
-        if (result.hasErrors()) {
-            return "add";
-        }
-
-        Contact contact = new Contact(form.getName(), form.getEmail());
-        contactManager.create(contact);
-
-        return "redirect:/secure/index.htm";
-    }
-
-    @RequestMapping(value="/secure/del.htm", method=RequestMethod.GET)
-    public ModelAndView handleRequest(@RequestParam("contactId") int contactId) {
-        Contact contact = contactManager.getById(Long.valueOf(contactId));
-        contactManager.delete(contact);
-
-        return new ModelAndView("deleted", "contact", contact);
-    }
-}
diff --git a/dist/spring-security-samples-contacts/sample/contact/AddPermission.java b/dist/spring-security-samples-contacts/sample/contact/AddPermission.java
deleted file mode 100644
index 6c260fd..0000000
--- a/dist/spring-security-samples-contacts/sample/contact/AddPermission.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/* Copyright 2004, 2005, 2006 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 sample.contact;
-
-import org.springframework.security.acls.domain.BasePermission;
-
-
-/**
- * Model object for add permission use case.
- *
- * @author Ben Alex
- */
-public class AddPermission {
-    //~ Instance fields ================================================================================================
-
-    public Contact contact;
-    public Integer permission = BasePermission.READ.getMask();
-    public String recipient;
-
-    //~ Methods ========================================================================================================
-
-    public Contact getContact() {
-        return contact;
-    }
-
-    public Integer getPermission() {
-        return permission;
-    }
-
-    public String getRecipient() {
-        return recipient;
-    }
-
-    public void setContact(Contact contact) {
-        this.contact = contact;
-    }
-
-    public void setPermission(Integer permission) {
-        this.permission = permission;
-    }
-
-    public void setRecipient(String recipient) {
-        this.recipient = recipient;
-    }
-}
diff --git a/dist/spring-security-samples-contacts/sample/contact/AddPermissionValidator.java b/dist/spring-security-samples-contacts/sample/contact/AddPermissionValidator.java
deleted file mode 100644
index cdea87f..0000000
--- a/dist/spring-security-samples-contacts/sample/contact/AddPermissionValidator.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/* Copyright 2004, 2005, 2006 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 sample.contact;
-
-import org.springframework.security.acls.domain.BasePermission;
-
-import org.springframework.validation.Errors;
-import org.springframework.validation.ValidationUtils;
-import org.springframework.validation.Validator;
-
-
-/**
- * Validates {@link AddPermission}.
- *
- * @author Ben Alex
- */
-public class AddPermissionValidator implements Validator {
-    //~ Methods ========================================================================================================
-
-    @SuppressWarnings("unchecked")
-    public boolean supports(Class clazz) {
-        return clazz.equals(AddPermission.class);
-    }
-
-    public void validate(Object obj, Errors errors) {
-        AddPermission addPermission = (AddPermission) obj;
-
-        ValidationUtils.rejectIfEmptyOrWhitespace(errors, "permission", "err.permission", "Permission is required. *");
-        ValidationUtils.rejectIfEmptyOrWhitespace(errors, "recipient", "err.recipient", "Recipient is required. *");
-
-        if (addPermission.getPermission() != null) {
-            int permission = addPermission.getPermission().intValue();
-
-            if ((permission != BasePermission.ADMINISTRATION.getMask())
-                && (permission != BasePermission.READ.getMask()) && (permission != BasePermission.DELETE.getMask())) {
-                errors.rejectValue("permission", "err.permission.invalid", "The indicated permission is invalid. *");
-            }
-        }
-
-        if (addPermission.getRecipient() != null) {
-            if (addPermission.getRecipient().length() > 100) {
-                errors.rejectValue("recipient", "err.recipient.length",
-                    "The recipient is too long (maximum 100 characters). *");
-            }
-        }
-    }
-}
diff --git a/dist/spring-security-samples-contacts/sample/contact/AdminPermissionController.java b/dist/spring-security-samples-contacts/sample/contact/AdminPermissionController.java
deleted file mode 100644
index 812a41c..0000000
--- a/dist/spring-security-samples-contacts/sample/contact/AdminPermissionController.java
+++ /dev/null
@@ -1,167 +0,0 @@
-package sample.contact;
-
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.MessageSource;
-import org.springframework.context.MessageSourceAware;
-import org.springframework.context.support.MessageSourceAccessor;
-import org.springframework.dao.DataAccessException;
-import org.springframework.security.acls.domain.BasePermission;
-import org.springframework.security.acls.domain.DefaultPermissionFactory;
-import org.springframework.security.acls.domain.ObjectIdentityImpl;
-import org.springframework.security.acls.domain.PermissionFactory;
-import org.springframework.security.acls.domain.PrincipalSid;
-import org.springframework.security.acls.model.Acl;
-import org.springframework.security.acls.model.AclService;
-import org.springframework.security.acls.model.Permission;
-import org.springframework.security.acls.model.Sid;
-import org.springframework.stereotype.Controller;
-import org.springframework.ui.ModelMap;
-import org.springframework.validation.BindingResult;
-import org.springframework.validation.Validator;
-import org.springframework.web.bind.WebDataBinder;
-import org.springframework.web.bind.annotation.InitBinder;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.SessionAttributes;
-import org.springframework.web.servlet.ModelAndView;
-
-/**
- * Web controller to handle <tt>Permission</tt> administration functions - adding and deleting
- * permissions for contacts.
- *
- * @author Luke Taylor
- * @since 3.0
- */
- at Controller
- at SessionAttributes("addPermission")
-public final class AdminPermissionController implements MessageSourceAware{
-    @Autowired
-    private AclService aclService;
-    @Autowired
-    private ContactManager contactManager;
-    private MessageSourceAccessor messages;
-    private Validator addPermissionValidator = new AddPermissionValidator();
-    private PermissionFactory permissionFactory = new DefaultPermissionFactory();
-
-    /**
-     * Displays the permission admin page for a particular contact.
-     */
-    @RequestMapping(value="/secure/adminPermission.htm", method=RequestMethod.GET)
-    public ModelAndView displayAdminPage(@RequestParam("contactId") int contactId) {
-        Contact contact = contactManager.getById(Long.valueOf(contactId));
-        Acl acl = aclService.readAclById(new ObjectIdentityImpl(contact));
-
-        Map<String, Object> model = new HashMap<String, Object>();
-        model.put("contact", contact);
-        model.put("acl", acl);
-
-        return new ModelAndView("adminPermission", "model", model);
-    }
-
-    /**
-     * Displays the "add permission" page for a contact.
-     */
-    @RequestMapping(value="/secure/addPermission.htm", method=RequestMethod.GET)
-    public ModelAndView displayAddPermissionPageForContact(@RequestParam("contactId") int contactId) {
-        Contact contact = contactManager.getById(new Long(contactId));
-
-        AddPermission addPermission = new AddPermission();
-        addPermission.setContact(contact);
-
-        Map<String,Object> model = new HashMap<String,Object>();
-        model.put("addPermission", addPermission);
-        model.put("recipients", listRecipients());
-        model.put("permissions", listPermissions());
-
-        return new ModelAndView("addPermission", model);
-    }
-
-    @InitBinder("addPermission")
-    public void initBinder(WebDataBinder binder) {
-        binder.setAllowedFields(new String[] {"recipient", "permission"});
-    }
-
-    /**
-     * Handles submission of the "add permission" form.
-     */
-    @RequestMapping(value="/secure/addPermission.htm", method=RequestMethod.POST)
-    public String addPermission(AddPermission addPermission, BindingResult result, ModelMap model) {
-        addPermissionValidator.validate(addPermission, result);
-
-        if (result.hasErrors()) {
-            model.put("recipients", listRecipients());
-            model.put("permissions", listPermissions());
-
-            return "addPermission";
-        }
-
-        PrincipalSid sid = new PrincipalSid(addPermission.getRecipient());
-        Permission permission = permissionFactory.buildFromMask(addPermission.getPermission());
-
-        try {
-            contactManager.addPermission(addPermission.getContact(), sid, permission);
-        } catch (DataAccessException existingPermission) {
-            existingPermission.printStackTrace();
-            result.rejectValue("recipient", "err.recipientExistsForContact", "Addition failure.");
-
-            model.put("recipients", listRecipients());
-            model.put("permissions", listPermissions());
-            return "addPermission";
-        }
-
-        return "redirect:/secure/index.htm";
-    }
-
-    /**
-     * Deletes a permission
-     */
-    @RequestMapping(value="/secure/deletePermission.htm")
-    public ModelAndView deletePermission(
-            @RequestParam("contactId") int contactId,
-            @RequestParam("sid") String sid,
-            @RequestParam("permission") int mask) {
-
-        Contact contact = contactManager.getById(new Long(contactId));
-
-        Sid sidObject = new PrincipalSid(sid);
-        Permission permission = permissionFactory.buildFromMask(mask);
-
-        contactManager.deletePermission(contact, sidObject, permission);
-
-        Map<String, Object> model = new HashMap<String, Object>();
-        model.put("contact", contact);
-        model.put("sid", sidObject);
-        model.put("permission", permission);
-
-        return new ModelAndView("deletePermission", "model", model);
-    }
-
-    private Map<Integer, String> listPermissions() {
-        Map<Integer, String> map = new LinkedHashMap<Integer, String>();
-        map.put(Integer.valueOf(BasePermission.ADMINISTRATION.getMask()), messages.getMessage("select.administer", "Administer"));
-        map.put(Integer.valueOf(BasePermission.READ.getMask()), messages.getMessage("select.read", "Read"));
-        map.put(Integer.valueOf(BasePermission.DELETE.getMask()), messages.getMessage("select.delete", "Delete"));
-
-        return map;
-    }
-
-    private Map<String, String> listRecipients() {
-        Map<String, String> map = new LinkedHashMap<String, String>();
-        map.put("", messages.getMessage("select.pleaseSelect", "-- please select --"));
-
-        for (String recipient : contactManager.getAllRecipients()) {
-            map.put(recipient, recipient);
-        }
-
-        return map;
-    }
-
-    public void setMessageSource(MessageSource messageSource) {
-        this.messages = new MessageSourceAccessor(messageSource);
-    }
-}
diff --git a/dist/spring-security-samples-contacts/sample/contact/ClientApplication.java b/dist/spring-security-samples-contacts/sample/contact/ClientApplication.java
deleted file mode 100644
index 4d0207b..0000000
--- a/dist/spring-security-samples-contacts/sample/contact/ClientApplication.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/* Copyright 2004, 2005, 2006 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 sample.contact;
-
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.List;
-import java.util.Map;
-
-import org.springframework.beans.factory.ListableBeanFactory;
-import org.springframework.context.support.FileSystemXmlApplicationContext;
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.util.StopWatch;
-
-
-/**
- * Demonstrates accessing the {@link ContactManager} via remoting protocols.
- * <p>
- * Based on Spring's JPetStore sample, written by Juergen Hoeller.
- *
- * @author Ben Alex
- */
-public class ClientApplication {
-    //~ Instance fields ================================================================================================
-
-    private final ListableBeanFactory beanFactory;
-
-    //~ Constructors ===================================================================================================
-
-    public ClientApplication(ListableBeanFactory beanFactory) {
-        this.beanFactory = beanFactory;
-    }
-
-    //~ Methods ========================================================================================================
-
-    public void invokeContactManager(Authentication authentication, int nrOfCalls) {
-        StopWatch stopWatch = new StopWatch(nrOfCalls + " ContactManager call(s)");
-        Map<String, ContactManager> contactServices = this.beanFactory.getBeansOfType(ContactManager.class, true, true);
-
-        SecurityContextHolder.getContext().setAuthentication(authentication);
-
-        for (String beanName : contactServices.keySet()) {
-            Object object = this.beanFactory.getBean("&" + beanName);
-
-            try {
-                System.out.println("Trying to find setUsername(String) method on: " + object.getClass().getName());
-
-                Method method = object.getClass().getMethod("setUsername", new Class[] {String.class});
-                System.out.println("Found; Trying to setUsername(String) to " + authentication.getPrincipal());
-                method.invoke(object, new Object[] {authentication.getPrincipal()});
-            } catch (NoSuchMethodException ignored) {
-                System.out.println("This client proxy factory does not have a setUsername(String) method");
-            } catch (IllegalAccessException ignored) {
-                ignored.printStackTrace();
-            } catch (InvocationTargetException ignored) {
-                ignored.printStackTrace();
-            }
-
-            try {
-                System.out.println("Trying to find setPassword(String) method on: " + object.getClass().getName());
-
-                Method method = object.getClass().getMethod("setPassword", new Class[] {String.class});
-                method.invoke(object, new Object[] {authentication.getCredentials()});
-                System.out.println("Found; Trying to setPassword(String) to " + authentication.getCredentials());
-            } catch (NoSuchMethodException ignored) {
-                System.out.println("This client proxy factory does not have a setPassword(String) method");
-            } catch (IllegalAccessException ignored) {}
-            catch (InvocationTargetException ignored) {}
-
-            ContactManager remoteContactManager = contactServices.get(beanName);
-            System.out.println("Calling ContactManager '" + beanName + "'");
-
-            stopWatch.start(beanName);
-
-            List<Contact> contacts = null;
-
-            for (int i = 0; i < nrOfCalls; i++) {
-                contacts = remoteContactManager.getAll();
-            }
-
-            stopWatch.stop();
-
-            if (contacts.size() != 0) {
-                for(Contact contact : contacts) {
-                    System.out.println("Contact: " + contact);
-                }
-            } else {
-                System.out.println("No contacts found which this user has permission to");
-            }
-
-            System.out.println();
-            System.out.println(stopWatch.prettyPrint());
-        }
-
-        SecurityContextHolder.clearContext();
-    }
-
-    public static void main(String[] args) {
-        String username = System.getProperty("username", "");
-        String password = System.getProperty("password", "");
-        String nrOfCallsString = System.getProperty("nrOfCalls", "");
-
-        if ("".equals(username) || "".equals(password)) {
-            System.out.println(
-                "You need to specify the user ID to use, the password to use, and optionally a number of calls "
-                + "using the username, password, and nrOfCalls system properties respectively. eg for user rod, "
-                + "use: -Dusername=rod -Dpassword=koala' for a single call per service and "
-                + "use: -Dusername=rod -Dpassword=koala -DnrOfCalls=10 for ten calls per service.");
-            System.exit(-1);
-        } else {
-            int nrOfCalls = 1;
-
-            if (!"".equals(nrOfCallsString)) {
-                nrOfCalls = Integer.parseInt(nrOfCallsString);
-            }
-
-            ListableBeanFactory beanFactory = new FileSystemXmlApplicationContext("clientContext.xml");
-            ClientApplication client = new ClientApplication(beanFactory);
-
-            client.invokeContactManager(new UsernamePasswordAuthenticationToken(username, password), nrOfCalls);
-            System.exit(0);
-        }
-    }
-}
diff --git a/dist/spring-security-samples-contacts/sample/contact/Contact.java b/dist/spring-security-samples-contacts/sample/contact/Contact.java
deleted file mode 100644
index fc1d034..0000000
--- a/dist/spring-security-samples-contacts/sample/contact/Contact.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/* Copyright 2004, 2005, 2006 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 sample.contact;
-
-import java.io.Serializable;
-
-
-/**
- * Represents a contact.
- *
- * @author Ben Alex
- */
-public class Contact implements Serializable {
-    //~ Instance fields ================================================================================================
-
-    private Long id;
-    private String email;
-    private String name;
-
-    //~ Constructors ===================================================================================================
-
-    public Contact(String name, String email) {
-        this.name = name;
-        this.email = email;
-    }
-
-    public Contact() {}
-
-    //~ Methods ========================================================================================================
-
-    /**
-     * @return Returns the email.
-     */
-    public String getEmail() {
-        return email;
-    }
-
-    /**
-     * @return Returns the id.
-     */
-    public Long getId() {
-        return id;
-    }
-
-    /**
-     * @return Returns the name.
-     */
-    public String getName() {
-        return name;
-    }
-
-    /**
-     * @param email The email to set.
-     */
-    public void setEmail(String email) {
-        this.email = email;
-    }
-
-    public void setId(Long id) {
-        this.id = id;
-    }
-
-    /**
-     * @param name The name to set.
-     */
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-        sb.append(super.toString() + ": ");
-        sb.append("Id: " + this.getId() + "; ");
-        sb.append("Name: " + this.getName() + "; ");
-        sb.append("Email: " + this.getEmail());
-
-        return sb.toString();
-    }
-}
diff --git a/dist/spring-security-samples-contacts/sample/contact/ContactDao.java b/dist/spring-security-samples-contacts/sample/contact/ContactDao.java
deleted file mode 100644
index a2d48ca..0000000
--- a/dist/spring-security-samples-contacts/sample/contact/ContactDao.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Copyright 2004, 2005, 2006 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 sample.contact;
-
-import java.util.List;
-
-
-/**
- * Provides access to the application's persistence layer.
- *
- * @author Ben Alex
- */
-public interface ContactDao {
-    //~ Methods ========================================================================================================
-
-    public void create(Contact contact);
-
-    public void delete(Long contactId);
-
-    public List<Contact> findAll();
-
-    public List<String> findAllPrincipals();
-
-    public List<String> findAllRoles();
-
-    public Contact getById(Long id);
-
-    public void update(Contact contact);
-}
diff --git a/dist/spring-security-samples-contacts/sample/contact/ContactDaoSpring.java b/dist/spring-security-samples-contacts/sample/contact/ContactDaoSpring.java
deleted file mode 100644
index fb34121..0000000
--- a/dist/spring-security-samples-contacts/sample/contact/ContactDaoSpring.java
+++ /dev/null
@@ -1,254 +0,0 @@
-/* Copyright 2004, 2005, 2006 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 sample.contact;
-
-import org.springframework.jdbc.core.SqlParameter;
-import org.springframework.jdbc.core.support.JdbcDaoSupport;
-import org.springframework.jdbc.object.MappingSqlQuery;
-import org.springframework.jdbc.object.SqlUpdate;
-
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Types;
-
-import java.util.List;
-
-import javax.sql.DataSource;
-
-
-/**
- * Base implementation of {@link ContactDao} that uses Spring JDBC services.
- *
- * @author Ben Alex
- */
-public class ContactDaoSpring extends JdbcDaoSupport implements ContactDao {
-    //~ Instance fields ================================================================================================
-
-    private ContactDelete contactDelete;
-    private ContactInsert contactInsert;
-    private ContactUpdate contactUpdate;
-    private ContactsAllQuery contactsAllQuery;
-    private ContactsByIdQuery contactsByIdQuery;
-    private PrincipalsAllQuery principalsAllQuery;
-    private RolesAllQuery rolesAllQuery;
-
-    //~ Methods ========================================================================================================
-
-    public void create(Contact contact) {
-        contactInsert.insert(contact);
-    }
-
-    public void delete(Long contactId) {
-        contactDelete.delete(contactId);
-    }
-
-    public List<Contact> findAll() {
-        return contactsAllQuery.execute();
-    }
-
-    public List<String> findAllPrincipals() {
-        return principalsAllQuery.execute();
-    }
-
-    public List<String> findAllRoles() {
-        return rolesAllQuery.execute();
-    }
-
-    public Contact getById(Long id) {
-        List<Contact> list = contactsByIdQuery.execute(id.longValue());
-
-        if (list.size() == 0) {
-            return null;
-        } else {
-            return (Contact) list.get(0);
-        }
-    }
-
-    protected void initDao() throws Exception {
-        contactInsert = new ContactInsert(getDataSource());
-        contactUpdate = new ContactUpdate(getDataSource());
-        contactDelete = new ContactDelete(getDataSource());
-        contactsAllQuery = new ContactsAllQuery(getDataSource());
-        principalsAllQuery = new PrincipalsAllQuery(getDataSource());
-        rolesAllQuery = new RolesAllQuery(getDataSource());
-        contactsByIdQuery = new ContactsByIdQuery(getDataSource());
-    }
-
-    public void update(Contact contact) {
-        contactUpdate.update(contact);
-    }
-
-    //~ Inner Classes ==================================================================================================
-
-    protected class AclObjectIdentityByObjectIdentityQuery extends MappingSqlQuery<Long> {
-        protected AclObjectIdentityByObjectIdentityQuery(DataSource ds) {
-            super(ds, "SELECT id FROM acl_object_identity WHERE object_identity = ?");
-            declareParameter(new SqlParameter(Types.VARCHAR));
-            compile();
-        }
-
-        protected Long mapRow(ResultSet rs, int rownum)
-            throws SQLException {
-            return new Long(rs.getLong("id"));
-        }
-    }
-
-    protected class AclObjectIdentityInsert extends SqlUpdate {
-        protected AclObjectIdentityInsert(DataSource ds) {
-            super(ds, "INSERT INTO acl_object_identity VALUES (?, ?, ?, ?)");
-            declareParameter(new SqlParameter(Types.BIGINT));
-            declareParameter(new SqlParameter(Types.VARCHAR));
-            declareParameter(new SqlParameter(Types.INTEGER));
-            declareParameter(new SqlParameter(Types.VARCHAR));
-            compile();
-        }
-
-        protected int insert(String objectIdentity, Long parentAclObjectIdentity, String aclClass) {
-            Object[] objs = new Object[] {null, objectIdentity, parentAclObjectIdentity, aclClass};
-            super.update(objs);
-
-            return getJdbcTemplate().queryForInt("call identity()");
-        }
-    }
-
-    protected class ContactDelete extends SqlUpdate {
-        protected ContactDelete(DataSource ds) {
-            super(ds, "DELETE FROM contacts WHERE id = ?");
-            declareParameter(new SqlParameter(Types.BIGINT));
-            compile();
-        }
-
-        protected void delete(Long contactId) {
-            super.update(contactId.longValue());
-        }
-    }
-
-    protected class ContactInsert extends SqlUpdate {
-        protected ContactInsert(DataSource ds) {
-            super(ds, "INSERT INTO contacts VALUES (?, ?, ?)");
-            declareParameter(new SqlParameter(Types.BIGINT));
-            declareParameter(new SqlParameter(Types.VARCHAR));
-            declareParameter(new SqlParameter(Types.VARCHAR));
-            compile();
-        }
-
-        protected void insert(Contact contact) {
-            Object[] objs = new Object[] {contact.getId(), contact.getName(), contact.getEmail()};
-            super.update(objs);
-        }
-    }
-
-    protected class ContactUpdate extends SqlUpdate {
-        protected ContactUpdate(DataSource ds) {
-            super(ds, "UPDATE contacts SET contact_name = ?, address = ? WHERE id = ?");
-            declareParameter(new SqlParameter(Types.VARCHAR));
-            declareParameter(new SqlParameter(Types.VARCHAR));
-            declareParameter(new SqlParameter(Types.BIGINT));
-            compile();
-        }
-
-        protected void update(Contact contact) {
-            Object[] objs = new Object[] {contact.getName(), contact.getEmail(), contact.getId()};
-            super.update(objs);
-        }
-    }
-
-    protected class ContactsAllQuery extends MappingSqlQuery<Contact> {
-        protected ContactsAllQuery(DataSource ds) {
-            super(ds, "SELECT id, contact_name, email FROM contacts ORDER BY id");
-            compile();
-        }
-
-        protected Contact mapRow(ResultSet rs, int rownum) throws SQLException {
-            Contact contact = new Contact();
-            contact.setId(new Long(rs.getLong("id")));
-            contact.setName(rs.getString("contact_name"));
-            contact.setEmail(rs.getString("email"));
-
-            return contact;
-        }
-    }
-
-    protected class ContactsByIdQuery extends MappingSqlQuery<Contact> {
-        protected ContactsByIdQuery(DataSource ds) {
-            super(ds, "SELECT id, contact_name, email FROM contacts WHERE id = ? ORDER BY id");
-            declareParameter(new SqlParameter(Types.BIGINT));
-            compile();
-        }
-
-        protected Contact mapRow(ResultSet rs, int rownum) throws SQLException {
-            Contact contact = new Contact();
-            contact.setId(new Long(rs.getLong("id")));
-            contact.setName(rs.getString("contact_name"));
-            contact.setEmail(rs.getString("email"));
-
-            return contact;
-        }
-    }
-
-    protected class PermissionDelete extends SqlUpdate {
-        protected PermissionDelete(DataSource ds) {
-            super(ds, "DELETE FROM acl_permission WHERE ACL_OBJECT_IDENTITY = ? AND RECIPIENT = ?");
-            declareParameter(new SqlParameter(Types.BIGINT));
-            declareParameter(new SqlParameter(Types.VARCHAR));
-            compile();
-        }
-
-        protected void delete(Long aclObjectIdentity, String recipient) {
-            super.update(new Object[] {aclObjectIdentity, recipient});
-        }
-    }
-
-    protected class PermissionInsert extends SqlUpdate {
-        protected PermissionInsert(DataSource ds) {
-            super(ds, "INSERT INTO acl_permission VALUES (?, ?, ?, ?);");
-            declareParameter(new SqlParameter(Types.BIGINT));
-            declareParameter(new SqlParameter(Types.BIGINT));
-            declareParameter(new SqlParameter(Types.VARCHAR));
-            declareParameter(new SqlParameter(Types.INTEGER));
-            compile();
-        }
-
-        protected int insert(Long aclObjectIdentity, String recipient, Integer mask) {
-            Object[] objs = new Object[] {null, aclObjectIdentity, recipient, mask};
-            super.update(objs);
-
-            return getJdbcTemplate().queryForInt("call identity()");
-        }
-    }
-
-    protected class PrincipalsAllQuery extends MappingSqlQuery<String> {
-        protected PrincipalsAllQuery(DataSource ds) {
-            super(ds, "SELECT username FROM users ORDER BY username");
-            compile();
-        }
-
-        protected String mapRow(ResultSet rs, int rownum) throws SQLException {
-            return rs.getString("username");
-        }
-    }
-
-    protected class RolesAllQuery extends MappingSqlQuery<String> {
-        protected RolesAllQuery(DataSource ds) {
-            super(ds, "SELECT DISTINCT authority FROM authorities ORDER BY authority");
-            compile();
-        }
-
-        protected String mapRow(ResultSet rs, int rownum) throws SQLException {
-            return rs.getString("authority");
-        }
-    }
-}
diff --git a/dist/spring-security-samples-contacts/sample/contact/ContactManager.java b/dist/spring-security-samples-contacts/sample/contact/ContactManager.java
deleted file mode 100644
index 15ac69f..0000000
--- a/dist/spring-security-samples-contacts/sample/contact/ContactManager.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/* Copyright 2004, 2005, 2006 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 sample.contact;
-
-import org.springframework.security.access.prepost.PostFilter;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.security.acls.model.Permission;
-import org.springframework.security.acls.model.Sid;
-
-import java.util.List;
-
-
-/**
- * Interface for the application's services layer.
- *
- * @author Ben Alex
- */
-public interface ContactManager {
-    //~ Methods ========================================================================================================
-    @PreAuthorize("hasPermission(#contact, admin)")
-    public void addPermission(Contact contact, Sid recipient, Permission permission);
-
-    @PreAuthorize("hasPermission(#contact, admin)")
-    public void deletePermission(Contact contact, Sid recipient, Permission permission);
-
-    @PreAuthorize("hasRole('ROLE_USER')")
-    public void create(Contact contact);
-
-    @PreAuthorize("hasPermission(#contact, 'delete') or hasPermission(#contact, admin)")
-    public void delete(Contact contact);
-
-    @PreAuthorize("hasRole('ROLE_USER')")
-    @PostFilter("hasPermission(filterObject, 'read') or hasPermission(filterObject, admin)")
-    public List<Contact> getAll();
-
-    @PreAuthorize("hasRole('ROLE_USER')")
-    public List<String> getAllRecipients();
-
-    @PreAuthorize(
-            "hasPermission(#id, 'sample.contact.Contact', read) or " +
-            "hasPermission(#id, 'sample.contact.Contact', admin)")
-    public Contact getById(Long id);
-
-    public Contact getRandomContact();
-}
diff --git a/dist/spring-security-samples-contacts/sample/contact/ContactManagerBackend.java b/dist/spring-security-samples-contacts/sample/contact/ContactManagerBackend.java
deleted file mode 100644
index 051ba22..0000000
--- a/dist/spring-security-samples-contacts/sample/contact/ContactManagerBackend.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/* Copyright 2004, 2005, 2006 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 sample.contact;
-
-
-import org.springframework.security.acls.domain.BasePermission;
-import org.springframework.security.acls.domain.ObjectIdentityImpl;
-import org.springframework.security.acls.domain.PrincipalSid;
-import org.springframework.security.acls.model.AccessControlEntry;
-import org.springframework.security.acls.model.MutableAcl;
-import org.springframework.security.acls.model.MutableAclService;
-import org.springframework.security.acls.model.NotFoundException;
-import org.springframework.security.acls.model.ObjectIdentity;
-import org.springframework.security.acls.model.Permission;
-import org.springframework.security.acls.model.Sid;
-
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.core.userdetails.UserDetails;
-
-import org.springframework.transaction.annotation.Transactional;
-
-import org.springframework.beans.factory.InitializingBean;
-
-import org.springframework.context.support.ApplicationObjectSupport;
-
-import org.springframework.util.Assert;
-
-import java.util.List;
-import java.util.Random;
-
-
-/**
- * Concrete implementation of {@link ContactManager}.
- *
- * @author Ben Alex
- */
- at Transactional
-public class ContactManagerBackend extends ApplicationObjectSupport implements ContactManager, InitializingBean {
-    //~ Instance fields ================================================================================================
-
-    private ContactDao contactDao;
-    private MutableAclService mutableAclService;
-    private int counter = 1000;
-
-    //~ Methods ========================================================================================================
-
-    public void afterPropertiesSet() throws Exception {
-        Assert.notNull(contactDao, "contactDao required");
-        Assert.notNull(mutableAclService, "mutableAclService required");
-    }
-
-    public void addPermission(Contact contact, Sid recipient, Permission permission) {
-        MutableAcl acl;
-        ObjectIdentity oid = new ObjectIdentityImpl(Contact.class, contact.getId());
-
-        try {
-            acl = (MutableAcl) mutableAclService.readAclById(oid);
-        } catch (NotFoundException nfe) {
-            acl = mutableAclService.createAcl(oid);
-        }
-
-        acl.insertAce(acl.getEntries().size(), permission, recipient, true);
-        mutableAclService.updateAcl(acl);
-
-        logger.debug("Added permission " + permission + " for Sid " + recipient + " contact " + contact);
-    }
-
-    public void create(Contact contact) {
-        // Create the Contact itself
-        contact.setId(new Long(counter++));
-        contactDao.create(contact);
-
-        // Grant the current principal administrative permission to the contact
-        addPermission(contact, new PrincipalSid(getUsername()), BasePermission.ADMINISTRATION);
-
-        if (logger.isDebugEnabled()) {
-            logger.debug("Created contact " + contact + " and granted admin permission to recipient " + getUsername());
-        }
-    }
-
-    public void delete(Contact contact) {
-        contactDao.delete(contact.getId());
-
-        // Delete the ACL information as well
-        ObjectIdentity oid = new ObjectIdentityImpl(Contact.class, contact.getId());
-        mutableAclService.deleteAcl(oid, false);
-
-        if (logger.isDebugEnabled()) {
-            logger.debug("Deleted contact " + contact + " including ACL permissions");
-        }
-    }
-
-    public void deletePermission(Contact contact, Sid recipient, Permission permission) {
-        ObjectIdentity oid = new ObjectIdentityImpl(Contact.class, contact.getId());
-        MutableAcl acl = (MutableAcl) mutableAclService.readAclById(oid);
-
-        // Remove all permissions associated with this particular recipient (string equality to KISS)
-        List<AccessControlEntry> entries = acl.getEntries();
-
-        for (int i = 0; i < entries.size(); i++) {
-            if (entries.get(i).getSid().equals(recipient) && entries.get(i).getPermission().equals(permission)) {
-                acl.deleteAce(i);
-            }
-        }
-
-        mutableAclService.updateAcl(acl);
-
-        if (logger.isDebugEnabled()) {
-            logger.debug("Deleted contact " + contact + " ACL permissions for recipient " + recipient);
-        }
-    }
-
-    @Transactional(readOnly=true)
-    public List<Contact> getAll() {
-        logger.debug("Returning all contacts");
-
-        return contactDao.findAll();
-    }
-
-    @Transactional(readOnly=true)
-    public List<String> getAllRecipients() {
-        logger.debug("Returning all recipients");
-
-        List<String> list = contactDao.findAllPrincipals();
-
-        return list;
-    }
-
-    @Transactional(readOnly=true)
-    public Contact getById(Long id) {
-        if (logger.isDebugEnabled()) {
-            logger.debug("Returning contact with id: " + id);
-        }
-
-        return contactDao.getById(id);
-    }
-
-    /**
-     * This is a public method.
-     */
-    @Transactional(readOnly=true)
-    public Contact getRandomContact() {
-        logger.debug("Returning random contact");
-
-        Random rnd = new Random();
-        List<Contact> contacts = contactDao.findAll();
-        int getNumber = rnd.nextInt(contacts.size());
-
-        return contacts.get(getNumber);
-    }
-
-    protected String getUsername() {
-        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
-
-        if (auth.getPrincipal() instanceof UserDetails) {
-            return ((UserDetails) auth.getPrincipal()).getUsername();
-        } else {
-            return auth.getPrincipal().toString();
-        }
-    }
-
-    public void setContactDao(ContactDao contactDao) {
-        this.contactDao = contactDao;
-    }
-
-    public void setMutableAclService(MutableAclService mutableAclService) {
-        this.mutableAclService = mutableAclService;
-    }
-
-    public void update(Contact contact) {
-        contactDao.update(contact);
-
-        logger.debug("Updated contact " + contact);
-    }
-}
diff --git a/dist/spring-security-samples-contacts/sample/contact/DataSourcePopulator.java b/dist/spring-security-samples-contacts/sample/contact/DataSourcePopulator.java
deleted file mode 100644
index 1edeb4f..0000000
--- a/dist/spring-security-samples-contacts/sample/contact/DataSourcePopulator.java
+++ /dev/null
@@ -1,285 +0,0 @@
-/* Copyright 2004, 2005, 2006 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 sample.contact;
-
-import java.util.Random;
-
-import javax.sql.DataSource;
-
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.jdbc.core.JdbcTemplate;
-import org.springframework.security.acls.domain.AclImpl;
-import org.springframework.security.acls.domain.BasePermission;
-import org.springframework.security.acls.domain.ObjectIdentityImpl;
-import org.springframework.security.acls.domain.PrincipalSid;
-import org.springframework.security.acls.model.MutableAcl;
-import org.springframework.security.acls.model.MutableAclService;
-import org.springframework.security.acls.model.ObjectIdentity;
-import org.springframework.security.acls.model.Permission;
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.authority.AuthorityUtils;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.transaction.PlatformTransactionManager;
-import org.springframework.transaction.TransactionStatus;
-import org.springframework.transaction.support.TransactionCallback;
-import org.springframework.transaction.support.TransactionTemplate;
-import org.springframework.util.Assert;
-
-
-/**
- * Populates the Contacts in-memory database with contact and ACL information.
- *
- * @author Ben Alex
- */
-public class DataSourcePopulator implements InitializingBean {
-    //~ Instance fields ================================================================================================
-
-    JdbcTemplate template;
-    private MutableAclService mutableAclService;
-    Random rnd = new Random();
-    TransactionTemplate tt;
-    String[] firstNames = {
-            "Bob", "Mary", "James", "Jane", "Kristy", "Kirsty", "Kate", "Jeni", "Angela", "Melanie", "Kent", "William",
-            "Geoff", "Jeff", "Adrian", "Amanda", "Lisa", "Elizabeth", "Prue", "Richard", "Darin", "Phillip", "Michael",
-            "Belinda", "Samantha", "Brian", "Greg", "Matthew"
-        };
-    String[] lastNames = {
-            "Smith", "Williams", "Jackson", "Rictor", "Nelson", "Fitzgerald", "McAlpine", "Sutherland", "Abbott", "Hall",
-            "Edwards", "Gates", "Black", "Brown", "Gray", "Marwell", "Booch", "Johnson", "McTaggart", "Parklin",
-            "Findlay", "Robinson", "Giugni", "Lang", "Chi", "Carmichael"
-        };
-    private int createEntities = 50;
-
-    //~ Methods ========================================================================================================
-
-    public void afterPropertiesSet() throws Exception {
-        Assert.notNull(mutableAclService, "mutableAclService required");
-        Assert.notNull(template, "dataSource required");
-        Assert.notNull(tt, "platformTransactionManager required");
-
-        // Set a user account that will initially own all the created data
-        Authentication authRequest = new UsernamePasswordAuthenticationToken("rod", "koala",
-                AuthorityUtils.createAuthorityList("ROLE_IGNORED"));
-        SecurityContextHolder.getContext().setAuthentication(authRequest);
-
-        try {
-            template.execute("DROP TABLE CONTACTS");
-            template.execute("DROP TABLE AUTHORITIES");
-            template.execute("DROP TABLE USERS");
-            template.execute("DROP TABLE ACL_ENTRY");
-            template.execute("DROP TABLE ACL_OBJECT_IDENTITY");
-            template.execute("DROP TABLE ACL_CLASS");
-            template.execute("DROP TABLE ACL_SID");
-        } catch(Exception e) {
-            System.out.println("Failed to drop tables: " + e.getMessage());
-        }
-
-        template.execute(
-            "CREATE TABLE ACL_SID(" +
-                    "ID BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 100) NOT NULL PRIMARY KEY," +
-                    "PRINCIPAL BOOLEAN NOT NULL," +
-                    "SID VARCHAR_IGNORECASE(100) NOT NULL," +
-                    "CONSTRAINT UNIQUE_UK_1 UNIQUE(SID,PRINCIPAL));");
-        template.execute(
-            "CREATE TABLE ACL_CLASS(" +
-                    "ID BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 100) NOT NULL PRIMARY KEY," +
-                    "CLASS VARCHAR_IGNORECASE(100) NOT NULL," +
-                    "CONSTRAINT UNIQUE_UK_2 UNIQUE(CLASS));");
-        template.execute(
-            "CREATE TABLE ACL_OBJECT_IDENTITY(" +
-                    "ID BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 100) NOT NULL PRIMARY KEY," +
-                    "OBJECT_ID_CLASS BIGINT NOT NULL," +
-                    "OBJECT_ID_IDENTITY BIGINT NOT NULL," +
-                    "PARENT_OBJECT BIGINT," +
-                    "OWNER_SID BIGINT," +
-                    "ENTRIES_INHERITING BOOLEAN NOT NULL," +
-                    "CONSTRAINT UNIQUE_UK_3 UNIQUE(OBJECT_ID_CLASS,OBJECT_ID_IDENTITY)," +
-                    "CONSTRAINT FOREIGN_FK_1 FOREIGN KEY(PARENT_OBJECT)REFERENCES ACL_OBJECT_IDENTITY(ID)," +
-                    "CONSTRAINT FOREIGN_FK_2 FOREIGN KEY(OBJECT_ID_CLASS)REFERENCES ACL_CLASS(ID)," +
-                    "CONSTRAINT FOREIGN_FK_3 FOREIGN KEY(OWNER_SID)REFERENCES ACL_SID(ID));");
-        template.execute(
-            "CREATE TABLE ACL_ENTRY(" +
-                    "ID BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 100) NOT NULL PRIMARY KEY," +
-                    "ACL_OBJECT_IDENTITY BIGINT NOT NULL,ACE_ORDER INT NOT NULL,SID BIGINT NOT NULL," +
-                    "MASK INTEGER NOT NULL,GRANTING BOOLEAN NOT NULL,AUDIT_SUCCESS BOOLEAN NOT NULL," +
-                    "AUDIT_FAILURE BOOLEAN NOT NULL,CONSTRAINT UNIQUE_UK_4 UNIQUE(ACL_OBJECT_IDENTITY,ACE_ORDER)," +
-                    "CONSTRAINT FOREIGN_FK_4 FOREIGN KEY(ACL_OBJECT_IDENTITY) REFERENCES ACL_OBJECT_IDENTITY(ID)," +
-                    "CONSTRAINT FOREIGN_FK_5 FOREIGN KEY(SID) REFERENCES ACL_SID(ID));");
-
-        template.execute(
-            "CREATE TABLE USERS(USERNAME VARCHAR_IGNORECASE(50) NOT NULL PRIMARY KEY,PASSWORD VARCHAR_IGNORECASE(50) NOT NULL,ENABLED BOOLEAN NOT NULL);");
-        template.execute(
-            "CREATE TABLE AUTHORITIES(USERNAME VARCHAR_IGNORECASE(50) NOT NULL,AUTHORITY VARCHAR_IGNORECASE(50) NOT NULL,CONSTRAINT FK_AUTHORITIES_USERS FOREIGN KEY(USERNAME) REFERENCES USERS(USERNAME));");
-        template.execute("CREATE UNIQUE INDEX IX_AUTH_USERNAME ON AUTHORITIES(USERNAME,AUTHORITY);");
-
-        template.execute(
-            "CREATE TABLE CONTACTS(ID BIGINT NOT NULL PRIMARY KEY, CONTACT_NAME VARCHAR_IGNORECASE(50) NOT NULL, EMAIL VARCHAR_IGNORECASE(50) NOT NULL)");
-
-        /*
-           Passwords encoded using MD5, NOT in Base64 format, with null as salt
-           Encoded password for rod is "koala"
-           Encoded password for dianne is "emu"
-           Encoded password for scott is "wombat"
-           Encoded password for peter is "opal" (but user is disabled)
-           Encoded password for bill is "wombat"
-           Encoded password for bob is "wombat"
-           Encoded password for jane is "wombat"
-
-         */
-        template.execute("INSERT INTO USERS VALUES('rod','a564de63c2d0da68cf47586ee05984d7',TRUE);");
-        template.execute("INSERT INTO USERS VALUES('dianne','65d15fe9156f9c4bbffd98085992a44e',TRUE);");
-        template.execute("INSERT INTO USERS VALUES('scott','2b58af6dddbd072ed27ffc86725d7d3a',TRUE);");
-        template.execute("INSERT INTO USERS VALUES('peter','22b5c9accc6e1ba628cedc63a72d57f8',FALSE);");
-        template.execute("INSERT INTO USERS VALUES('bill','2b58af6dddbd072ed27ffc86725d7d3a',TRUE);");
-        template.execute("INSERT INTO USERS VALUES('bob','2b58af6dddbd072ed27ffc86725d7d3a',TRUE);");
-        template.execute("INSERT INTO USERS VALUES('jane','2b58af6dddbd072ed27ffc86725d7d3a',TRUE);");
-        template.execute("INSERT INTO AUTHORITIES VALUES('rod','ROLE_USER');");
-        template.execute("INSERT INTO AUTHORITIES VALUES('rod','ROLE_SUPERVISOR');");
-        template.execute("INSERT INTO AUTHORITIES VALUES('dianne','ROLE_USER');");
-        template.execute("INSERT INTO AUTHORITIES VALUES('scott','ROLE_USER');");
-        template.execute("INSERT INTO AUTHORITIES VALUES('peter','ROLE_USER');");
-        template.execute("INSERT INTO AUTHORITIES VALUES('bill','ROLE_USER');");
-        template.execute("INSERT INTO AUTHORITIES VALUES('bob','ROLE_USER');");
-        template.execute("INSERT INTO AUTHORITIES VALUES('jane','ROLE_USER');");
-
-        template.execute("INSERT INTO contacts VALUES (1, 'John Smith', 'john at somewhere.com');");
-        template.execute("INSERT INTO contacts VALUES (2, 'Michael Citizen', 'michael at xyz.com');");
-        template.execute("INSERT INTO contacts VALUES (3, 'Joe Bloggs', 'joe at demo.com');");
-        template.execute("INSERT INTO contacts VALUES (4, 'Karen Sutherland', 'karen at sutherland.com');");
-        template.execute("INSERT INTO contacts VALUES (5, 'Mitchell Howard', 'mitchell at abcdef.com');");
-        template.execute("INSERT INTO contacts VALUES (6, 'Rose Costas', 'rose at xyz.com');");
-        template.execute("INSERT INTO contacts VALUES (7, 'Amanda Smith', 'amanda at abcdef.com');");
-        template.execute("INSERT INTO contacts VALUES (8, 'Cindy Smith', 'cindy at smith.com');");
-        template.execute("INSERT INTO contacts VALUES (9, 'Jonathan Citizen', 'jonathan at xyz.com');");
-
-        for (int i = 10; i < createEntities; i++) {
-            String[] person = selectPerson();
-            template.execute("INSERT INTO contacts VALUES (" + i + ", '" + person[2] + "', '" + person[0].toLowerCase()
-                + "@" + person[1].toLowerCase() + ".com');");
-        }
-
-        // Create acl_object_identity rows (and also acl_class rows as needed
-        for (int i = 1; i < createEntities; i++) {
-            final ObjectIdentity objectIdentity = new ObjectIdentityImpl(Contact.class, new Long(i));
-            tt.execute(new TransactionCallback<Object>() {
-                    public Object doInTransaction(TransactionStatus arg0) {
-                        mutableAclService.createAcl(objectIdentity);
-
-                        return null;
-                    }
-                });
-        }
-
-        // Now grant some permissions
-        grantPermissions(1, "rod", BasePermission.ADMINISTRATION);
-        grantPermissions(2, "rod", BasePermission.READ);
-        grantPermissions(3, "rod", BasePermission.READ);
-        grantPermissions(3, "rod", BasePermission.WRITE);
-        grantPermissions(3, "rod", BasePermission.DELETE);
-        grantPermissions(4, "rod", BasePermission.ADMINISTRATION);
-        grantPermissions(4, "dianne", BasePermission.ADMINISTRATION);
-        grantPermissions(4, "scott", BasePermission.READ);
-        grantPermissions(5, "dianne", BasePermission.ADMINISTRATION);
-        grantPermissions(5, "dianne", BasePermission.READ);
-        grantPermissions(6, "dianne", BasePermission.READ);
-        grantPermissions(6, "dianne", BasePermission.WRITE);
-        grantPermissions(6, "dianne", BasePermission.DELETE);
-        grantPermissions(6, "scott", BasePermission.READ);
-        grantPermissions(7, "scott", BasePermission.ADMINISTRATION);
-        grantPermissions(8, "dianne", BasePermission.ADMINISTRATION);
-        grantPermissions(8, "dianne", BasePermission.READ);
-        grantPermissions(8, "scott", BasePermission.READ);
-        grantPermissions(9, "scott", BasePermission.ADMINISTRATION);
-        grantPermissions(9, "scott", BasePermission.READ);
-        grantPermissions(9, "scott", BasePermission.WRITE);
-        grantPermissions(9, "scott", BasePermission.DELETE);
-
-        // Now expressly change the owner of the first ten contacts
-        // We have to do this last, because "rod" owns all of them (doing it sooner would prevent ACL updates)
-        // Note that ownership has no impact on permissions - they're separate (ownership only allows ACl editing)
-        changeOwner(5, "dianne");
-        changeOwner(6, "dianne");
-        changeOwner(7, "scott");
-        changeOwner(8, "dianne");
-        changeOwner(9, "scott");
-
-        String[] users = {"bill", "bob", "jane"}; // don't want to mess around with consistent sample data
-        Permission[] permissions = {BasePermission.ADMINISTRATION, BasePermission.READ, BasePermission.DELETE};
-
-        for (int i = 10; i < createEntities; i++) {
-            String user = users[rnd.nextInt(users.length)];
-            Permission permission = permissions[rnd.nextInt(permissions.length)];
-            grantPermissions(i, user, permission);
-
-            String user2 = users[rnd.nextInt(users.length)];
-            Permission permission2 = permissions[rnd.nextInt(permissions.length)];
-            grantPermissions(i, user2, permission2);
-        }
-
-        SecurityContextHolder.clearContext();
-    }
-
-    private void changeOwner(int contactNumber, String newOwnerUsername) {
-        AclImpl acl = (AclImpl) mutableAclService.readAclById(new ObjectIdentityImpl(Contact.class,
-                    new Long(contactNumber)));
-        acl.setOwner(new PrincipalSid(newOwnerUsername));
-        updateAclInTransaction(acl);
-    }
-
-    public int getCreateEntities() {
-        return createEntities;
-    }
-
-    private void grantPermissions(int contactNumber, String recipientUsername, Permission permission) {
-        AclImpl acl = (AclImpl) mutableAclService.readAclById(new ObjectIdentityImpl(Contact.class,
-                    new Long(contactNumber)));
-        acl.insertAce(acl.getEntries().size(), permission, new PrincipalSid(recipientUsername), true);
-        updateAclInTransaction(acl);
-    }
-
-    private String[] selectPerson() {
-        String firstName = firstNames[rnd.nextInt(firstNames.length)];
-        String lastName = lastNames[rnd.nextInt(lastNames.length)];
-
-        return new String[] {firstName, lastName, firstName + " " + lastName};
-    }
-
-    public void setCreateEntities(int createEntities) {
-        this.createEntities = createEntities;
-    }
-
-    public void setDataSource(DataSource dataSource) {
-        this.template = new JdbcTemplate(dataSource);
-    }
-
-    public void setMutableAclService(MutableAclService mutableAclService) {
-        this.mutableAclService = mutableAclService;
-    }
-
-    public void setPlatformTransactionManager(PlatformTransactionManager platformTransactionManager) {
-        this.tt = new TransactionTemplate(platformTransactionManager);
-    }
-
-    private void updateAclInTransaction(final MutableAcl acl) {
-        tt.execute(new TransactionCallback<Object>() {
-                public Object doInTransaction(TransactionStatus arg0) {
-                    mutableAclService.updateAcl(acl);
-
-                    return null;
-                }
-            });
-    }
-}
diff --git a/dist/spring-security-samples-contacts/sample/contact/IndexController.java b/dist/spring-security-samples-contacts/sample/contact/IndexController.java
deleted file mode 100644
index 72cf8bb..0000000
--- a/dist/spring-security-samples-contacts/sample/contact/IndexController.java
+++ /dev/null
@@ -1,82 +0,0 @@
-package sample.contact;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.access.PermissionEvaluator;
-import org.springframework.security.acls.AclPermissionEvaluator;
-import org.springframework.security.acls.domain.BasePermission;
-import org.springframework.security.acls.model.Permission;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.servlet.ModelAndView;
-
-/**
- * Controller which handles simple, single request use cases such as index pages and contact deletion.
- *
- * @author Luke Taylor
- * @since 3.0
- */
- at Controller
-public class IndexController {
-    private final static Permission[] HAS_DELETE = new Permission[] {BasePermission.DELETE, BasePermission.ADMINISTRATION};
-    private final static Permission[] HAS_ADMIN = new Permission[] {BasePermission.ADMINISTRATION};
-
-    //~ Instance fields ================================================================================================
-
-    @Autowired
-    private ContactManager contactManager;
-    @Autowired
-    private PermissionEvaluator permissionEvaluator;
-
-    //~ Methods ========================================================================================================
-
-    /**
-     * The public index page, used for unauthenticated users.
-     */
-    @RequestMapping(value="/hello.htm", method=RequestMethod.GET)
-    public ModelAndView displayPublicIndex() {
-        Contact rnd = contactManager.getRandomContact();
-
-        return new ModelAndView("hello", "contact", rnd);
-    }
-
-    /**
-     * The index page for an authenticated user.
-     * <p>
-     * This controller displays a list of all the contacts for which the current user has read or admin permissions.
-     * It makes a call to {@link ContactManager#getAll()} which automatically filters the returned list using Spring
-     * Security's ACL mechanism (see the expression annotations on this interface for the details).
-     * <p>
-     * In addition to rendering the list of contacts, the view will also include a "Del" or "Admin" link beside the
-     * contact, depending on whether the user has the corresponding permissions (admin permission is assumed to imply
-     * delete here). This information is stored in the model using the injected {@link PermissionEvaluator} instance.
-     * The implementation should be an instance of {@link AclPermissionEvaluator} or one which is compatible with Spring
-     * Security's ACL module.
-     */
-    @RequestMapping(value="/secure/index.htm", method=RequestMethod.GET)
-    public ModelAndView displayUserContacts() {
-        List<Contact> myContactsList = contactManager.getAll();
-        Map<Contact, Boolean> hasDelete = new HashMap<Contact, Boolean>(myContactsList.size());
-        Map<Contact, Boolean> hasAdmin = new HashMap<Contact, Boolean>(myContactsList.size());
-
-        Authentication user = SecurityContextHolder.getContext().getAuthentication();
-
-        for (Contact contact : myContactsList) {
-            hasDelete.put(contact, Boolean.valueOf(permissionEvaluator.hasPermission(user, contact, HAS_DELETE)));
-            hasAdmin.put(contact, Boolean.valueOf(permissionEvaluator.hasPermission(user, contact, HAS_ADMIN)));
-        }
-
-        Map<String, Object> model = new HashMap<String, Object>();
-        model.put("contacts", myContactsList);
-        model.put("hasDeletePermission", hasDelete);
-        model.put("hasAdminPermission", hasAdmin);
-
-        return new ModelAndView("index", "model", model);
-    }
-}
diff --git a/dist/spring-security-samples-contacts/sample/contact/WebContact.java b/dist/spring-security-samples-contacts/sample/contact/WebContact.java
deleted file mode 100644
index ad3dd32..0000000
--- a/dist/spring-security-samples-contacts/sample/contact/WebContact.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/* Copyright 2004, 2005, 2006 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 sample.contact;
-
-/**
- * An object that represents user-editable sections of a {@link Contact}.
- *
- * @author Ben Alex
- */
-public class WebContact {
-    //~ Instance fields ================================================================================================
-
-    private String email;
-    private String name;
-
-    //~ Methods ========================================================================================================
-
-    public String getEmail() {
-        return email;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setEmail(String email) {
-        this.email = email;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-}
diff --git a/dist/spring-security-samples-contacts/sample/contact/WebContactValidator.java b/dist/spring-security-samples-contacts/sample/contact/WebContactValidator.java
deleted file mode 100644
index c161a98..0000000
--- a/dist/spring-security-samples-contacts/sample/contact/WebContactValidator.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/* Copyright 2004, 2005, 2006 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 sample.contact;
-
-import org.springframework.validation.Errors;
-import org.springframework.validation.Validator;
-
-
-/**
- * Validates {@link WebContact}.
- *
- * @author Ben Alex
- */
-public class WebContactValidator implements Validator {
-    //~ Methods ========================================================================================================
-
-    @SuppressWarnings("unchecked")
-    public boolean supports(Class clazz) {
-        return clazz.equals(WebContact.class);
-    }
-
-    public void validate(Object obj, Errors errors) {
-        WebContact wc = (WebContact) obj;
-
-        if ((wc.getName() == null) || (wc.getName().length() < 3) || (wc.getName().length() > 50)) {
-            errors.rejectValue("name", "err.name", "Name 3-50 characters is required. *");
-        }
-
-        if ((wc.getEmail() == null) || (wc.getEmail().length() < 3) || (wc.getEmail().length() > 50)) {
-            errors.rejectValue("email", "err.email", "Email 3-50 characters is required. *");
-        }
-    }
-}
diff --git a/dist/spring-security-samples-tutorial/META-INF/MANIFEST.MF b/dist/spring-security-samples-tutorial/META-INF/MANIFEST.MF
deleted file mode 100644
index 351fd34..0000000
--- a/dist/spring-security-samples-tutorial/META-INF/MANIFEST.MF
+++ /dev/null
@@ -1,4 +0,0 @@
-Manifest-Version: 1.0
-Archiver-Version: Plexus Archiver
-Created-By: 17.1-b03-307 (Apple Inc.)
-
diff --git a/dist/spring-security-samples-tutorial/applicationContext-business.xml b/dist/spring-security-samples-tutorial/applicationContext-business.xml
deleted file mode 100644
index 3442315..0000000
--- a/dist/spring-security-samples-tutorial/applicationContext-business.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<beans xmlns="http://www.springframework.org/schema/beans"
-    xmlns:security="http://www.springframework.org/schema/security"
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
-http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">
-
-    <bean id="bankDao" class="bigbank.BankDaoStub"/>
-
-    <bean id="seedData" class="bigbank.SeedData">
-        <property name="bankDao" ref="bankDao"/>
-    </bean>
-
-    <bean id="bankService" class="bigbank.BankServiceImpl">
-        <constructor-arg ref="bankDao"/>
-        <!-- This will add a security interceptor to the bean
-        <security:intercept-methods>
-            <security:protect method="bigbank.BankService.*" access="IS_AUTHENTICATED_REMEMBERED" />
-            <security:protect method="bigbank.BankService.post" access="ROLE_TELLER" />
-        </security:intercept-methods>  -->
-    </bean>
-
-</beans>
diff --git a/dist/spring-security-samples-tutorial/bigbank/Account.java b/dist/spring-security-samples-tutorial/bigbank/Account.java
deleted file mode 100644
index 5d3fbee..0000000
--- a/dist/spring-security-samples-tutorial/bigbank/Account.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package bigbank;
-
-/**
- * Note this class does not represent best practice, as we are failing to
- * encapsulate business logic (methods) and state in the domain object.
- * Nevertheless, this demo is intended to reflect what people usually do,
- * as opposed to what they ideally would be doing.
- *
- * @author Ben Alex
- */
-public class Account {
-    private long id = -1;
-    private String holder;
-    private double balance;
-    private double overdraft = 100.00;
-
-    public Account(String holder) {
-        this.holder = holder;
-    }
-
-    public long getId() {
-        return id;
-    }
-
-    public void setId(long id) {
-        this.id = id;
-    }
-
-    public String getHolder() {
-        return holder;
-    }
-
-    public void setHolder(String holder) {
-        this.holder = holder;
-    }
-
-    public double getBalance() {
-        return balance;
-    }
-
-    public void setBalance(double balance) {
-        this.balance = balance;
-    }
-
-    public double getOverdraft() {
-        return overdraft;
-    }
-
-    public void setOverdraft(double overdraft) {
-        this.overdraft = overdraft;
-    }
-
-    public String toString() {
-        return "Account[id=" + id + ",balance=" + balance +",holder=" + holder + ", overdraft=" + overdraft + "]";
-    }
-}
diff --git a/dist/spring-security-samples-tutorial/bigbank/BankDao.java b/dist/spring-security-samples-tutorial/bigbank/BankDao.java
deleted file mode 100644
index 6c22619..0000000
--- a/dist/spring-security-samples-tutorial/bigbank/BankDao.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package bigbank;
-
-public interface BankDao {
-    public Account readAccount(Long id);
-    public void createOrUpdateAccount(Account account);
-    public Account[] findAccounts();
-}
diff --git a/dist/spring-security-samples-tutorial/bigbank/BankDaoStub.java b/dist/spring-security-samples-tutorial/bigbank/BankDaoStub.java
deleted file mode 100644
index 2c6a4ce..0000000
--- a/dist/spring-security-samples-tutorial/bigbank/BankDaoStub.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package bigbank;
-
-import java.util.HashMap;
-import java.util.Map;
-
-public class BankDaoStub implements BankDao {
-    private long id = 0;
-    private Map<Long, Account> accounts = new HashMap<Long, Account>();
-
-    public void createOrUpdateAccount(Account account) {
-        if (account.getId() == -1) {
-            id++;
-            account.setId(id);
-        }
-        accounts.put(new Long(account.getId()), account);
-        System.out.println("SAVE: " + account);
-    }
-
-    public Account[] findAccounts() {
-        Account[] a = accounts.values().toArray(new Account[] {});
-        System.out.println("Returning " + a.length + " account(s):");
-        for (int i = 0; i < a.length; i++) {
-            System.out.println(" > " + a[i]);
-        }
-        return a;
-    }
-
-    public Account readAccount(Long id) {
-        return accounts.get(id);
-    }
-
-}
diff --git a/dist/spring-security-samples-tutorial/bigbank/BankService.java b/dist/spring-security-samples-tutorial/bigbank/BankService.java
deleted file mode 100644
index e9bbce0..0000000
--- a/dist/spring-security-samples-tutorial/bigbank/BankService.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package bigbank;
-
-import org.springframework.security.access.prepost.PreAuthorize;
-
-
-public interface BankService {
-
-    public Account readAccount(Long id);
-
-    public Account[] findAccounts();
-
-    @PreAuthorize(
-            "hasRole('ROLE_SUPERVISOR') or " +
-            "hasRole('ROLE_TELLER') and (#account.balance + #amount >= -#account.overdraft)" )
-    public Account post(Account account, double amount);
-}
diff --git a/dist/spring-security-samples-tutorial/bigbank/BankServiceImpl.java b/dist/spring-security-samples-tutorial/bigbank/BankServiceImpl.java
deleted file mode 100644
index 59ac02b..0000000
--- a/dist/spring-security-samples-tutorial/bigbank/BankServiceImpl.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package bigbank;
-
-import org.aspectj.lang.annotation.Pointcut;
-import org.springframework.util.Assert;
-
-public class BankServiceImpl implements BankService {
-    private BankDao bankDao;
-
-    // Not used unless you declare a <protect-pointcut>
-    @Pointcut("execution(* bigbank.BankServiceImpl.*(..))")
-    public void myPointcut() {}
-
-    public BankServiceImpl(BankDao bankDao) {
-        Assert.notNull(bankDao);
-        this.bankDao = bankDao;
-    }
-
-    public Account[] findAccounts() {
-        return this.bankDao.findAccounts();
-    }
-
-    public Account post(Account account, double amount) {
-        Assert.notNull(account);
-
-        // We read account bank from DAO so it reflects the latest balance
-        Account a = bankDao.readAccount(account.getId());
-        if (account == null) {
-            throw new IllegalArgumentException("Couldn't find requested account");
-        }
-
-        a.setBalance(a.getBalance() + amount);
-        bankDao.createOrUpdateAccount(a);
-        return a;
-    }
-
-    public Account readAccount(Long id) {
-        return bankDao.readAccount(id);
-    }
-}
diff --git a/dist/spring-security-samples-tutorial/bigbank/SeedData.java b/dist/spring-security-samples-tutorial/bigbank/SeedData.java
deleted file mode 100644
index 6eaf6ec..0000000
--- a/dist/spring-security-samples-tutorial/bigbank/SeedData.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package bigbank;
-
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.util.Assert;
-
-public class SeedData implements InitializingBean{
-    private BankDao bankDao;
-
-    public void afterPropertiesSet() throws Exception {
-        Assert.notNull(bankDao);
-        bankDao.createOrUpdateAccount(new Account("rod"));
-        bankDao.createOrUpdateAccount(new Account("dianne"));
-        bankDao.createOrUpdateAccount(new Account("scott"));
-        bankDao.createOrUpdateAccount(new Account("peter"));
-    }
-
-    public void setBankDao(BankDao bankDao) {
-        this.bankDao = bankDao;
-    }
-
-}
diff --git a/dist/spring-security-samples-tutorial/bigbank/web/ListAccounts.java b/dist/spring-security-samples-tutorial/bigbank/web/ListAccounts.java
deleted file mode 100644
index ac31e1a..0000000
--- a/dist/spring-security-samples-tutorial/bigbank/web/ListAccounts.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package bigbank.web;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.springframework.util.Assert;
-import org.springframework.web.servlet.ModelAndView;
-import org.springframework.web.servlet.mvc.Controller;
-
-import bigbank.BankService;
-
-public class ListAccounts implements Controller {
-
-    private BankService bankService;
-
-    public ListAccounts(BankService bankService) {
-        Assert.notNull(bankService);
-        this.bankService = bankService;
-    }
-
-    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
-        // Security check (this is unnecessary if Spring Security is performing the authorization)
-//        if (request.getUserPrincipal() == null) {
-//            throw new AuthenticationCredentialsNotFoundException("You must login to view the account list (Spring Security message)"); // only for Spring Security managed authentication
-//        }
-
-        // Actual business logic
-        ModelAndView mav = new ModelAndView("listAccounts");
-        mav.addObject("accounts", bankService.findAccounts());
-        return mav;
-    }
-
-}
diff --git a/dist/spring-security-samples-tutorial/bigbank/web/PostAccounts.java b/dist/spring-security-samples-tutorial/bigbank/web/PostAccounts.java
deleted file mode 100644
index 8caa906..0000000
--- a/dist/spring-security-samples-tutorial/bigbank/web/PostAccounts.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package bigbank.web;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.springframework.util.Assert;
-import org.springframework.web.bind.ServletRequestUtils;
-import org.springframework.web.servlet.ModelAndView;
-import org.springframework.web.servlet.mvc.Controller;
-
-import bigbank.Account;
-import bigbank.BankService;
-
-public class PostAccounts implements Controller {
-
-    private BankService bankService;
-
-    public PostAccounts(BankService bankService) {
-        Assert.notNull(bankService);
-        this.bankService = bankService;
-    }
-
-    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
-        // Security check (this is unnecessary if Spring Security is performing the authorization)
-//        if (!request.isUserInRole("ROLE_TELLER")) {
-//            throw new AccessDeniedException("You must be a teller to post transactions (Spring Security message)");
-//        }
-
-        // Actual business logic
-        Long id = ServletRequestUtils.getRequiredLongParameter(request, "id");
-        Double amount = ServletRequestUtils.getRequiredDoubleParameter(request, "amount");
-        Account a = bankService.readAccount(id);
-        bankService.post(a, amount);
-
-        return new ModelAndView("redirect:listAccounts.html");
-    }
-
-}
diff --git a/dist/spring-security-web/org/springframework/security/web/FilterChainProxy.java b/dist/spring-security-web/org/springframework/security/web/FilterChainProxy.java
index 1f826ad..8f4e564 100644
--- a/dist/spring-security-web/org/springframework/security/web/FilterChainProxy.java
+++ b/dist/spring-security-web/org/springframework/security/web/FilterChainProxy.java
@@ -158,6 +158,8 @@ public class FilterChainProxy extends GenericFilterBean {
                 logger.debug(url + (filters == null ? " has no matching filters" : " has an empty filter list"));
             }
 
+            fwRequest.reset();
+
             chain.doFilter(fwRequest, fwResponse);
 
             return;
diff --git a/dist/spring-security-web/org/springframework/security/web/context/HttpSessionSecurityContextRepository.java b/dist/spring-security-web/org/springframework/security/web/context/HttpSessionSecurityContextRepository.java
index 89521f3..e0cbee4 100644
--- a/dist/spring-security-web/org/springframework/security/web/context/HttpSessionSecurityContextRepository.java
+++ b/dist/spring-security-web/org/springframework/security/web/context/HttpSessionSecurityContextRepository.java
@@ -10,6 +10,7 @@ import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.springframework.security.authentication.AuthenticationTrustResolver;
 import org.springframework.security.authentication.AuthenticationTrustResolverImpl;
+import org.springframework.security.core.Authentication;
 import org.springframework.security.core.context.SecurityContext;
 import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.security.core.context.SecurityContextHolderStrategy;
@@ -328,23 +329,31 @@ public class HttpSessionSecurityContextRepository implements SecurityContextRepo
          */
         @Override
         protected void saveContext(SecurityContext context) {
+            final Authentication authentication = context.getAuthentication();
+            HttpSession httpSession = request.getSession(false);
+
             // See SEC-776
-            if (authenticationTrustResolver.isAnonymous(context.getAuthentication())) {
+            if (authentication == null || authenticationTrustResolver.isAnonymous(authentication)) {
                 if (logger.isDebugEnabled()) {
-                    logger.debug("SecurityContext contents are anonymous - context will not be stored in HttpSession. ");
+                    logger.debug("SecurityContext is empty or anonymous - context will not be stored in HttpSession. ");
+                }
+
+                if (httpSession != null) {
+                    // SEC-1587 A non-anonymous context may still be in the session
+                    httpSession.removeAttribute(SPRING_SECURITY_CONTEXT_KEY);
                 }
                 return;
             }
 
-            HttpSession httpSession = request.getSession(false);
-
             if (httpSession == null) {
                 httpSession = createNewSessionIfAllowed(context);
             }
 
             // If HttpSession exists, store current SecurityContextHolder contents but only if
             // the SecurityContext has actually changed (see JIRA SEC-37)
-            if (httpSession != null && context.hashCode() != contextHashBeforeChainExecution) {
+            // We also check that the session contains the context, in case a new session has been created (SEC-1561)
+            if (httpSession != null && (context.hashCode() != contextHashBeforeChainExecution ||
+                    httpSession.getAttribute(SPRING_SECURITY_CONTEXT_KEY) == null)) {
                 httpSession.setAttribute(SPRING_SECURITY_CONTEXT_KEY, context);
 
                 if (logger.isDebugEnabled()) {
diff --git a/dist/spring-security-web/org/springframework/security/web/firewall/RequestWrapper.java b/dist/spring-security-web/org/springframework/security/web/firewall/RequestWrapper.java
index 1c6e25d..df2f0b6 100644
--- a/dist/spring-security-web/org/springframework/security/web/firewall/RequestWrapper.java
+++ b/dist/spring-security-web/org/springframework/security/web/firewall/RequestWrapper.java
@@ -1,6 +1,12 @@
 package org.springframework.security.web.firewall;
 
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
+
+import java.io.IOException;
 import java.util.*;
 
 /**
@@ -94,7 +100,44 @@ final class RequestWrapper extends FirewalledRequest {
         return stripPaths ? strippedServletPath : super.getServletPath();
     }
 
+    @Override
+    public RequestDispatcher getRequestDispatcher(String path) {
+        return this.stripPaths ? new FirewalledRequestAwareRequestDispatcher(path) : super.getRequestDispatcher(path);
+    }
+
     public void reset() {
         this.stripPaths = false;
     }
-}
+
+    /**
+     * Ensures {@link FirewalledRequest#reset()} is called prior to performing a forward. It then delegates work to the
+     * {@link RequestDispatcher} from the original {@link HttpServletRequest}.
+     *
+     * @author Rob Winch
+     */
+    private class FirewalledRequestAwareRequestDispatcher implements RequestDispatcher {
+        private final String path;
+
+        /**
+         *
+         * @param path the {@code path} that will be used to obtain the delegate {@link RequestDispatcher} from the
+         * original {@link HttpServletRequest}.
+         */
+        public FirewalledRequestAwareRequestDispatcher(String path) {
+            this.path = path;
+        }
+
+        public void forward(ServletRequest request, ServletResponse response) throws ServletException, IOException {
+            reset();
+            getDelegateDispatcher().forward(request, response);
+        }
+
+        public void include(ServletRequest request, ServletResponse response) throws ServletException, IOException {
+            getDelegateDispatcher().include(request, response);
+        }
+
+        private RequestDispatcher getDelegateDispatcher() {
+            return RequestWrapper.super.getRequestDispatcher(path);
+        }
+    }
+}
\ No newline at end of file
diff --git a/dist/spring-security-web/org/springframework/security/web/savedrequest/DefaultSavedRequest.java b/dist/spring-security-web/org/springframework/security/web/savedrequest/DefaultSavedRequest.java
index ef08206..b759aaf 100644
--- a/dist/spring-security-web/org/springframework/security/web/savedrequest/DefaultSavedRequest.java
+++ b/dist/spring-security-web/org/springframework/security/web/savedrequest/DefaultSavedRequest.java
@@ -15,18 +15,6 @@
 
 package org.springframework.security.web.savedrequest;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.TreeMap;
-
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletRequest;
-
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.springframework.security.web.PortResolver;
@@ -34,19 +22,27 @@ import org.springframework.security.web.WebAttributes;
 import org.springframework.security.web.util.UrlUtils;
 import org.springframework.util.Assert;
 
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import java.util.*;
 
 /**
- * Represents central information from a <code>HttpServletRequest</code>.<p>This class is used by {@link
- * org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter} and {@link org.springframework.security.web.savedrequest.SavedRequestAwareWrapper} to
+ * Represents central information from a <code>HttpServletRequest</code>.
+ * <p>
+ * This class is used by {@link org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter}
+ * and {@link org.springframework.security.web.savedrequest.SavedRequestAwareWrapper} to
  * reproduce the request after successful authentication. An instance of this class is stored at the time of an
- * authentication exception by {@link org.springframework.security.web.access.ExceptionTranslationFilter}.</p>
- * <p><em>IMPLEMENTATION NOTE</em>: It is assumed that this object is accessed only from the context of a single
- * thread, so no synchronization around internal collection classes is performed.</p>
- * <p>This class is based on code in Apache Tomcat.</p>
+ * authentication exception by {@link org.springframework.security.web.access.ExceptionTranslationFilter}.
+ * <p>
+ * <em>IMPLEMENTATION NOTE</em>: It is assumed that this object is accessed only from the context of a single
+ * thread, so no synchronization around internal collection classes is performed.
+ * <p>
+ * This class is based on code in Apache Tomcat.
  *
  * @author Craig McClanahan
  * @author Andrey Grebnev
  * @author Ben Alex
+ * @author Luke Taylor
  */
 public class DefaultSavedRequest implements SavedRequest {
     //~ Static fields/initializers =====================================================================================
@@ -59,23 +55,24 @@ public class DefaultSavedRequest implements SavedRequest {
     public static final String SPRING_SECURITY_SAVED_REQUEST_KEY = WebAttributes.SAVED_REQUEST;
 
     private static final String HEADER_IF_NONE_MATCH = "If-None-Match";
+    private static final String HEADER_IF_MODIFIED_SINCE = "If-Modified-Since";
 
     //~ Instance fields ================================================================================================
 
-    private ArrayList<SavedCookie> cookies = new ArrayList<SavedCookie>();
-    private ArrayList<Locale> locales = new ArrayList<Locale>();
-    private Map<String, List<String>> headers = new TreeMap<String, List<String>>(String.CASE_INSENSITIVE_ORDER);
-    private Map<String, String[]> parameters = new TreeMap<String, String[]>(String.CASE_INSENSITIVE_ORDER);
-    private String contextPath;
-    private String method;
-    private String pathInfo;
-    private String queryString;
-    private String requestURI;
-    private String requestURL;
-    private String scheme;
-    private String serverName;
-    private String servletPath;
-    private int serverPort;
+    private final ArrayList<SavedCookie> cookies = new ArrayList<SavedCookie>();
+    private final ArrayList<Locale> locales = new ArrayList<Locale>();
+    private final Map<String, List<String>> headers = new TreeMap<String, List<String>>(String.CASE_INSENSITIVE_ORDER);
+    private final Map<String, String[]> parameters = new TreeMap<String, String[]>(String.CASE_INSENSITIVE_ORDER);
+    private final String contextPath;
+    private final String method;
+    private final String pathInfo;
+    private final String queryString;
+    private final String requestURI;
+    private final String requestURL;
+    private final String scheme;
+    private final String serverName;
+    private final String servletPath;
+    private final int serverPort;
 
     //~ Constructors ===================================================================================================
 
@@ -98,8 +95,8 @@ public class DefaultSavedRequest implements SavedRequest {
 
         while (names.hasMoreElements()) {
             String name = names.nextElement();
-            // Skip If-None-Match header. SEC-1412.
-            if (HEADER_IF_NONE_MATCH.equalsIgnoreCase(name)) {
+            // Skip If-Modified-Since and If-None-Match header. SEC-1412, SEC-1624.
+            if (HEADER_IF_MODIFIED_SINCE.equalsIgnoreCase(name) || HEADER_IF_NONE_MATCH.equalsIgnoreCase(name)) {
                 continue;
             }
             Enumeration<String> values = request.getHeaders(name);
@@ -195,8 +192,7 @@ public class DefaultSavedRequest implements SavedRequest {
             return false;
         }
 
-        if (!propertyEquals("serverPort", new Integer(this.serverPort), new Integer(portResolver.getServerPort(request))))
-        {
+        if (!propertyEquals("serverPort", new Integer(this.serverPort), new Integer(portResolver.getServerPort(request)))) {
             return false;
         }
 
diff --git a/docs/reference/preauth.html b/docs/reference/preauth.html
index f410070..98bae7c 100644
--- a/docs/reference/preauth.html
+++ b/docs/reference/preauth.html
@@ -105,7 +105,7 @@
           potentially choose any username they wished. </p></td></tr></table></div><div class="section" title="Siteminder Example Configuration"><div class="titlepage"><div><div><h4 class="title"><a name="d0e5670"></a>Siteminder Example Configuration</h4></div></div></div><p> A typical configuration using this filter would look like this: </p><pre class="programlisting">
   <security:http>
     <!-- Additional http configuration omitted -->
-    <security:custom-filter ref="siteminderFilter" />
+    <security:custom-filter position="PRE_AUTH_FILTER" ref="siteminderFilter" />
   </security:http>
 
     <bean id="siteminderFilter" class=
diff --git a/docs/reference/springsecurity-single.html b/docs/reference/springsecurity-single.html
index 4686f80..571b4f5 100644
--- a/docs/reference/springsecurity-single.html
+++ b/docs/reference/springsecurity-single.html
@@ -8,7 +8,7 @@ var pageTracker = _gat._getTracker("UA-2728886-3");
 pageTracker._setDomainName("none");
 pageTracker._setAllowLinker(true);
 pageTracker._trackPageview();
-</script><!--End Google Analytics code--></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="book" title="Spring Security"><div class="titlepage"><div><div><h1 class="title"><a name="spring-security-reference-guide"></a>Spring Security</h1></div><div><h2 class="subtitle">Reference Documentation</h2></div><div><div class="authorgroup"><div class="author"><h3 class="author">Ben Alex</h3></div><div class="author"><h3 class="author">Luke Taylor</h3></div></div></div><div><p class="releaseinfo">3.0.4.RELEASE</p></div></div><hr></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="preface"><a href="#preface">Preface</a></span></dt><dt><span class="part"><a href="#getting-started">I. Getting Started</a></span></dt><dd><dl><dt><span class="chapter"><a href="#introduction">1. Introduction</a></span></dt><dd><dl><dt><span class="section"><a href="#what-is-acegi-security">1.1. What is Spring Security?</a></span></dt><dt><span class="section"><a href="#history">1.2. History</a></span></dt><dt><span class="section"><a href="#release-numbering">1.3. Release Numbering</a></span></dt><dt><span class="section"><a href="#get-spring-security">1.4. Getting Spring Security</a></span></dt><dd><dl><dt><span class="section"><a href="#modules">1.4.1. Project Modules</a></span></dt><dt><span class="section"><a href="#get-source">1.4.2. Checking out the Source</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="#ns-config">2. Security Namespace Configuration</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e344">2.1. Introduction</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e382">2.1.1. Design of the Namespace</a></span></dt></dl></dd><dt><span class="section"><a href="#ns-getting-started">2.2. Getting Started with Security Namespace Configuration</a></span></dt><dd><dl><dt><span class="section"><a href="#ns-web-xml">2.2.1. <code class="literal">web.xml</code> Configuration</a></span></dt><dt><span class="section"><a href="#ns-minimal">2.2.2. A Minimal <code class="literal"><http></code> Configuration</a></span></dt><dt><span class="section"><a href="#ns-auth-providers">2.2.3. Using other Authentication Providers</a></span></dt></dl></dd><dt><span class="section"><a href="#ns-web-advanced">2.3. Advanced Web Features</a></span></dt><dd><dl><dt><span class="section"><a href="#ns-remember-me">2.3.1. Remember-Me Authentication</a></span></dt><dt><span class="section"><a href="#ns-requires-channel">2.3.2. Adding HTTP/HTTPS Channel Security</a></span></dt><dt><span class="section"><a href="#ns-session-mgmt">2.3.3. Session Management</a></span></dt><dt><span class="section"><a href="#ns-openid">2.3.4. OpenID Support</a></span></dt><dt><span class="section"><a href="#ns-custom-filters">2.3.5. Adding in Your Own Filters</a></span></dt></dl></dd><dt><span class="section"><a href="#ns-method-security">2.4. Method Security</a></span></dt><dd><dl><dt><span class="section"><a href="#ns-global-method">2.4.1. The <code class="literal"><global-method-security></code> Element</a></span></dt></dl></dd><dt><span class="section"><a href="#ns-access-manager">2.5. The Default AccessDecisionManager</a></span></dt><dd><dl><dt><span class="section"><a href="#ns-custom-access-mgr">2.5.1. Customizing the AccessDecisionManager</a></span></dt></dl></dd><dt><span class="section"><a href="#ns-auth-manager">2.6. The Authentication Manager and the Namespace</a></span></dt></dl></dd><dt><span class="chapter"><a href="#sample-apps">3. Sample Applications</a></span></dt><dd><dl><dt><span class="section"><a href="#tutorial-sample">3.1. Tutorial Sample</a></span></dt><dt><span class="section"><a href="#contacts-sample">3.2. Contacts</a></span></dt><dt><span class="section"><a href="#ldap-sample">3.3. LDAP Sample</a></span></dt><dt><span class="section"><a href="#cas-sample">3.4. CAS Sample</a></span></dt><dt><span class="section"><a href="#preauth-sample">3.5. Pre-Authentication Sample</a></span></dt></dl></dd><dt><span class="chapter"><a href="#community">4. Spring Security Community</a></span></dt><dd><dl><dt><span class="section"><a href="#jira">4.1. Issue Tracking</a></span></dt><dt><span class="section"><a href="#becoming-involved">4.2. Becoming Involved</a></span></dt><dt><span class="section"><a href="#further-info">4.3. Further Information</a></span></dt></dl></dd></dl></dd><dt><span class="part"><a href="#overall-architecture">II. Architecture and Implementation</a></span></dt><dd><dl><dt><span class="chapter"><a href="#technical-overview">5. Technical Overview</a></span></dt><dd><dl><dt><span class="section"><a href="#runtime-environment">5.1. Runtime Environment</a></span></dt><dt><span class="section"><a href="#core-components">5.2. Core Components</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e1518">5.2.1.  SecurityContextHolder, SecurityContext and Authentication Objects </a></span></dt><dt><span class="section"><a href="#d0e1588">5.2.2. The UserDetailsService</a></span></dt><dt><span class="section"><a href="#tech-granted-authority">5.2.3. GrantedAuthority</a></span></dt><dt><span class="section"><a href="#d0e1709">5.2.4. Summary</a></span></dt></dl></dd><dt><span class="section"><a href="#tech-intro-authentication">5.3. Authentication</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e1765">5.3.1. What is authentication in Spring Security?</a></span></dt><dt><span class="section"><a href="#d0e1835">5.3.2. Setting the SecurityContextHolder Contents Directly</a></span></dt></dl></dd><dt><span class="section"><a href="#tech-intro-web-authentication">5.4. Authentication in a Web Application</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e1917">5.4.1. ExceptionTranslationFilter</a></span></dt><dt><span class="section"><a href="#tech-intro-auth-entry-point">5.4.2. AuthenticationEntryPoint</a></span></dt><dt><span class="section"><a href="#d0e1947">5.4.3. Authentication Mechanism</a></span></dt><dt><span class="section"><a href="#tech-intro-sec-context-persistence">5.4.4. Storing the <code class="interfacename">SecurityContext</code> between requests</a></span></dt></dl></dd><dt><span class="section"><a href="#tech-intro-access-control">5.5. Access-Control (Authorization) in Spring Security</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e2068">5.5.1. Security and AOP Advice</a></span></dt><dt><span class="section"><a href="#secure-objects">5.5.2. Secure Objects and the <code class="classname">AbstractSecurityInterceptor</code></a></span></dt></dl></dd><dt><span class="section"><a href="#localization">5.6. Localization</a></span></dt></dl></dd><dt><span class="chapter"><a href="#core-services">6. Core Services</a></span></dt><dd><dl><dt><span class="section"><a href="#core-services-authentication-manager">6.1. The <code class="interfacename">AuthenticationManager</code>,
+</script><!--End Google Analytics code--></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="book" title="Spring Security"><div class="titlepage"><div><div><h1 class="title"><a name="spring-security-reference-guide"></a>Spring Security</h1></div><div><h2 class="subtitle">Reference Documentation</h2></div><div><div class="authorgroup"><div class="author"><h3 class="author">Ben Alex</h3></div><div class="author"><h3 class="author">Luke Taylor</h3></div></div></div><div><p class="releaseinfo">3.0.5.RELEASE</p></div></div><hr></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="preface"><a href="#preface">Preface</a></span></dt><dt><span class="part"><a href="#getting-started">I. Getting Started</a></span></dt><dd><dl><dt><span class="chapter"><a href="#introduction">1. Introduction</a></span></dt><dd><dl><dt><span class="section"><a href="#what-is-acegi-security">1.1. What is Spring Security?</a></span></dt><dt><span class="section"><a href="#history">1.2. History</a></span></dt><dt><span class="section"><a href="#release-numbering">1.3. Release Numbering</a></span></dt><dt><span class="section"><a href="#get-spring-security">1.4. Getting Spring Security</a></span></dt><dd><dl><dt><span class="section"><a href="#modules">1.4.1. Project Modules</a></span></dt><dt><span class="section"><a href="#get-source">1.4.2. Checking out the Source</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="#ns-config">2. Security Namespace Configuration</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e344">2.1. Introduction</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e382">2.1.1. Design of the Namespace</a></span></dt></dl></dd><dt><span class="section"><a href="#ns-getting-started">2.2. Getting Started with Security Namespace Configuration</a></span></dt><dd><dl><dt><span class="section"><a href="#ns-web-xml">2.2.1. <code class="literal">web.xml</code> Configuration</a></span></dt><dt><span class="section"><a href="#ns-minimal">2.2.2. A Minimal <code class="literal"><http></code> Configuration</a></span></dt><dt><span class="section"><a href="#ns-auth-providers">2.2.3. Using other Authentication Providers</a></span></dt></dl></dd><dt><span class="section"><a href="#ns-web-advanced">2.3. Advanced Web Features</a></span></dt><dd><dl><dt><span class="section"><a href="#ns-remember-me">2.3.1. Remember-Me Authentication</a></span></dt><dt><span class="section"><a href="#ns-requires-channel">2.3.2. Adding HTTP/HTTPS Channel Security</a></span></dt><dt><span class="section"><a href="#ns-session-mgmt">2.3.3. Session Management</a></span></dt><dt><span class="section"><a href="#ns-openid">2.3.4. OpenID Support</a></span></dt><dt><span class="section"><a href="#ns-custom-filters">2.3.5. Adding in Your Own Filters</a></span></dt></dl></dd><dt><span class="section"><a href="#ns-method-security">2.4. Method Security</a></span></dt><dd><dl><dt><span class="section"><a href="#ns-global-method">2.4.1. The <code class="literal"><global-method-security></code> Element</a></span></dt></dl></dd><dt><span class="section"><a href="#ns-access-manager">2.5. The Default AccessDecisionManager</a></span></dt><dd><dl><dt><span class="section"><a href="#ns-custom-access-mgr">2.5.1. Customizing the AccessDecisionManager</a></span></dt></dl></dd><dt><span class="section"><a href="#ns-auth-manager">2.6. The Authentication Manager and the Namespace</a></span></dt></dl></dd><dt><span class="chapter"><a href="#sample-apps">3. Sample Applications</a></span></dt><dd><dl><dt><span class="section"><a href="#tutorial-sample">3.1. Tutorial Sample</a></span></dt><dt><span class="section"><a href="#contacts-sample">3.2. Contacts</a></span></dt><dt><span class="section"><a href="#ldap-sample">3.3. LDAP Sample</a></span></dt><dt><span class="section"><a href="#cas-sample">3.4. CAS Sample</a></span></dt><dt><span class="section"><a href="#preauth-sample">3.5. Pre-Authentication Sample</a></span></dt></dl></dd><dt><span class="chapter"><a href="#community">4. Spring Security Community</a></span></dt><dd><dl><dt><span class="section"><a href="#jira">4.1. Issue Tracking</a></span></dt><dt><span class="section"><a href="#becoming-involved">4.2. Becoming Involved</a></span></dt><dt><span class="section"><a href="#further-info">4.3. Further Information</a></span></dt></dl></dd></dl></dd><dt><span class="part"><a href="#overall-architecture">II. Architecture and Implementation</a></span></dt><dd><dl><dt><span class="chapter"><a href="#technical-overview">5. Technical Overview</a></span></dt><dd><dl><dt><span class="section"><a href="#runtime-environment">5.1. Runtime Environment</a></span></dt><dt><span class="section"><a href="#core-components">5.2. Core Components</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e1518">5.2.1.  SecurityContextHolder, SecurityContext and Authentication Objects </a></span></dt><dt><span class="section"><a href="#d0e1588">5.2.2. The UserDetailsService</a></span></dt><dt><span class="section"><a href="#tech-granted-authority">5.2.3. GrantedAuthority</a></span></dt><dt><span class="section"><a href="#d0e1709">5.2.4. Summary</a></span></dt></dl></dd><dt><span class="section"><a href="#tech-intro-authentication">5.3. Authentication</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e1765">5.3.1. What is authentication in Spring Security?</a></span></dt><dt><span class="section"><a href="#d0e1835">5.3.2. Setting the SecurityContextHolder Contents Directly</a></span></dt></dl></dd><dt><span class="section"><a href="#tech-intro-web-authentication">5.4. Authentication in a Web Application</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e1917">5.4.1. ExceptionTranslationFilter</a></span></dt><dt><span class="section"><a href="#tech-intro-auth-entry-point">5.4.2. AuthenticationEntryPoint</a></span></dt><dt><span class="section"><a href="#d0e1947">5.4.3. Authentication Mechanism</a></span></dt><dt><span class="section"><a href="#tech-intro-sec-context-persistence">5.4.4. Storing the <code class="interfacename">SecurityContext</code> between requests</a></span></dt></dl></dd><dt><span class="section"><a href="#tech-intro-access-control">5.5. Access-Control (Authorization) in Spring Security</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e2068">5.5.1. Security and AOP Advice</a></span></dt><dt><span class="section"><a href="#secure-objects">5.5.2. Secure Objects and the <code class="classname">AbstractSecurityInterceptor</code></a></span></dt></dl></dd><dt><span class="section"><a href="#localization">5.6. Localization</a></span></dt></dl></dd><dt><span class="chapter"><a href="#core-services">6. Core Services</a></span></dt><dd><dl><dt><span class="section"><a href="#core-services-authentication-manager">6.1. The <code class="interfacename">AuthenticationManager</code>,
                 <code class="classname">ProviderManager</code> and
                 <code class="classname">AuthenticationProvider</code>s</a></span></dt><dd><dl><dt><span class="section"><a href="#core-services-dao-provider">6.1.1. <code class="literal">DaoAuthenticationProvider</code></a></span></dt><dt><span class="section"><a href="#core-services-erasing-credentials">6.1.2. Erasing Credentials on Successful Authentication</a></span></dt></dl></dd><dt><span class="section"><a href="#d0e2530">6.2. <code class="interfacename">UserDetailsService</code> Implementations</a></span></dt><dd><dl><dt><span class="section"><a href="#core-services-in-memory-service">6.2.1. In-Memory Authentication</a></span></dt><dt><span class="section"><a href="#core-services-jdbc-user-service">6.2.2. <code class="literal">JdbcDaoImpl</code></a></span></dt></dl></dd><dt><span class="section"><a href="#core-services-password-encoding">6.3. Password Encoding</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e2649">6.3.1. What is a hash?</a></span></dt><dt><span class="section"><a href="#d0e2663">6.3.2. Adding Salt to a Hash</a></span></dt><dt><span class="section"><a href="#d0e2680">6.3.3.  Hashing and Authentication</a></span></dt></dl></dd></dl></dd></dl></dd><dt><span class="part"><a href="#web-app-security">III. Web Application Security</a></span></dt><dd><dl><dt><span class="chapter"><a href="#security-filter-chain">7. The Security Filter Chain</a></span></dt><dd><dl><dt><span class="section"><a href="#delegating-filter-proxy">7.1. <code class="classname">DelegatingFilterProxy</code></a></span></dt><dt><span class="section"><a href="#filter-chain-proxy">7.2. <code class="classname">FilterChainProxy</code></a></span></dt><dd><dl><dt><span class="section"><a href="#d0e2910">7.2.1. Bypassing the Filter Chain</a></span></dt></dl></dd><dt><span class="section"><a href="#d0e2924">7.3. Filter Ordering</a></span></dt><dt><span class="section"><a href="#d0e3025">7.4. Use with other Filter-Based Frameworks</a></span></dt></dl></dd><dt><span class="chapter"><a href="#core-web-filters">8. Core Security Filters</a></span></dt><dd><dl><dt><span class="section"><a href="#filter-security-interceptor">8.1. <code class="classname">FilterSecurityInterceptor</code></a></span></dt><dt><span class="section"><a href="#exception-translation-filter">8.2. 
             <code class="classname">ExceptionTranslationFilter</code></a></span></dt><dd><dl><dt><span class="section"><a href="#auth-entry-point">8.2.1. <code class="interfacename">AuthenticationEntryPoint</code></a></span></dt><dt><span class="section"><a href="#access-denied-handler">8.2.2. <code class="interfacename">AccessDeniedHandler</code></a></span></dt></dl></dd><dt><span class="section"><a href="#security-context-persistence-filter">8.3. <code class="classname">SecurityContextPersistenceFilter</code></a></span></dt><dd><dl><dt><span class="section"><a href="#security-context-repository">8.3.1. <code class="interfacename">SecurityContextRepository</code></a></span></dt></dl></dd><dt><span class="section"><a href="#form-login-filter">8.4. <code class="classname">UsernamePasswordAuthenticationFilter</code></a></span></dt><dd><dl><dt><span class="section"><a href="#form-login-flow-handling">8.4.1. Application Flow on Authentication Success and Failure</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="#basic">9. Basic and Digest Authentication</a></span></dt><dd><dl><dt><span class="section"><a href="#basic-processing-filter">9.1. <code class="classname">BasicAuthenticationFilter</code></a></span></dt><dd><dl><dt><span class="section"><a href="#basic-config">9.1.1. Configuration</a></span></dt></dl></dd><dt><span class="section"><a href="#digest-processing-filter">9.2. <code class="classname">DigestAuthenticationFilter</code></a></span></dt><dd><dl><dt><span class="section"><a href="#digest-config">9.2.1. Configuration</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="#remember-me">10. Remember-Me Authentication</a></span></dt><dd><dl><dt><span class="section"><a href="#remember-me-overview">10.1. Overview</a></span></dt><dt><span class="section"><a href="#remember-me-hash-token">10.2. Simple Hash-Based Token Approach</a></span></dt><dt><span class="section"><a href="#remember-me-persistent-token">10.3. Persistent Token Approach</a></span></dt><dt><span class="section"><a href="#remember-me-impls">10.4. Remember-Me Interfaces and Implementations</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e3706">10.4.1. TokenBasedRememberMeServices</a></span></dt><dt><span class="section"><a href="#d0e3772">10.4.2. PersistentTokenBasedRememberMeServices</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="#session-mgmt">11. Session Management</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e3809">11.1. SessionManagementFilter</a></span></dt><dt><span class="section"><a href="#d0e3847">11.2. <code class="interfacename">SessionAuthenticationStrategy</code></a></span></dt><dt><span class="section"><a href="#concurrent-sessions">11.3. Concurrency Control</a></span></dt></dl></dd><dt><span class="chapter"><a href="#anonymous">12. Anonymous Authentication</a></span></dt><dd><dl><dt><span class="section"><a href="#anonymous-overview">12.1. Overview</a></span></dt><dt><span class="section"><a href="#anonymous-config">12.2. Configuration</a></span></dt><dt><span class="section"><a href="#anonymous-auth-trust-resolver">12.3. <code class="interfacename">AuthenticationTrustResolver</code></a></span></dt></dl></dd></dl></dd><dt><span class="part"><a href="#authorization">IV. Authorization</a></span></dt><dd><dl><dt><span class="chapter"><a href="#authz-arch">13. Authorization Architecture</a></span></dt><dd><dl><dt><span class="section"><a href="#authz-authorities">13.1. Authorities</a></span></dt><dt><span class="section"><a href="#authz-pre-invocation">13.2. Pre-Invocation Handling</a></span></dt><dd><dl><dt><span class="section"><a href="#authz-access-decision-manager">13.2.1. The AccessDecisionManager</a></span></dt><dt><span class="section"><a href="#authz-voting-based">13.2.2. Voting-Based AccessDecisionManager Implementations</a></span></dt></dl></dd><dt><span class="section"><a href="#authz-after-invocation-handling">13.3. After Invocation Handling</a></span></dt></dl></dd><dt><span class="chapter"><a href="#secure-object-impls">14. Secure Object Implementations</a></span></dt><dd><dl><dt><span class="section"><a href="#aop-alliance">14.1. AOP Alliance (MethodInvocation) Security Interceptor</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e4677">14.1.1. Explicit MethodSecurityInterceptor Configuration</a></span></dt></dl></dd><dt><span class="section"><a href="#aspectj">14.2. AspectJ (JoinPoint) Security Interceptor</a></span></dt></dl></dd><dt><span class="chapter"><a href="#el-access">15. Expression-Based Access Control</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e4781">15.1. Overview</a></span></dt><dd><dl><dt><span class="section"><a href="#el-common-built-in">15.1.1. Common Built-In Expressions</a></span></dt></dl></dd><dt><span class="section"><a href="#el-access-web">15.2. Web Security Expressions</a></span></dt><dt><span class="section"><a href="#d0e4949">15.3. Method Security Expressions</a></span></dt><dd><dl><dt><span class="section"><a href="#el-pre-post-annotations">15.3.1. <code class="literal">@Pre</code> and <code class="literal">@Post</code> Annotations</a></span></dt><dt><span class="section"><a href="#el-method-built-in">15.3.2. Built-In Expressions</a></span></dt></dl></dd></dl></dd></dl></dd><dt><span class="part"><a href="#advanced-topics">V. Additional Topics</a></span></dt><dd><dl><dt><span class="chapter"><a href="#domain-acls">16. Domain Object Security (ACLs)</a></span></dt><dd><dl><dt><span class="section"><a href="#domain-acls-overview">16.1. Overview</a></span></dt><dt><span class="section"><a href="#domain-acls-key-concepts">16.2. Key Concepts</a></span></dt><dt><span class="section"><a href="#domain-acls-getting-started">16.3. Getting Started</a></span></dt></dl></dd><dt><span class="chapter"><a href="#preauth">17. Pre-Authentication Scenarios</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e5505">17.1. Pre-Authentication Framework Classes</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e5516">17.1.1. AbstractPreAuthenticatedProcessingFilter</a></span></dt><dt><span class="section"><a href="#d0e5533">17.1.2. AbstractPreAuthenticatedAuthenticationDetailsSource</a></span></dt><dt><span class="section"><a href="#d0e5590">17.1.3. PreAuthenticatedAuthenticationProvider</a></span></dt><dt><span class="section"><a href="#d0e5622">17.1.4. Http403ForbiddenEntryPoint</a></span></dt></dl></dd><dt><span class="section"><a href="#d0e5642">17.2. Concrete Implementations</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e5650">17.2.1. Request-Header Authentication (Siteminder)</a></span></dt><dt><span class="section"><a href="#d0e5696">17.2.2. J2EE Container Authentication</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="#ldap">18. LDAP Authentication</a></span></dt><dd><dl><dt><span class="section"><a href="#ldap-overview">18.1. Overview</a></span></dt><dt><span class="section"><a href="#d0e5734">18.2. Using LDAP with Spring Security</a></span></dt><dt><span class="section"><a href="#ldap-server">18.3. Configuring an LDAP Server</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e5773">18.3.1. Using an Embedded Test Server</a></span></dt><dt><span class="section"><a href="#d0e5797">18.3.2. Using Bind Authentication</a></span></dt><dt><span class="section"><a href="#d0e5818">18.3.3. Loading Authorities</a></span></dt></dl></dd><dt><span class="section"><a href="#d0e5883">18.4. Implementation Classes</a></span></dt><dd><dl><dt><span class="section"><a href="#ldap-ldap-authenticators">18.4.1. LdapAuthenticator Implementations</a></span></dt><dt><span class="section"><a href="#ldap-context-source">18.4.2. Connecting to the LDAP Server</a></span></dt><dt><span class="section"><a href="#ldap-searchobjects">18.4.3. LDAP Search Objects</a></span></dt><dt><span class="section"><a href="#ldap-authorities">18.4.4. LdapAuthoritiesPopulator</a></span></dt><dt><span class="section"><a href="#ldap-bean-config">18.4.5. Spring Bean Configuration</a></span></dt><dt><span class="section"><a href="#ldap-custom-user-details">18.4.6. LDAP Attributes and Customized UserDetails</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="#taglibs">19. JSP Tag Libraries</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e6137">19.1. Declaring the Taglib</a></span></dt><dt><span class="section"><a href="#d0e6144">19.2. The <code class="literal">authorize</code> Tag</a></span></dt><dt><span class="section"><a href="#d0e6190">19.3. The <code class="literal">authentication</code>Tag</a></span></dt><dt><span class="section"><a href="#d0e6221">19.4. The <code class="literal">accesscontrollist</code> Tag</a></span></dt></dl></dd><dt><span class="chapter"><a href="#jaas">20. Java Authentication and Authorization Service (JAAS) Provider</a></span></dt><dd><dl><dt><span class="section"><a href="#jaas-overview">20.1. Overview</a></span></dt><dt><span class="section"><a href="#jaas-config">20.2. Configuration</a></span></dt><dd><dl><dt><span class="section"><a href="#jaas-callbackhandler">20.2.1. JAAS CallbackHandler</a></span></dt><dt><span class="section"><a href="#jaas-authoritygranter">20.2.2. JAAS AuthorityGranter</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="#cas">21. CAS Authentication</a></span></dt><dd><dl><dt><span class="section"><a href="#cas-overview">21.1. Overview</a></span></dt><dt><span class="section"><a href="#cas-how-it-works">21.2. How CAS Works</a></span></dt><dt><span class="section"><a href="#cas-client">21.3. Configuration of CAS Client</a></span></dt></dl></dd><dt><span class="chapter"><a href="#x509">22. X.509 Authentication</a></span></dt><dd><dl><dt><span class="section"><a href="#x509-overview">22.1. Overview</a></span></dt><dt><span class="section"><a href="#d0e6578">22.2. Adding X.509 Authentication to Your Web Application</a></span></dt><dt><span class="section"><a href="#x509-ssl-config">22.3. Setting up SSL in Tomcat</a></span></dt></dl></dd><dt><span class="chapter"><a href="#runas">23. Run-As Authentication Replacement</a></span></dt><dd><dl><dt><span class="section"><a href="#runas-overview">23.1. Overview</a></span></dt><dt><span class="section"><a href="#runas-config">23.2. Configuration</a></span></dt></dl></dd></dl></dd><dt><span class="appendix"><a href="#appendix-schema">A. Security Database Schema</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e6840">A.1. User Schema</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e6853">A.1.1. Group Authorities</a></span></dt></dl></dd><dt><span class="section"><a href="#d0e6863">A.2. Persistent Login (Remember-Me) Schema</a></span></dt><dt><span class="section"><a href="#dbschema-acl">A.3. ACL Schema</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e6927">A.3.1. Hypersonic SQL</a></span></dt></dl></dd></dl></dd><dt><span class="appendix"><a href="#appendix-namespace">B. The Security Namespace</a></span></dt><dd><dl><dt><span class="section"><a href="#nsa-http">B.1. Web Application Security - the <code class="literal"><http></code> Element</a></span></dt><dd><dl><dt><span class="section"><a href="#nsa-http-attributes">B.1.1. <code class="literal"><http></code> Attributes</a></span></dt><dt><span class="section"><a href="#nsa-access-denied-handler">B.1.2. <code class="literal"><access-denied-handler></code></a></span></dt><dt><span class="section"><a href="#d0e7289">B.1.3. The <code class="literal"><intercept-url></code> Element</a></span></dt><dt><span class="section"><a href="#d0e7375">B.1.4. The <code class="literal"><port-mappings></code> Element</a></span></dt><dt><span class="section"><a href="#nsa-form-login">B.1.5. The <code class="literal"><form-login></code> Element</a></span></dt><dt><span class="section"><a href="#nsa-http-basic">B.1.6. The <code class="literal"><http-basic></code> Element</a></span></dt><dt><span class="section"><a href="#nsa-remember-me">B.1.7. The <code class="literal"><remember-me></code> Element</a></span></dt><dt><span class="section"><a href="#nsa-session-mgmt">B.1.8. The <code class="literal"><session-management></code> Element</a></span></dt><dt><span class="section"><a href="#nsa-concurrent-session-control">B.1.9. The <code class="literal"><concurrency-control></code> Element</a></span></dt><dt><span class="section"><a href="#nsa-anonymous">B.1.10. The <code class="literal"><anonymous></code> Element</a></span></dt><dt><span class="section"><a href="#nsa-x509">B.1.11. The <code class="literal"><x509></code> Element</a></span></dt><dt><span class="section"><a href="#nsa-openid-login">B.1.12. The <code class="literal"><openid-login></code> Element</a></span></dt><dt><span class="section"><a href="#nsa-logout">B.1.13. The <code class="literal"><logout></code> Element</a></span></dt><dt><span class="section"><a href="#d0e7898">B.1.14. The <code class="literal"><custom-filter></code> Element</a></span></dt><dt><span class="section"><a href="#nsa-request-cache">B.1.15. The <code class="literal">request-cache</code> Element</a></span></dt><dt><span class="section"><a href="#d0e7926">B.1.16. The <code class="literal"><http-firewall></code> Element</a></span></dt></dl></dd><dt><span class="section"><a href="#nsa-authentication">B.2. Authentication Services</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e7960">B.2.1. The <code class="literal"><authentication-manager></code> Element</a></span></dt></dl></dd><dt><span class="section"><a href="#nsa-method-security">B.3. Method Security</a></span></dt><dd><dl><dt><span class="section"><a href="#nsa-gms">B.3.1. The <code class="literal"><global-method-security></code> Element</a></span></dt><dt><span class="section"><a href="#d0e8166">B.3.2. LDAP Namespace Options</a></span></dt></dl></dd></dl></dd></dl></div><div class="preface" title="Preface"><div class="titlepage"><div><div><h2 class="title"><a name="preface"></a>Preface</h2></div></div></div><p>Spring Security provides a comprehensive security solution for J2EE-based enterprise
@@ -3158,7 +3158,7 @@ aclService.updateAcl(acl);
           potentially choose any username they wished. </p></td></tr></table></div><div class="section" title="Siteminder Example Configuration"><div class="titlepage"><div><div><h4 class="title"><a name="d0e5670"></a>Siteminder Example Configuration</h4></div></div></div><p> A typical configuration using this filter would look like this: </p><pre class="programlisting">
   <security:http>
     <!-- Additional http configuration omitted -->
-    <security:custom-filter ref="siteminderFilter" />
+    <security:custom-filter position="PRE_AUTH_FILTER" ref="siteminderFilter" />
   </security:http>
 
     <bean id="siteminderFilter" class=
diff --git a/docs/reference/springsecurity.html b/docs/reference/springsecurity.html
index 41bc5c8..e20fe4a 100644
--- a/docs/reference/springsecurity.html
+++ b/docs/reference/springsecurity.html
@@ -8,7 +8,7 @@
 			pageTracker._setDomainName("none");
 			pageTracker._setAllowLinker(true);
 			pageTracker._trackPageview();
-		</script><!--End Google Analytics code--></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Spring Security</th></tr><tr><td width="20%" align="left"> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="preface.html">Next</a></td></tr></table><hr></div><div class="book" title="Spring Security"><div class="titlepage"><div><div><h1 class="title"><a name="spring-security-reference-guide"></a>Spring Security</h1></div><div><h2 class="subtitle">Reference Documentation</h2></div><div><div class="authorgroup"><div class="author"><h3 class="author">Ben Alex</h3></div><div class="author"><h3 class="author">Luke Taylor</h3></div></div></div><div><p class="releaseinfo">3.0.4.RELEASE</p></div></div><hr></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="preface"><a href="preface.html">Preface</a></span></dt><dt><span class="part"><a href="getting-started.html">I. Getting Started</a></span></dt><dd><dl><dt><span class="chapter"><a href="introduction.html">1. Introduction</a></span></dt><dd><dl><dt><span class="section"><a href="introduction.html#what-is-acegi-security">1.1. What is Spring Security?</a></span></dt><dt><span class="section"><a href="introduction.html#history">1.2. History</a></span></dt><dt><span class="section"><a href="introduction.html#release-numbering">1.3. Release Numbering</a></span></dt><dt><span class="section"><a href="introduction.html#get-spring-security">1.4. Getting Spring Security</a></span></dt><dd><dl><dt><span class="section"><a href="introduction.html#modules">1.4.1. Project Modules</a></span></dt><dt><span class="section"><a href="introduction.html#get-source">1.4.2. Checking out the Source</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="ns-config.html">2. Security Namespace Configuration</a></span></dt><dd><dl><dt><span class="section"><a href="ns-config.html#d0e344">2.1. Introduction</a></span></dt><dd><dl><dt><span class="section"><a href="ns-config.html#d0e382">2.1.1. Design of the Namespace</a></span></dt></dl></dd><dt><span class="section"><a href="ns-config.html#ns-getting-started">2.2. Getting Started with Security Namespace Configuration</a></span></dt><dd><dl><dt><span class="section"><a href="ns-config.html#ns-web-xml">2.2.1. <code class="literal">web.xml</code> Configuration</a></span></dt><dt><span class="section"><a href="ns-config.html#ns-minimal">2.2.2. A Minimal <code class="literal"><http></code> Configuration</a></span></dt><dt><span class="section"><a href="ns-config.html#ns-auth-providers">2.2.3. Using other Authentication Providers</a></span></dt></dl></dd><dt><span class="section"><a href="ns-config.html#ns-web-advanced">2.3. Advanced Web Features</a></span></dt><dd><dl><dt><span class="section"><a href="ns-config.html#ns-remember-me">2.3.1. Remember-Me Authentication</a></span></dt><dt><span class="section"><a href="ns-config.html#ns-requires-channel">2.3.2. Adding HTTP/HTTPS Channel Security</a></span></dt><dt><span class="section"><a href="ns-config.html#ns-session-mgmt">2.3.3. Session Management</a></span></dt><dt><span class="section"><a href="ns-config.html#ns-openid">2.3.4. OpenID Support</a></span></dt><dt><span class="section"><a href="ns-config.html#ns-custom-filters">2.3.5. Adding in Your Own Filters</a></span></dt></dl></dd><dt><span class="section"><a href="ns-config.html#ns-method-security">2.4. Method Security</a></span></dt><dd><dl><dt><span class="section"><a href="ns-config.html#ns-global-method">2.4.1. The <code class="literal"><global-method-security></code> Element</a></span></dt></dl></dd><dt><span class="section"><a href="ns-config.html#ns-access-manager">2.5. The Default AccessDecisionManager</a></span></dt><dd><dl><dt><span class="section"><a href="ns-config.html#ns-custom-access-mgr">2.5.1. Customizing the AccessDecisionManager</a></span></dt></dl></dd><dt><span class="section"><a href="ns-config.html#ns-auth-manager">2.6. The Authentication Manager and the Namespace</a></span></dt></dl></dd><dt><span class="chapter"><a href="sample-apps.html">3. Sample Applications</a></span></dt><dd><dl><dt><span class="section"><a href="sample-apps.html#tutorial-sample">3.1. Tutorial Sample</a></span></dt><dt><span class="section"><a href="sample-apps.html#contacts-sample">3.2. Contacts</a></span></dt><dt><span class="section"><a href="sample-apps.html#ldap-sample">3.3. LDAP Sample</a></span></dt><dt><span class="section"><a href="sample-apps.html#cas-sample">3.4. CAS Sample</a></span></dt><dt><span class="section"><a href="sample-apps.html#preauth-sample">3.5. Pre-Authentication Sample</a></span></dt></dl></dd><dt><span class="chapter"><a href="community.html">4. Spring Security Community</a></span></dt><dd><dl><dt><span class="section"><a href="community.html#jira">4.1. Issue Tracking</a></span></dt><dt><span class="section"><a href="community.html#becoming-involved">4.2. Becoming Involved</a></span></dt><dt><span class="section"><a href="community.html#further-info">4.3. Further Information</a></span></dt></dl></dd></dl></dd><dt><span class="part"><a href="overall-architecture.html">II. Architecture and Implementation</a></span></dt><dd><dl><dt><span class="chapter"><a href="technical-overview.html">5. Technical Overview</a></span></dt><dd><dl><dt><span class="section"><a href="technical-overview.html#runtime-environment">5.1. Runtime Environment</a></span></dt><dt><span class="section"><a href="technical-overview.html#core-components">5.2. Core Components</a></span></dt><dd><dl><dt><span class="section"><a href="technical-overview.html#d0e1518">5.2.1.  SecurityContextHolder, SecurityContext and Authentication Objects </a></span></dt><dt><span class="section"><a href="technical-overview.html#d0e1588">5.2.2. The UserDetailsService</a></span></dt><dt><span class="section"><a href="technical-overview.html#tech-granted-authority">5.2.3. GrantedAuthority</a></span></dt><dt><span class="section"><a href="technical-overview.html#d0e1709">5.2.4. Summary</a></span></dt></dl></dd><dt><span class="section"><a href="technical-overview.html#tech-intro-authentication">5.3. Authentication</a></span></dt><dd><dl><dt><span class="section"><a href="technical-overview.html#d0e1765">5.3.1. What is authentication in Spring Security?</a></span></dt><dt><span class="section"><a href="technical-overview.html#d0e1835">5.3.2. Setting the SecurityContextHolder Contents Directly</a></span></dt></dl></dd><dt><span class="section"><a href="technical-overview.html#tech-intro-web-authentication">5.4. Authentication in a Web Application</a></span></dt><dd><dl><dt><span class="section"><a href="technical-overview.html#d0e1917">5.4.1. ExceptionTranslationFilter</a></span></dt><dt><span class="section"><a href="technical-overview.html#tech-intro-auth-entry-point">5.4.2. AuthenticationEntryPoint</a></span></dt><dt><span class="section"><a href="technical-overview.html#d0e1947">5.4.3. Authentication Mechanism</a></span></dt><dt><span class="section"><a href="technical-overview.html#tech-intro-sec-context-persistence">5.4.4. Storing the <code class="interfacename">SecurityContext</code> between requests</a></span></dt></dl></dd><dt><span class="section"><a href="technical-overview.html#tech-intro-access-control">5.5. Access-Control (Authorization) in Spring Security</a></span></dt><dd><dl><dt><span class="section"><a href="technical-overview.html#d0e2068">5.5.1. Security and AOP Advice</a></span></dt><dt><span class="section"><a href="technical-overview.html#secure-objects">5.5.2. Secure Objects and the <code class="classname">AbstractSecurityInterceptor</code></a></span></dt></dl></dd><dt><span class="section"><a href="technical-overview.html#localization">5.6. Localization</a></span></dt></dl></dd><dt><span class="chapter"><a href="core-services.html">6. Core Services</a></span></dt><dd><dl><dt><span class="section"><a href="core-services.html#core-services-authentication-manager">6.1. The <code class="interfacename">AuthenticationManager</code>,
+		</script><!--End Google Analytics code--></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Spring Security</th></tr><tr><td width="20%" align="left"> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="preface.html">Next</a></td></tr></table><hr></div><div class="book" title="Spring Security"><div class="titlepage"><div><div><h1 class="title"><a name="spring-security-reference-guide"></a>Spring Security</h1></div><div><h2 class="subtitle">Reference Documentation</h2></div><div><div class="authorgroup"><div class="author"><h3 class="author">Ben Alex</h3></div><div class="author"><h3 class="author">Luke Taylor</h3></div></div></div><div><p class="releaseinfo">3.0.5.RELEASE</p></div></div><hr></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="preface"><a href="preface.html">Preface</a></span></dt><dt><span class="part"><a href="getting-started.html">I. Getting Started</a></span></dt><dd><dl><dt><span class="chapter"><a href="introduction.html">1. Introduction</a></span></dt><dd><dl><dt><span class="section"><a href="introduction.html#what-is-acegi-security">1.1. What is Spring Security?</a></span></dt><dt><span class="section"><a href="introduction.html#history">1.2. History</a></span></dt><dt><span class="section"><a href="introduction.html#release-numbering">1.3. Release Numbering</a></span></dt><dt><span class="section"><a href="introduction.html#get-spring-security">1.4. Getting Spring Security</a></span></dt><dd><dl><dt><span class="section"><a href="introduction.html#modules">1.4.1. Project Modules</a></span></dt><dt><span class="section"><a href="introduction.html#get-source">1.4.2. Checking out the Source</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="ns-config.html">2. Security Namespace Configuration</a></span></dt><dd><dl><dt><span class="section"><a href="ns-config.html#d0e344">2.1. Introduction</a></span></dt><dd><dl><dt><span class="section"><a href="ns-config.html#d0e382">2.1.1. Design of the Namespace</a></span></dt></dl></dd><dt><span class="section"><a href="ns-config.html#ns-getting-started">2.2. Getting Started with Security Namespace Configuration</a></span></dt><dd><dl><dt><span class="section"><a href="ns-config.html#ns-web-xml">2.2.1. <code class="literal">web.xml</code> Configuration</a></span></dt><dt><span class="section"><a href="ns-config.html#ns-minimal">2.2.2. A Minimal <code class="literal"><http></code> Configuration</a></span></dt><dt><span class="section"><a href="ns-config.html#ns-auth-providers">2.2.3. Using other Authentication Providers</a></span></dt></dl></dd><dt><span class="section"><a href="ns-config.html#ns-web-advanced">2.3. Advanced Web Features</a></span></dt><dd><dl><dt><span class="section"><a href="ns-config.html#ns-remember-me">2.3.1. Remember-Me Authentication</a></span></dt><dt><span class="section"><a href="ns-config.html#ns-requires-channel">2.3.2. Adding HTTP/HTTPS Channel Security</a></span></dt><dt><span class="section"><a href="ns-config.html#ns-session-mgmt">2.3.3. Session Management</a></span></dt><dt><span class="section"><a href="ns-config.html#ns-openid">2.3.4. OpenID Support</a></span></dt><dt><span class="section"><a href="ns-config.html#ns-custom-filters">2.3.5. Adding in Your Own Filters</a></span></dt></dl></dd><dt><span class="section"><a href="ns-config.html#ns-method-security">2.4. Method Security</a></span></dt><dd><dl><dt><span class="section"><a href="ns-config.html#ns-global-method">2.4.1. The <code class="literal"><global-method-security></code> Element</a></span></dt></dl></dd><dt><span class="section"><a href="ns-config.html#ns-access-manager">2.5. The Default AccessDecisionManager</a></span></dt><dd><dl><dt><span class="section"><a href="ns-config.html#ns-custom-access-mgr">2.5.1. Customizing the AccessDecisionManager</a></span></dt></dl></dd><dt><span class="section"><a href="ns-config.html#ns-auth-manager">2.6. The Authentication Manager and the Namespace</a></span></dt></dl></dd><dt><span class="chapter"><a href="sample-apps.html">3. Sample Applications</a></span></dt><dd><dl><dt><span class="section"><a href="sample-apps.html#tutorial-sample">3.1. Tutorial Sample</a></span></dt><dt><span class="section"><a href="sample-apps.html#contacts-sample">3.2. Contacts</a></span></dt><dt><span class="section"><a href="sample-apps.html#ldap-sample">3.3. LDAP Sample</a></span></dt><dt><span class="section"><a href="sample-apps.html#cas-sample">3.4. CAS Sample</a></span></dt><dt><span class="section"><a href="sample-apps.html#preauth-sample">3.5. Pre-Authentication Sample</a></span></dt></dl></dd><dt><span class="chapter"><a href="community.html">4. Spring Security Community</a></span></dt><dd><dl><dt><span class="section"><a href="community.html#jira">4.1. Issue Tracking</a></span></dt><dt><span class="section"><a href="community.html#becoming-involved">4.2. Becoming Involved</a></span></dt><dt><span class="section"><a href="community.html#further-info">4.3. Further Information</a></span></dt></dl></dd></dl></dd><dt><span class="part"><a href="overall-architecture.html">II. Architecture and Implementation</a></span></dt><dd><dl><dt><span class="chapter"><a href="technical-overview.html">5. Technical Overview</a></span></dt><dd><dl><dt><span class="section"><a href="technical-overview.html#runtime-environment">5.1. Runtime Environment</a></span></dt><dt><span class="section"><a href="technical-overview.html#core-components">5.2. Core Components</a></span></dt><dd><dl><dt><span class="section"><a href="technical-overview.html#d0e1518">5.2.1.  SecurityContextHolder, SecurityContext and Authentication Objects </a></span></dt><dt><span class="section"><a href="technical-overview.html#d0e1588">5.2.2. The UserDetailsService</a></span></dt><dt><span class="section"><a href="technical-overview.html#tech-granted-authority">5.2.3. GrantedAuthority</a></span></dt><dt><span class="section"><a href="technical-overview.html#d0e1709">5.2.4. Summary</a></span></dt></dl></dd><dt><span class="section"><a href="technical-overview.html#tech-intro-authentication">5.3. Authentication</a></span></dt><dd><dl><dt><span class="section"><a href="technical-overview.html#d0e1765">5.3.1. What is authentication in Spring Security?</a></span></dt><dt><span class="section"><a href="technical-overview.html#d0e1835">5.3.2. Setting the SecurityContextHolder Contents Directly</a></span></dt></dl></dd><dt><span class="section"><a href="technical-overview.html#tech-intro-web-authentication">5.4. Authentication in a Web Application</a></span></dt><dd><dl><dt><span class="section"><a href="technical-overview.html#d0e1917">5.4.1. ExceptionTranslationFilter</a></span></dt><dt><span class="section"><a href="technical-overview.html#tech-intro-auth-entry-point">5.4.2. AuthenticationEntryPoint</a></span></dt><dt><span class="section"><a href="technical-overview.html#d0e1947">5.4.3. Authentication Mechanism</a></span></dt><dt><span class="section"><a href="technical-overview.html#tech-intro-sec-context-persistence">5.4.4. Storing the <code class="interfacename">SecurityContext</code> between requests</a></span></dt></dl></dd><dt><span class="section"><a href="technical-overview.html#tech-intro-access-control">5.5. Access-Control (Authorization) in Spring Security</a></span></dt><dd><dl><dt><span class="section"><a href="technical-overview.html#d0e2068">5.5.1. Security and AOP Advice</a></span></dt><dt><span class="section"><a href="technical-overview.html#secure-objects">5.5.2. Secure Objects and the <code class="classname">AbstractSecurityInterceptor</code></a></span></dt></dl></dd><dt><span class="section"><a href="technical-overview.html#localization">5.6. Localization</a></span></dt></dl></dd><dt><span class="chapter"><a href="core-services.html">6. Core Services</a></span></dt><dd><dl><dt><span class="section"><a href="core-services.html#core-services-authentication-manager">6.1. The <code class="interfacename">AuthenticationManager</code>,
                 <code class="classname">ProviderManager</code> and
                 <code class="classname">AuthenticationProvider</code>s</a></span></dt><dd><dl><dt><span class="section"><a href="core-services.html#core-services-dao-provider">6.1.1. <code class="literal">DaoAuthenticationProvider</code></a></span></dt><dt><span class="section"><a href="core-services.html#core-services-erasing-credentials">6.1.2. Erasing Credentials on Successful Authentication</a></span></dt></dl></dd><dt><span class="section"><a href="core-services.html#d0e2530">6.2. <code class="interfacename">UserDetailsService</code> Implementations</a></span></dt><dd><dl><dt><span class="section"><a href="core-services.html#core-services-in-memory-service">6.2.1. In-Memory Authentication</a></span></dt><dt><span class="section"><a href="core-services.html#core-services-jdbc-user-service">6.2.2. <code class="literal">JdbcDaoImpl</code></a></span></dt></dl></dd><dt><span class="section"><a href="core-services.html#core-services-password-encoding">6.3. Password Encoding</a></span></dt><dd><dl><dt><span class="section"><a href="core-services.html#d0e2649">6.3.1. What is a hash?</a></span></dt><dt><span class="section"><a href="core-services.html#d0e2663">6.3.2. Adding Salt to a Hash</a></span></dt><dt><span class="section"><a href="core-services.html#d0e2680">6.3.3.  Hashing and Authentication</a></span></dt></dl></dd></dl></dd></dl></dd><dt><span class="part"><a href="web-app-security.html">III. Web Application Security</a></span></dt><dd><dl><dt><span class="chapter"><a href="security-filter-chain.html">7. The Security Filter Chain</a></span></dt><dd><dl><dt><span class="section"><a href="security-filter-chain.html#delegating-filter-proxy">7.1. <code class="classname">DelegatingFilterProxy</code></a></span></dt><dt><span class="section"><a href="security-filter-chain.html#filter-chain-proxy">7.2. <code class="classname">FilterChainProxy</code></a></span></dt><dd><dl><dt><span class="section"><a href="security-filter-chain.html#d0e2910">7.2.1. Bypassing the Filter Chain</a></span></dt></dl></dd><dt><span class="section"><a href="security-filter-chain.html#d0e2924">7.3. Filter Ordering</a></span></dt><dt><span class="section"><a href="security-filter-chain.html#d0e3025">7.4. Use with other Filter-Based Frameworks</a></span></dt></dl></dd><dt><span class="chapter"><a href="core-web-filters.html">8. Core Security Filters</a></span></dt><dd><dl><dt><span class="section"><a href="core-web-filters.html#filter-security-interceptor">8.1. <code class="classname">FilterSecurityInterceptor</code></a></span></dt><dt><span class="section"><a href="core-web-filters.html#exception-translation-filter">8.2. 
             <code class="classname">ExceptionTranslationFilter</code></a></span></dt><dd><dl><dt><span class="section"><a href="core-web-filters.html#auth-entry-point">8.2.1. <code class="interfacename">AuthenticationEntryPoint</code></a></span></dt><dt><span class="section"><a href="core-web-filters.html#access-denied-handler">8.2.2. <code class="interfacename">AccessDeniedHandler</code></a></span></dt></dl></dd><dt><span class="section"><a href="core-web-filters.html#security-context-persistence-filter">8.3. <code class="classname">SecurityContextPersistenceFilter</code></a></span></dt><dd><dl><dt><span class="section"><a href="core-web-filters.html#security-context-repository">8.3.1. <code class="interfacename">SecurityContextRepository</code></a></span></dt></dl></dd><dt><span class="section"><a href="core-web-filters.html#form-login-filter">8.4. <code class="classname">UsernamePasswordAuthenticationFilter</code></a></span></dt><dd><dl><dt><span class="section"><a href="core-web-filters.html#form-login-flow-handling">8.4.1. Application Flow on Authentication Success and Failure</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="basic.html">9. Basic and Digest Authentication</a></span></dt><dd><dl><dt><span class="section"><a href="basic.html#basic-processing-filter">9.1. <code class="classname">BasicAuthenticationFilter</code></a></span></dt><dd><dl><dt><span class="section"><a href="basic.html#basic-config">9.1.1. Configuration</a></span></dt></dl></dd><dt><span class="section"><a href="basic.html#digest-processing-filter">9.2. <code class="classname">DigestAuthenticationFilter</code></a></span></dt><dd><dl><dt><span class="section"><a href="basic.html#digest-config">9.2.1. Configuration</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="remember-me.html">10. Remember-Me Authentication</a></span></dt><dd><dl><dt><span class="section"><a href="remember-me.html#remember-me-overview">10.1. Overview</a></span></dt><dt><span class="section"><a href="remember-me.html#remember-me-hash-token">10.2. Simple Hash-Based Token Approach</a></span></dt><dt><span class="section"><a href="remember-me.html#remember-me-persistent-token">10.3. Persistent Token Approach</a></span></dt><dt><span class="section"><a href="remember-me.html#remember-me-impls">10.4. Remember-Me Interfaces and Implementations</a></span></dt><dd><dl><dt><span class="section"><a href="remember-me.html#d0e3706">10.4.1. TokenBasedRememberMeServices</a></span></dt><dt><span class="section"><a href="remember-me.html#d0e3772">10.4.2. PersistentTokenBasedRememberMeServices</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="session-mgmt.html">11. Session Management</a></span></dt><dd><dl><dt><span class="section"><a href="session-mgmt.html#d0e3809">11.1. SessionManagementFilter</a></span></dt><dt><span class="section"><a href="session-mgmt.html#d0e3847">11.2. <code class="interfacename">SessionAuthenticationStrategy</code></a></span></dt><dt><span class="section"><a href="session-mgmt.html#concurrent-sessions">11.3. Concurrency Control</a></span></dt></dl></dd><dt><span class="chapter"><a href="anonymous.html">12. Anonymous Authentication</a></span></dt><dd><dl><dt><span class="section"><a href="anonymous.html#anonymous-overview">12.1. Overview</a></span></dt><dt><span class="section"><a href="anonymous.html#anonymous-config">12.2. Configuration</a></span></dt><dt><span class="section"><a href="anonymous.html#anonymous-auth-trust-resolver">12.3. <code class="interfacename">AuthenticationTrustResolver</code></a></span></dt></dl></dd></dl></dd><dt><span class="part"><a href="authorization.html">IV. Authorization</a></span></dt><dd><dl><dt><span class="chapter"><a href="authz-arch.html">13. Authorization Architecture</a></span></dt><dd><dl><dt><span class="section"><a href="authz-arch.html#authz-authorities">13.1. Authorities</a></span></dt><dt><span class="section"><a href="authz-arch.html#authz-pre-invocation">13.2. Pre-Invocation Handling</a></span></dt><dd><dl><dt><span class="section"><a href="authz-arch.html#authz-access-decision-manager">13.2.1. The AccessDecisionManager</a></span></dt><dt><span class="section"><a href="authz-arch.html#authz-voting-based">13.2.2. Voting-Based AccessDecisionManager Implementations</a></span></dt></dl></dd><dt><span class="section"><a href="authz-arch.html#authz-after-invocation-handling">13.3. After Invocation Handling</a></span></dt></dl></dd><dt><span class="chapter"><a href="secure-object-impls.html">14. Secure Object Implementations</a></span></dt><dd><dl><dt><span class="section"><a href="secure-object-impls.html#aop-alliance">14.1. AOP Alliance (MethodInvocation) Security Interceptor</a></span></dt><dd><dl><dt><span class="section"><a href="secure-object-impls.html#d0e4677">14.1.1. Explicit MethodSecurityInterceptor Configuration</a></span></dt></dl></dd><dt><span class="section"><a href="secure-object-impls.html#aspectj">14.2. AspectJ (JoinPoint) Security Interceptor</a></span></dt></dl></dd><dt><span class="chapter"><a href="el-access.html">15. Expression-Based Access Control</a></span></dt><dd><dl><dt><span class="section"><a href="el-access.html#d0e4781">15.1. Overview</a></span></dt><dd><dl><dt><span class="section"><a href="el-access.html#el-common-built-in">15.1.1. Common Built-In Expressions</a></span></dt></dl></dd><dt><span class="section"><a href="el-access.html#el-access-web">15.2. Web Security Expressions</a></span></dt><dt><span class="section"><a href="el-access.html#d0e4949">15.3. Method Security Expressions</a></span></dt><dd><dl><dt><span class="section"><a href="el-access.html#el-pre-post-annotations">15.3.1. <code class="literal">@Pre</code> and <code class="literal">@Post</code> Annotations</a></span></dt><dt><span class="section"><a href="el-access.html#el-method-built-in">15.3.2. Built-In Expressions</a></span></dt></dl></dd></dl></dd></dl></dd><dt><span class="part"><a href="advanced-topics.html">V. Additional Topics</a></span></dt><dd><dl><dt><span class="chapter"><a href="domain-acls.html">16. Domain Object Security (ACLs)</a></span></dt><dd><dl><dt><span class="section"><a href="domain-acls.html#domain-acls-overview">16.1. Overview</a></span></dt><dt><span class="section"><a href="domain-acls.html#domain-acls-key-concepts">16.2. Key Concepts</a></span></dt><dt><span class="section"><a href="domain-acls.html#domain-acls-getting-started">16.3. Getting Started</a></span></dt></dl></dd><dt><span class="chapter"><a href="preauth.html">17. Pre-Authentication Scenarios</a></span></dt><dd><dl><dt><span class="section"><a href="preauth.html#d0e5505">17.1. Pre-Authentication Framework Classes</a></span></dt><dd><dl><dt><span class="section"><a href="preauth.html#d0e5516">17.1.1. AbstractPreAuthenticatedProcessingFilter</a></span></dt><dt><span class="section"><a href="preauth.html#d0e5533">17.1.2. AbstractPreAuthenticatedAuthenticationDetailsSource</a></span></dt><dt><span class="section"><a href="preauth.html#d0e5590">17.1.3. PreAuthenticatedAuthenticationProvider</a></span></dt><dt><span class="section"><a href="preauth.html#d0e5622">17.1.4. Http403ForbiddenEntryPoint</a></span></dt></dl></dd><dt><span class="section"><a href="preauth.html#d0e5642">17.2. Concrete Implementations</a></span></dt><dd><dl><dt><span class="section"><a href="preauth.html#d0e5650">17.2.1. Request-Header Authentication (Siteminder)</a></span></dt><dt><span class="section"><a href="preauth.html#d0e5696">17.2.2. J2EE Container Authentication</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="ldap.html">18. LDAP Authentication</a></span></dt><dd><dl><dt><span class="section"><a href="ldap.html#ldap-overview">18.1. Overview</a></span></dt><dt><span class="section"><a href="ldap.html#d0e5734">18.2. Using LDAP with Spring Security</a></span></dt><dt><span class="section"><a href="ldap.html#ldap-server">18.3. Configuring an LDAP Server</a></span></dt><dd><dl><dt><span class="section"><a href="ldap.html#d0e5773">18.3.1. Using an Embedded Test Server</a></span></dt><dt><span class="section"><a href="ldap.html#d0e5797">18.3.2. Using Bind Authentication</a></span></dt><dt><span class="section"><a href="ldap.html#d0e5818">18.3.3. Loading Authorities</a></span></dt></dl></dd><dt><span class="section"><a href="ldap.html#d0e5883">18.4. Implementation Classes</a></span></dt><dd><dl><dt><span class="section"><a href="ldap.html#ldap-ldap-authenticators">18.4.1. LdapAuthenticator Implementations</a></span></dt><dt><span class="section"><a href="ldap.html#ldap-context-source">18.4.2. Connecting to the LDAP Server</a></span></dt><dt><span class="section"><a href="ldap.html#ldap-searchobjects">18.4.3. LDAP Search Objects</a></span></dt><dt><span class="section"><a href="ldap.html#ldap-authorities">18.4.4. LdapAuthoritiesPopulator</a></span></dt><dt><span class="section"><a href="ldap.html#ldap-bean-config">18.4.5. Spring Bean Configuration</a></span></dt><dt><span class="section"><a href="ldap.html#ldap-custom-user-details">18.4.6. LDAP Attributes and Customized UserDetails</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="taglibs.html">19. JSP Tag Libraries</a></span></dt><dd><dl><dt><span class="section"><a href="taglibs.html#d0e6137">19.1. Declaring the Taglib</a></span></dt><dt><span class="section"><a href="taglibs.html#d0e6144">19.2. The <code class="literal">authorize</code> Tag</a></span></dt><dt><span class="section"><a href="taglibs.html#d0e6190">19.3. The <code class="literal">authentication</code>Tag</a></span></dt><dt><span class="section"><a href="taglibs.html#d0e6221">19.4. The <code class="literal">accesscontrollist</code> Tag</a></span></dt></dl></dd><dt><span class="chapter"><a href="jaas.html">20. Java Authentication and Authorization Service (JAAS) Provider</a></span></dt><dd><dl><dt><span class="section"><a href="jaas.html#jaas-overview">20.1. Overview</a></span></dt><dt><span class="section"><a href="jaas.html#jaas-config">20.2. Configuration</a></span></dt><dd><dl><dt><span class="section"><a href="jaas.html#jaas-callbackhandler">20.2.1. JAAS CallbackHandler</a></span></dt><dt><span class="section"><a href="jaas.html#jaas-authoritygranter">20.2.2. JAAS AuthorityGranter</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="cas.html">21. CAS Authentication</a></span></dt><dd><dl><dt><span class="section"><a href="cas.html#cas-overview">21.1. Overview</a></span></dt><dt><span class="section"><a href="cas.html#cas-how-it-works">21.2. How CAS Works</a></span></dt><dt><span class="section"><a href="cas.html#cas-client">21.3. Configuration of CAS Client</a></span></dt></dl></dd><dt><span class="chapter"><a href="x509.html">22. X.509 Authentication</a></span></dt><dd><dl><dt><span class="section"><a href="x509.html#x509-overview">22.1. Overview</a></span></dt><dt><span class="section"><a href="x509.html#d0e6578">22.2. Adding X.509 Authentication to Your Web Application</a></span></dt><dt><span class="section"><a href="x509.html#x509-ssl-config">22.3. Setting up SSL in Tomcat</a></span></dt></dl></dd><dt><span class="chapter"><a href="runas.html">23. Run-As Authentication Replacement</a></span></dt><dd><dl><dt><span class="section"><a href="runas.html#runas-overview">23.1. Overview</a></span></dt><dt><span class="section"><a href="runas.html#runas-config">23.2. Configuration</a></span></dt></dl></dd></dl></dd><dt><span class="appendix"><a href="appendix-schema.html">A. Security Database Schema</a></span></dt><dd><dl><dt><span class="section"><a href="appendix-schema.html#d0e6840">A.1. User Schema</a></span></dt><dd><dl><dt><span class="section"><a href="appendix-schema.html#d0e6853">A.1.1. Group Authorities</a></span></dt></dl></dd><dt><span class="section"><a href="appendix-schema.html#d0e6863">A.2. Persistent Login (Remember-Me) Schema</a></span></dt><dt><span class="section"><a href="appendix-schema.html#dbschema-acl">A.3. ACL Schema</a></span></dt><dd><dl><dt><span class="section"><a href="appendix-schema.html#d0e6927">A.3.1. Hypersonic SQL</a></span></dt></dl></dd></dl></dd><dt><span class="appendix"><a href="appendix-namespace.html">B. The Security Namespace</a></span></dt><dd><dl><dt><span class="section"><a href="appendix-namespace.html#nsa-http">B.1. Web Application Security - the <code class="literal"><http></code> Element</a></span></dt><dd><dl><dt><span class="section"><a href="appendix-namespace.html#nsa-http-attributes">B.1.1. <code class="literal"><http></code> Attributes</a></span></dt><dt><span class="section"><a href="appendix-namespace.html#nsa-access-denied-handler">B.1.2. <code class="literal"><access-denied-handler></code></a></span></dt><dt><span class="section"><a href="appendix-namespace.html#d0e7289">B.1.3. The <code class="literal"><intercept-url></code> Element</a></span></dt><dt><span class="section"><a href="appendix-namespace.html#d0e7375">B.1.4. The <code class="literal"><port-mappings></code> Element</a></span></dt><dt><span class="section"><a href="appendix-namespace.html#nsa-form-login">B.1.5. The <code class="literal"><form-login></code> Element</a></span></dt><dt><span class="section"><a href="appendix-namespace.html#nsa-http-basic">B.1.6. The <code class="literal"><http-basic></code> Element</a></span></dt><dt><span class="section"><a href="appendix-namespace.html#nsa-remember-me">B.1.7. The <code class="literal"><remember-me></code> Element</a></span></dt><dt><span class="section"><a href="appendix-namespace.html#nsa-session-mgmt">B.1.8. The <code class="literal"><session-management></code> Element</a></span></dt><dt><span class="section"><a href="appendix-namespace.html#nsa-concurrent-session-control">B.1.9. The <code class="literal"><concurrency-control></code> Element</a></span></dt><dt><span class="section"><a href="appendix-namespace.html#nsa-anonymous">B.1.10. The <code class="literal"><anonymous></code> Element</a></span></dt><dt><span class="section"><a href="appendix-namespace.html#nsa-x509">B.1.11. The <code class="literal"><x509></code> Element</a></span></dt><dt><span class="section"><a href="appendix-namespace.html#nsa-openid-login">B.1.12. The <code class="literal"><openid-login></code> Element</a></span></dt><dt><span class="section"><a href="appendix-namespace.html#nsa-logout">B.1.13. The <code class="literal"><logout></code> Element</a></span></dt><dt><span class="section"><a href="appendix-namespace.html#d0e7898">B.1.14. The <code class="literal"><custom-filter></code> Element</a></span></dt><dt><span class="section"><a href="appendix-namespace.html#nsa-request-cache">B.1.15. The <code class="literal">request-cache</code> Element</a></span></dt><dt><span class="section"><a href="appendix-namespace.html#d0e7926">B.1.16. The <code class="literal"><http-firewall></code> Element</a></span></dt></dl></dd><dt><span class="section"><a href="appendix-namespace.html#nsa-authentication">B.2. Authentication Services</a></span></dt><dd><dl><dt><span class="section"><a href="appendix-namespace.html#d0e7960">B.2.1. The <code class="literal"><authentication-manager></code> Element</a></span></dt></dl></dd><dt><span class="section"><a href="appendix-namespace.html#nsa-method-security">B.3. Method Security</a></span></dt><dd><dl><dt><span class="section"><a href="appendix-namespace.html#nsa-gms">B.3.1. The <code class="literal"><global-method-security></code> Element</a></span></dt><dt><span class="section"><a href="appendix-namespace.html#d0e8166">B.3.2. LDAP Namespace Options</a></span></dt></dl></dd></dl></dd></dl></div></div><!--Begin LoopFuse code--><script src="http://loopfuse.net/webrecorder/js/listen.js" type="text/javascript"></script><script type="text/javascript">

-- 
Spring Security: Java libraries that provide security services for the Spring Framework



More information about the pkg-java-commits mailing list