Selaa lähdekoodia

SEC-877, SEC-553: Added code to sandbox/other

Luke Taylor 17 vuotta sitten
vanhempi
commit
6b45eda37c
48 muutettua tiedostoa jossa 3663 lisäystä ja 0 poistoa
  1. 36 0
      sandbox/other/src/main/java/org/springframework/security/ui/preauth/AttributesSource.java
  2. 96 0
      sandbox/other/src/main/java/org/springframework/security/ui/preauth/AttributesSourceWebAuthenticationDetailsSource.java
  3. 51 0
      sandbox/other/src/main/java/org/springframework/security/ui/preauth/AuthenticationDetailsImpl.java
  4. 78 0
      sandbox/other/src/main/java/org/springframework/security/ui/preauth/CookieAttributesSource.java
  5. 70 0
      sandbox/other/src/main/java/org/springframework/security/ui/preauth/CookieUsernameSource.java
  6. 78 0
      sandbox/other/src/main/java/org/springframework/security/ui/preauth/HeaderAttributesSource.java
  7. 69 0
      sandbox/other/src/main/java/org/springframework/security/ui/preauth/HeaderUsernameSource.java
  8. 67 0
      sandbox/other/src/main/java/org/springframework/security/ui/preauth/PropertyAttributesSource.java
  9. 77 0
      sandbox/other/src/main/java/org/springframework/security/ui/preauth/RemoteUserUsernameSource.java
  10. 68 0
      sandbox/other/src/main/java/org/springframework/security/ui/preauth/RequestParameterUsernameSource.java
  11. 35 0
      sandbox/other/src/main/java/org/springframework/security/ui/preauth/UsernameSource.java
  12. 103 0
      sandbox/other/src/main/java/org/springframework/security/ui/preauth/UsernameSourcePreAuthenticatedProcessingFilter.java
  13. 38 0
      sandbox/other/src/main/java/org/springframework/security/userdetails/ldap/AccountMapper.java
  14. 91 0
      sandbox/other/src/main/java/org/springframework/security/userdetails/ldap/AuthorityByPrefixAccountMapper.java
  15. 35 0
      sandbox/other/src/main/java/org/springframework/security/userdetails/ldap/AuthorityNotFoundException.java
  16. 133 0
      sandbox/other/src/main/java/org/springframework/security/userdetails/ldap/ReplacingUserDetailsMapper.java
  17. 69 0
      sandbox/other/src/main/java/org/springframework/security/userdetails/ldap/UsernameFromPropertyAccountMapper.java
  18. 47 0
      sandbox/other/src/main/java/org/springframework/security/userdetails/ldap/UsernameFromUserdetailsAccountMapper.java
  19. 37 0
      sandbox/other/src/main/java/org/springframework/security/userdetails/preauth/AccountMapper.java
  20. 96 0
      sandbox/other/src/main/java/org/springframework/security/userdetails/preauth/UserDetailsMappingServiceWrapper.java
  21. 74 0
      sandbox/other/src/main/java/org/springframework/security/userdetails/preauth/UsernameFromPropertyAccountMapper.java
  22. 51 0
      sandbox/other/src/main/java/org/springframework/security/userdetails/preauth/UsernameFromRequestAccountMapper.java
  23. 99 0
      sandbox/other/src/main/java/org/springframework/security/util/ServletUtils.java
  24. 69 0
      sandbox/other/src/main/java/org/springframework/security/util/StringUtils.java
  25. 32 0
      sandbox/other/src/test/java/org/springframework/security/ui/AllTests.java
  26. 47 0
      sandbox/other/src/test/java/org/springframework/security/ui/preauth/AllTests.java
  27. 176 0
      sandbox/other/src/test/java/org/springframework/security/ui/preauth/AttributesSourceWebAuthenticationDetailsSourceTest.java
  28. 80 0
      sandbox/other/src/test/java/org/springframework/security/ui/preauth/CookieAttributesSourceTest.java
  29. 64 0
      sandbox/other/src/test/java/org/springframework/security/ui/preauth/CookieUsernameSourceTest.java
  30. 76 0
      sandbox/other/src/test/java/org/springframework/security/ui/preauth/HeaderAttributesSourceTest.java
  31. 70 0
      sandbox/other/src/test/java/org/springframework/security/ui/preauth/HeaderUsernameSourceTest.java
  32. 74 0
      sandbox/other/src/test/java/org/springframework/security/ui/preauth/PropertyAttributesSourceTest.java
  33. 65 0
      sandbox/other/src/test/java/org/springframework/security/ui/preauth/RemoteUserUsernameSourceTest.java
  34. 70 0
      sandbox/other/src/test/java/org/springframework/security/ui/preauth/RequestParameterUsernameSourceTest.java
  35. 232 0
      sandbox/other/src/test/java/org/springframework/security/ui/preauth/UsernameSourcePreAuthenticatedProcessingFilterTest.java
  36. 33 0
      sandbox/other/src/test/java/org/springframework/security/userdetails/AllTests.java
  37. 37 0
      sandbox/other/src/test/java/org/springframework/security/userdetails/ldap/AllTests.java
  38. 103 0
      sandbox/other/src/test/java/org/springframework/security/userdetails/ldap/AuthorityByPrefixAccountMapperTest.java
  39. 154 0
      sandbox/other/src/test/java/org/springframework/security/userdetails/ldap/ReplacingUserDetailsMapperTest.java
  40. 89 0
      sandbox/other/src/test/java/org/springframework/security/userdetails/ldap/UsernameFromPropertyAccountMapperTest.java
  41. 37 0
      sandbox/other/src/test/java/org/springframework/security/userdetails/preauth/AllTests.java
  42. 121 0
      sandbox/other/src/test/java/org/springframework/security/userdetails/preauth/UserDetailsMappingServiceWrapperTest.java
  43. 89 0
      sandbox/other/src/test/java/org/springframework/security/userdetails/preauth/UsernameFromPropertyAccountMapperTest.java
  44. 60 0
      sandbox/other/src/test/java/org/springframework/security/userdetails/preauth/UsernameFromRequestAccountMapperTest.java
  45. 33 0
      sandbox/other/src/test/java/org/springframework/security/util/AllTests.java
  46. 124 0
      sandbox/other/src/test/java/org/springframework/security/util/ServletUtilsTest.java
  47. 79 0
      sandbox/other/src/test/java/org/springframework/security/util/StringUtilsTest.java
  48. 51 0
      sandbox/other/src/test/java/org/springframework/security/vote/FirstDecisionBased.java

+ 36 - 0
sandbox/other/src/main/java/org/springframework/security/ui/preauth/AttributesSource.java

@@ -0,0 +1,36 @@
+/* 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 org.springframework.security.ui.preauth;
+
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * Source of the attributes associated with pre-authenticated authentication request. The attributes
+ * can be supplied in the cookies, request header, or property (configuration file).
+ * 
+ * @author Valery Tydykov
+ * 
+ */
+public interface AttributesSource {
+    /**
+     * Obtain attributes supplied in the request or property.
+     * 
+     * @param request with optional attributes
+     * @return Map<String, String> of attributes: name/value.
+     */
+    public Map obtainAttributes(HttpServletRequest request);
+}

+ 96 - 0
sandbox/other/src/main/java/org/springframework/security/ui/preauth/AttributesSourceWebAuthenticationDetailsSource.java

@@ -0,0 +1,96 @@
+/* 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 org.springframework.security.ui.preauth;
+
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.security.ui.AuthenticationDetailsSource;
+import org.springframework.security.ui.WebAuthenticationDetailsSource;
+import org.springframework.util.Assert;
+
+/**
+ * Implementation of {@link AuthenticationDetailsSource} which builds the details object from an
+ * <tt>HttpServletRequest</tt> object.
+ * <p>
+ * Uses <code>attributesSource</code> to obtain attributes from the request. Adds obtained
+ * attributes to created details object. The details object must be an instance of
+ * <tt>AuthenticationDetailsImpl</tt>, which has additional <tt>attributes</tt> property.
+ * 
+ * @author Valery Tydykov
+ */
+public class AttributesSourceWebAuthenticationDetailsSource extends WebAuthenticationDetailsSource
+        implements InitializingBean {
+
+    public AttributesSourceWebAuthenticationDetailsSource() {
+        super();
+        setClazz(AuthenticationDetailsImpl.class);
+    }
+
+    private AttributesSource attributesSource;
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.springframework.security.ui.WebAuthenticationDetailsSource#buildDetails(java.lang.Object)
+     */
+    public Object buildDetails(Object context) {
+        // build AuthenticationDetailsImpl object
+        Object result = super.buildDetails(context);
+
+        Assert.isInstanceOf(HttpServletRequest.class, context);
+        HttpServletRequest request = (HttpServletRequest) context;
+
+        // extract attributes from the request
+        Map attributes = this.getAttributesSource().obtainAttributes(request);
+
+        // add additional attributes to the AuthenticationDetailsImpl object
+        AuthenticationDetailsImpl authenticationDetails;
+        {
+            Assert.isInstanceOf(AuthenticationDetailsImpl.class, result);
+            authenticationDetails = (AuthenticationDetailsImpl) result;
+            // add attributes from the AttributesSource to the AuthenticationDetailsImpl object
+            authenticationDetails.getAttributes().putAll(attributes);
+        }
+
+        return authenticationDetails;
+    }
+
+    /**
+     * @return the attributesSource
+     */
+    public AttributesSource getAttributesSource() {
+        return this.attributesSource;
+    }
+
+    /**
+     * @param attributesSource the attributesSource to set
+     */
+    public void setAttributesSource(AttributesSource attributesSource) {
+        Assert.notNull(attributesSource, "attributesSource must not be null");
+        this.attributesSource = attributesSource;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
+     */
+    public void afterPropertiesSet() throws Exception {
+        Assert.notNull(this.attributesSource, "attributesSource must be set");
+    }
+}

+ 51 - 0
sandbox/other/src/main/java/org/springframework/security/ui/preauth/AuthenticationDetailsImpl.java

@@ -0,0 +1,51 @@
+/* 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 org.springframework.security.ui.preauth;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.springframework.security.ui.WebAuthenticationDetails;
+
+/**
+ * A holder of selected HTTP details related to a web authentication request.
+ * <p>
+ * Has additional <tt>attributes</tt> property.
+ * 
+ * @author Valery Tydykov
+ */
+public class AuthenticationDetailsImpl extends WebAuthenticationDetails {
+    public AuthenticationDetailsImpl(HttpServletRequest request) {
+        super(request);
+    }
+
+    private Map attributes = new HashMap();
+
+    /**
+     * @return the attributes
+     */
+    public Map getAttributes() {
+        return attributes;
+    }
+
+    /**
+     * @param attributes the attributes to set
+     */
+    public void setAttributes(Map attributes) {
+        this.attributes = attributes;
+    }
+}

+ 78 - 0
sandbox/other/src/main/java/org/springframework/security/ui/preauth/CookieAttributesSource.java

@@ -0,0 +1,78 @@
+/* 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 org.springframework.security.ui.preauth;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.security.util.ServletUtils;
+import org.springframework.util.Assert;
+
+/**
+ * Source of the attributes associated with pre-authenticated authentication request. The attributes
+ * can be supplied in the cookies. The keys for values to be extracted must be specified as a
+ * <tt>keys</tt> property.
+ * 
+ * @author Valery Tydykov
+ * 
+ */
+public class CookieAttributesSource implements AttributesSource, InitializingBean {
+
+    /**
+     * Logger for this class and subclasses
+     */
+    protected final Log logger = LogFactory.getLog(this.getClass());
+
+    // keys for values to be extracted
+    private List keys;
+
+    /**
+     * @return the keys
+     */
+    public List getKeys() {
+        return this.keys;
+    }
+
+    /**
+     * @param keys the keys to set
+     */
+    public void setKeys(List keys) {
+        this.keys = keys;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.springframework.security.ui.preauth.AttributesSource#obtainAttributes(javax.servlet.http.HttpServletRequest)
+     */
+    public Map obtainAttributes(HttpServletRequest request) {
+        Map attributes = ServletUtils.extractCookiesValues(request, this.getKeys());
+
+        if (this.logger.isDebugEnabled()) {
+            this.logger.debug("Obtained attributes=[" + attributes + "] from cookies");
+        }
+
+        return attributes;
+    }
+
+    public void afterPropertiesSet() throws Exception {
+        Assert.notNull(this.keys, "keys must be not null");
+    }
+}

+ 70 - 0
sandbox/other/src/main/java/org/springframework/security/ui/preauth/CookieUsernameSource.java

@@ -0,0 +1,70 @@
+/* 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 org.springframework.security.ui.preauth;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.security.util.ServletUtils;
+import org.springframework.util.Assert;
+
+/**
+ * Source of the username supplied with pre-authenticated authentication request as cookie. The
+ * <tt>usernameKey</tt> property must be set, which will be used to extract the username from the
+ * cookie.
+ * 
+ * @author Valery Tydykov
+ * 
+ */
+public class CookieUsernameSource implements UsernameSource, InitializingBean {
+    /**
+     * Logger for this class and subclasses
+     */
+    protected final Log logger = LogFactory.getLog(this.getClass());
+
+    // username key
+    private String usernameKey;
+
+    public String obtainUsername(HttpServletRequest request) {
+        String username = ServletUtils.findCookieValue(request, getUsernameKey());
+
+        if (this.logger.isDebugEnabled()) {
+            this.logger.debug("Obtained username=[" + username + "] from cookie");
+        }
+
+        return username;
+    }
+
+    /**
+     * @return the usernameKey
+     */
+    public String getUsernameKey() {
+        return usernameKey;
+    }
+
+    /**
+     * @param usernameKey the usernameKey to set
+     */
+    public void setUsernameKey(String usernameKey) {
+        Assert.hasLength(usernameKey, "usernameKey must be not empty");
+        this.usernameKey = usernameKey;
+    }
+
+    public void afterPropertiesSet() throws Exception {
+        Assert.hasLength(this.usernameKey, "usernameKey must be not empty");
+    }
+}

+ 78 - 0
sandbox/other/src/main/java/org/springframework/security/ui/preauth/HeaderAttributesSource.java

@@ -0,0 +1,78 @@
+/* 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 org.springframework.security.ui.preauth;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.security.util.ServletUtils;
+import org.springframework.util.Assert;
+
+/**
+ * Source of the attributes associated with pre-authenticated authentication request. The attributes
+ * can be supplied in the request header. The keys for values to be extracted must be specified as a
+ * <tt>keys</tt> property.
+ * 
+ * @author Valery Tydykov
+ * 
+ */
+public class HeaderAttributesSource implements AttributesSource, InitializingBean {
+
+    /**
+     * Logger for this class and subclasses
+     */
+    protected final Log logger = LogFactory.getLog(this.getClass());
+
+    // keys for values to be extracted
+    private List keys;
+
+    /**
+     * @return the keys
+     */
+    public List getKeys() {
+        return this.keys;
+    }
+
+    /**
+     * @param keys the keys to set
+     */
+    public void setKeys(List keys) {
+        this.keys = keys;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.springframework.security.ui.preauth.AttributesSource#obtainAttributes(javax.servlet.http.HttpServletRequest)
+     */
+    public Map obtainAttributes(HttpServletRequest request) {
+        Map attributes = ServletUtils.extractHeaderValues(request, this.getKeys());
+
+        if (this.logger.isDebugEnabled()) {
+            this.logger.debug("Obtained attributes=[" + attributes + "] from header");
+        }
+
+        return attributes;
+    }
+
+    public void afterPropertiesSet() throws Exception {
+        Assert.notNull(this.keys, "keys must be not null");
+    }
+}

+ 69 - 0
sandbox/other/src/main/java/org/springframework/security/ui/preauth/HeaderUsernameSource.java

@@ -0,0 +1,69 @@
+/* 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 org.springframework.security.ui.preauth;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.util.Assert;
+
+/**
+ * Source of the username supplied with pre-authenticated authentication request as header value.
+ * The <tt>usernameKey</tt> property must be set, which will be used to extract the username from
+ * the header.
+ * 
+ * @author Valery Tydykov
+ * 
+ */
+public class HeaderUsernameSource implements UsernameSource, InitializingBean {
+    /**
+     * Logger for this class and subclasses
+     */
+    protected final Log logger = LogFactory.getLog(this.getClass());
+
+    // username key
+    private String usernameKey;
+
+    public String obtainUsername(HttpServletRequest request) {
+        String userName = request.getHeader(getUsernameKey());
+
+        if (this.logger.isDebugEnabled()) {
+            this.logger.debug("Obtained username=[" + userName + "] from header");
+        }
+
+        return userName;
+    }
+
+    /**
+     * @return the usernameKey
+     */
+    public String getUsernameKey() {
+        return usernameKey;
+    }
+
+    /**
+     * @param usernameKey the usernameKey to set
+     */
+    public void setUsernameKey(String usernameKey) {
+        Assert.hasLength(usernameKey, "usernameKey must be not empty");
+        this.usernameKey = usernameKey;
+    }
+
+    public void afterPropertiesSet() throws Exception {
+        Assert.hasLength(this.usernameKey, "usernameKey must be not empty");
+    }
+}

+ 67 - 0
sandbox/other/src/main/java/org/springframework/security/ui/preauth/PropertyAttributesSource.java

@@ -0,0 +1,67 @@
+/* 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 org.springframework.security.ui.preauth;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Source of the attributes associated with pre-authenticated authentication request. The attributes
+ * can be supplied in the <tt>attributes</tt> property (configuration file).
+ * 
+ * @author Valery Tydykov
+ * 
+ */
+public class PropertyAttributesSource implements AttributesSource {
+
+    /**
+     * Logger for this class and subclasses
+     */
+    protected final Log logger = LogFactory.getLog(this.getClass());
+
+    private Map attributes = new HashMap();
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.springframework.security.ui.preauth.AttributesSource#obtainAttributes(javax.servlet.http.HttpServletRequest)
+     */
+    public Map obtainAttributes(HttpServletRequest request) {
+        if (this.logger.isDebugEnabled()) {
+            this.logger.debug("Obtained attributes=[" + attributes + "] from property");
+        }
+
+        return attributes;
+    }
+
+    /**
+     * @return the attributes
+     */
+    public Map getAttributes() {
+        return this.attributes;
+    }
+
+    /**
+     * @param attributes the attributes to set
+     */
+    public void setAttributes(Map attributes) {
+        this.attributes = attributes;
+    }
+}

+ 77 - 0
sandbox/other/src/main/java/org/springframework/security/ui/preauth/RemoteUserUsernameSource.java

@@ -0,0 +1,77 @@
+/* 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 org.springframework.security.ui.preauth;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.security.util.StringUtils;
+
+/**
+ * Source of the username supplied with pre-authenticated authentication request as remote user
+ * header value. Optionally can strip prefix: "domain\\username" -> "username", if
+ * <tt>stripPrefix</tt> property value is "true".
+ * 
+ * @author Valery Tydykov
+ * 
+ */
+public class RemoteUserUsernameSource implements UsernameSource {
+    /**
+     * Logger for this class and subclasses
+     */
+    protected final Log logger = LogFactory.getLog(this.getClass());
+
+    private boolean stripPrefix = true;
+
+    public String obtainUsername(HttpServletRequest request) {
+        String username = request.getRemoteUser();
+
+        if (this.isStripPrefix()) {
+            username = this.stripPrefix(username);
+        }
+
+        if (this.logger.isDebugEnabled()) {
+            this.logger.debug("Obtained username=[" + username + "] from remote user");
+        }
+
+        return username;
+    }
+
+    private String stripPrefix(String userName) {
+        if (!StringUtils.notNull(userName).equals("")) {
+            int index = userName.lastIndexOf("\\");
+            if (index != -1) {
+                userName = userName.substring(index + 1);
+            }
+        }
+
+        return userName;
+    }
+
+    /**
+     * @return the stripPrefix
+     */
+    public boolean isStripPrefix() {
+        return stripPrefix;
+    }
+
+    /**
+     * @param stripPrefix the stripPrefix to set
+     */
+    public void setStripPrefix(boolean stripPrefix) {
+        this.stripPrefix = stripPrefix;
+    }
+}

+ 68 - 0
sandbox/other/src/main/java/org/springframework/security/ui/preauth/RequestParameterUsernameSource.java

@@ -0,0 +1,68 @@
+/* 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 org.springframework.security.ui.preauth;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.util.Assert;
+
+/**
+ * Source of the username supplied with pre-authenticated authentication request as request
+ * parameter. The <tt>usernameKey</tt> property must be set, which will be used to extract the
+ * username from the request parameter.
+ * 
+ * @author Valery Tydykov
+ * 
+ */
+public class RequestParameterUsernameSource implements UsernameSource, InitializingBean {
+    /**
+     * Logger for this class and subclasses
+     */
+    protected final Log logger = LogFactory.getLog(this.getClass());
+
+    private String usernameKey;
+
+    public String obtainUsername(HttpServletRequest request) {
+        String userName = request.getParameter(getUsernameKey());
+
+        if (this.logger.isDebugEnabled()) {
+            this.logger.debug("Obtained username=[" + userName + "] from request parameter");
+        }
+
+        return userName;
+    }
+
+    /**
+     * @return the usernameKey
+     */
+    public String getUsernameKey() {
+        return this.usernameKey;
+    }
+
+    /**
+     * @param usernameKey the usernameKey to set
+     */
+    public void setUsernameKey(String usernameKey) {
+        Assert.hasLength(usernameKey, "usernameKey must be not empty");
+        this.usernameKey = usernameKey;
+    }
+
+    public void afterPropertiesSet() throws Exception {
+        Assert.hasLength(usernameKey, "usernameKey must be not empty");
+    }
+}

+ 35 - 0
sandbox/other/src/main/java/org/springframework/security/ui/preauth/UsernameSource.java

@@ -0,0 +1,35 @@
+/* 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 org.springframework.security.ui.preauth;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * Source of the username supplied with pre-authenticated authentication request. The username can
+ * be supplied in the request: in cookie, request header, request parameter or as
+ * ServletRequest.getRemoteUser().
+ * 
+ * @author Valery Tydykov
+ * 
+ */
+public interface UsernameSource {
+    /**
+     * Obtain username supplied in the request.
+     * 
+     * @param request with username
+     * @return username or null if not supplied
+     */
+    public String obtainUsername(HttpServletRequest request);
+}

+ 103 - 0
sandbox/other/src/main/java/org/springframework/security/ui/preauth/UsernameSourcePreAuthenticatedProcessingFilter.java

@@ -0,0 +1,103 @@
+/* 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 org.springframework.security.ui.preauth;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.springframework.security.ui.FilterChainOrder;
+import org.springframework.util.Assert;
+
+/**
+ * Flexible pre-authenticated filter which obtains username and other values supplied in the request
+ * (in headers, or in cookies, or in HttpServletRequest.getRemoteUser()), for use with SSO systems.
+ * <p>
+ * Has additional <tt>usernameSource</tt> property.
+ * <p>
+ * Will create Authentication object (and attach it to the SecurityContextHolder), if such object
+ * does not exist yet.
+ * <p>
+ * As with most pre-authenticated scenarios, it is essential that the external authentication system
+ * is set up correctly as this filter does no authentication whatsoever. All the protection is
+ * assumed to be provided externally and if this filter is included inappropriately in a
+ * configuration, it would be possible to assume the identity of a user merely by setting the
+ * correct header name. This also means it should not be used in combination with other Spring
+ * Security authentication mechanisms such as form login, as this would imply there was a means of
+ * bypassing the external system which would be risky.
+ * <p>
+ * 
+ * @author Valery Tydykov
+ */
+public class UsernameSourcePreAuthenticatedProcessingFilter extends
+        AbstractPreAuthenticatedProcessingFilter {
+    private UsernameSource usernameSource;
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.springframework.ui.AbstractProcessingFilter#afterPropertiesSet()
+     */
+    public void afterPropertiesSet() throws Exception {
+        super.afterPropertiesSet();
+
+        Assert.notNull(this.getUsernameSource(), "usernameSource must be set");
+    }
+
+    /**
+     * @return the usernameSource
+     */
+    public UsernameSource getUsernameSource() {
+        return usernameSource;
+    }
+
+    /**
+     * @param usernameSource the usernameSource to set
+     */
+    public void setUsernameSource(UsernameSource usernameSource) {
+        Assert.notNull(usernameSource, "usernameSource must be specified");
+
+        this.usernameSource = usernameSource;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.springframework.security.ui.preauth.AbstractPreAuthenticatedProcessingFilter#getPreAuthenticatedCredentials(javax.servlet.http.HttpServletRequest)
+     */
+    protected Object getPreAuthenticatedCredentials(HttpServletRequest request) {
+        // no password - user is already authenticated
+        return "NONE";
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.springframework.security.ui.preauth.AbstractPreAuthenticatedProcessingFilter#getPreAuthenticatedPrincipal(javax.servlet.http.HttpServletRequest)
+     */
+    protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) {
+        // obtain username from request
+        String username = this.getUsernameSource().obtainUsername(request);
+
+        return username;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.springframework.core.Ordered#getOrder()
+     */
+    public int getOrder() {
+        return FilterChainOrder.PRE_AUTH_FILTER;
+    }
+}

+ 38 - 0
sandbox/other/src/main/java/org/springframework/security/userdetails/ldap/AccountMapper.java

@@ -0,0 +1,38 @@
+/* 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 org.springframework.security.userdetails.ldap;
+
+import org.springframework.security.AuthenticationException;
+import org.springframework.security.userdetails.UserDetails;
+
+/**
+ * Maps user (loaded from the primary user accounts repository, e.g. LDAP) to username in secondary
+ * user accounts repository.
+ * 
+ * 
+ * @author Valery Tydykov
+ * 
+ */
+public interface AccountMapper {
+
+    /**
+     * Map user to username in secondary user accounts repository.
+     * 
+     * @param user, loaded from the primary user accounts repository.
+     * @return username for secondary user accounts repository.
+     * @throws AuthenticationException if can not map given user.
+     */
+    String map(UserDetails user) throws AuthenticationException;
+}

+ 91 - 0
sandbox/other/src/main/java/org/springframework/security/userdetails/ldap/AuthorityByPrefixAccountMapper.java

@@ -0,0 +1,91 @@
+/* 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 org.springframework.security.userdetails.ldap;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.security.AuthenticationException;
+import org.springframework.security.GrantedAuthority;
+import org.springframework.security.userdetails.UserDetails;
+import org.springframework.util.Assert;
+
+/**
+ * Maps user (loaded from the primary user accounts repository, e.g. LDAP) to username in secondary
+ * user accounts repository. Tries to find user's authority with name starting with
+ * <tt>authorityPrefix</tt>.
+ * 
+ * 
+ * @author Valery Tydykov
+ * 
+ */
+public class AuthorityByPrefixAccountMapper implements AccountMapper, InitializingBean {
+    /**
+     * Logger for this class and subclasses
+     */
+    protected final Log logger = LogFactory.getLog(this.getClass());
+
+    // prefix of the authority to find
+    private String authorityPrefix;
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.springframework.security.userdetails.ldap.AccountMapper#map(org.springframework.security.userdetails.UserDetails)
+     */
+    public String map(UserDetails user) throws AuthenticationException {
+        if (this.logger.isDebugEnabled()) {
+            this.logger.debug("Mapping account=[" + user.getUsername()
+                    + "]: search authorities for authority prefix=[" + this.getAuthorityPrefix()
+                    + "]");
+        }
+
+        // search authorities for authority prefix
+        GrantedAuthority[] authorities = user.getAuthorities();
+        for (int i = 0; i < authorities.length; i++) {
+            String authority = authorities[i].getAuthority();
+            if (authority.startsWith(this.getAuthorityPrefix())) {
+                if (this.logger.isDebugEnabled()) {
+                    this.logger.debug("Authority found=[" + authority + "]");
+                }
+
+                return authority;
+            }
+        }
+
+        // not found
+        // TODO message with UserDetails and authorityPrefix?
+        throw new AuthorityNotFoundException(null);
+    }
+
+    /**
+     * @return the authorityPrefix
+     */
+    public String getAuthorityPrefix() {
+        return authorityPrefix;
+    }
+
+    /**
+     * @param authorityPrefix the authorityPrefix to set
+     */
+    public void setAuthorityPrefix(String authorityPrefix) {
+        Assert.hasLength(authorityPrefix, "authorityPrefix must be not empty");
+        this.authorityPrefix = authorityPrefix;
+    }
+
+    public void afterPropertiesSet() throws Exception {
+        Assert.hasLength(authorityPrefix, "authorityPrefix must be not empty");
+    }
+}

+ 35 - 0
sandbox/other/src/main/java/org/springframework/security/userdetails/ldap/AuthorityNotFoundException.java

@@ -0,0 +1,35 @@
+/* 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 org.springframework.security.userdetails.ldap;
+
+import org.springframework.security.AuthenticationException;
+import org.springframework.security.GrantedAuthority;
+
+/**
+ * Thrown if an {@link AccountMapper} implementation cannot find a {@link GrantedAuthority} by the
+ * given prefix.
+ * 
+ * @author Valery Tydykov
+ */
+public class AuthorityNotFoundException extends AuthenticationException {
+
+    public AuthorityNotFoundException(String msg, Throwable t) {
+        super(msg, t);
+    }
+
+    public AuthorityNotFoundException(String msg) {
+        super(msg);
+    }
+}

+ 133 - 0
sandbox/other/src/main/java/org/springframework/security/userdetails/ldap/ReplacingUserDetailsMapper.java

@@ -0,0 +1,133 @@
+/* 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 org.springframework.security.userdetails.ldap;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.dao.DataAccessException;
+import org.springframework.ldap.core.DirContextOperations;
+import org.springframework.security.AuthenticationException;
+import org.springframework.security.AuthenticationServiceException;
+import org.springframework.security.GrantedAuthority;
+import org.springframework.security.userdetails.UserDetails;
+import org.springframework.security.userdetails.UserDetailsService;
+import org.springframework.util.Assert;
+
+/**
+ * The context mapper used by the LDAP authentication provider to create an LDAP user object.
+ * Creates the final <tt>UserDetails</tt> object that will be returned by the provider once the
+ * user has been authenticated, replacing the original <tt>UserDetails</tt> object. Has additional
+ * properties <tt>userDetailsService</tt> and <tt>accountMapper</tt>, which are used to map
+ * original user to username in secondary repository and to retrieve UserDetails from the secondary
+ * account repository.
+ * 
+ * 
+ * @author Valery Tydykov
+ * 
+ */
+public class ReplacingUserDetailsMapper extends LdapUserDetailsMapper implements InitializingBean {
+
+    /**
+     * Logger for this class and subclasses
+     */
+    protected final Log logger = LogFactory.getLog(this.getClass());
+
+    /**
+     * service which will be used to retrieve UserDetails from the secondary account repository
+     */
+    private UserDetailsService userDetailsService;
+
+    /**
+     * mapper which will be used to map original user to username in secondary repository
+     */
+    private AccountMapper accountMapper;
+
+    /**
+     * @return the userDetailsService
+     */
+    public UserDetailsService getUserDetailsService() {
+        return this.userDetailsService;
+    }
+
+    /**
+     * @param userDetailsService the userDetailsService to set
+     */
+    public void setUserDetailsService(UserDetailsService userDetailsService) {
+        Assert.notNull(userDetailsService, "UserDetailsService must be supplied");
+        this.userDetailsService = userDetailsService;
+    }
+
+    /**
+     * @return the accountMapper
+     */
+    public AccountMapper getAccountMapper() {
+        return this.accountMapper;
+    }
+
+    /**
+     * @param accountMapper the accountMapper to set
+     */
+    public void setAccountMapper(AccountMapper accountMapper) {
+        Assert.notNull(accountMapper, "AccountMapper must be supplied");
+        this.accountMapper = accountMapper;
+    }
+
+    public void afterPropertiesSet() throws Exception {
+        Assert.notNull(userDetailsService, "UserDetailsService must be supplied");
+        Assert.notNull(accountMapper, "AccountMapper must be supplied");
+    }
+
+    /*
+     * Creates the final <tt>UserDetails</tt> object that will be returned by the provider once
+     * the user has been authenticated, replacing the original <tt>UserDetails</tt> object.
+     */
+    public UserDetails mapUserFromContext(DirContextOperations ctx, String username,
+            GrantedAuthority[] authorities) {
+        UserDetails userOriginal = super.mapUserFromContext(ctx, username, authorities);
+
+        if (this.logger.isDebugEnabled()) {
+            this.logger.debug("Replacing UserDetails with username=[" + userOriginal.getUsername()
+                    + "]");
+        }
+
+        // map user to secondary username
+        String usernameMapped = this.getAccountMapper().map(userOriginal);
+
+        // replace original UserDetails with the secondary UserDetails
+        UserDetails user = retrieveUser(usernameMapped);
+
+        return user;
+    }
+
+    protected UserDetails retrieveUser(String username) throws AuthenticationException {
+        UserDetails loadedUser;
+
+        // retrieve UserDetails from the secondary account repository
+        try {
+            loadedUser = this.getUserDetailsService().loadUserByUsername(username);
+        } catch (DataAccessException repositoryProblem) {
+            throw new AuthenticationServiceException(repositoryProblem.getMessage(),
+                repositoryProblem);
+        }
+
+        if (loadedUser == null) {
+            throw new AuthenticationServiceException(
+                "UserDetailsService returned null, which is an interface contract violation");
+        }
+
+        return loadedUser;
+    }
+}

+ 69 - 0
sandbox/other/src/main/java/org/springframework/security/userdetails/ldap/UsernameFromPropertyAccountMapper.java

@@ -0,0 +1,69 @@
+/* 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 org.springframework.security.userdetails.ldap;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.security.AuthenticationException;
+import org.springframework.security.userdetails.UserDetails;
+import org.springframework.util.Assert;
+
+/**
+ * Maps user (loaded from the primary user accounts repository, e.g. LDAP) to username in secondary
+ * user accounts repository. Maps all users to the same <tt>username</tt>.
+ * 
+ * 
+ * @author Valery Tydykov
+ * 
+ */
+public class UsernameFromPropertyAccountMapper implements AccountMapper, InitializingBean {
+    /**
+     * Logger for this class and subclasses
+     */
+    protected final Log logger = LogFactory.getLog(this.getClass());
+
+    // single username to map to
+    private String username;
+
+    public String map(UserDetails user) throws AuthenticationException {
+        if (this.logger.isDebugEnabled()) {
+            this.logger.debug("Mapping account=[" + user.getUsername() + "] to account=["
+                    + this.getUsername() + "]");
+        }
+
+        // map all users to the same userName
+        return this.getUsername();
+    }
+
+    public void afterPropertiesSet() throws Exception {
+        Assert.hasLength(username, "userName must be not empty");
+    }
+
+    /**
+     * @return the username
+     */
+    public String getUsername() {
+        return this.username;
+    }
+
+    /**
+     * @param username the username to set
+     */
+    public void setUsername(String username) {
+        Assert.hasLength(username, "userName must be not empty");
+        this.username = username;
+    }
+}

+ 47 - 0
sandbox/other/src/main/java/org/springframework/security/userdetails/ldap/UsernameFromUserdetailsAccountMapper.java

@@ -0,0 +1,47 @@
+/* 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 org.springframework.security.userdetails.ldap;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.security.AuthenticationException;
+import org.springframework.security.userdetails.UserDetails;
+
+/**
+ * Maps user (loaded from the primary user accounts repository, e.g. LDAP) to username in secondary
+ * user accounts repository. One-to-one mapping, e.g. maps user with <tt>username</tt> to user
+ * with the same <tt>username</tt>.
+ * 
+ * @author Joel Emery
+ * 
+ */
+public class UsernameFromUserdetailsAccountMapper implements AccountMapper {
+    /**
+     * Logger for this class and subclasses
+     */
+    protected final Log logger = LogFactory.getLog(this.getClass());
+
+    public String map(UserDetails user) throws AuthenticationException {
+        // get username from UserDetails
+        String username = user.getUsername();
+
+        if (this.logger.isDebugEnabled()) {
+            this.logger.debug("Mapping account=[" + username + "] to account=[" + username + "]");
+        }
+
+        // map cn to userName
+        return username;
+    }
+}

+ 37 - 0
sandbox/other/src/main/java/org/springframework/security/userdetails/preauth/AccountMapper.java

@@ -0,0 +1,37 @@
+/* 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 org.springframework.security.userdetails.preauth;
+
+import org.springframework.security.Authentication;
+import org.springframework.security.AuthenticationException;
+
+/**
+ * Maps username (from the primary user accounts repository, e.g. LDAP) to username in secondary
+ * user accounts repository.
+ * 
+ * 
+ * @author Valery Tydykov
+ * 
+ */
+public interface AccountMapper {
+    /**
+     * Map username to username in secondary user accounts repository.
+     * 
+     * @param authenticationRequest, with username from the primary user accounts repository.
+     * @return username for secondary user accounts repository.
+     * @throws AuthenticationException if cannot map given username.
+     */
+    String map(Authentication authenticationRequest) throws AuthenticationException;
+}

+ 96 - 0
sandbox/other/src/main/java/org/springframework/security/userdetails/preauth/UserDetailsMappingServiceWrapper.java

@@ -0,0 +1,96 @@
+/* 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 org.springframework.security.userdetails.preauth;
+
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.dao.DataAccessException;
+import org.springframework.security.Authentication;
+import org.springframework.security.userdetails.AuthenticationUserDetailsService;
+import org.springframework.security.userdetails.UserDetails;
+import org.springframework.security.userdetails.UserDetailsService;
+import org.springframework.security.userdetails.UsernameNotFoundException;
+import org.springframework.util.Assert;
+
+/**
+ * This implementation for AuthenticationUserDetailsService wraps a regular Spring Security
+ * UserDetailsService implementation, to retrieve a UserDetails object based on the mapping of the
+ * user name contained in a PreAuthenticatedAuthenticationToken to user name expected by the
+ * userDetailsService.
+ * 
+ * @author Valery Tydykov
+ */
+public class UserDetailsMappingServiceWrapper implements AuthenticationUserDetailsService,
+        InitializingBean {
+    private UserDetailsService userDetailsService;
+
+    private AccountMapper accountMapper;
+
+    /**
+     * Check whether all required properties have been set.
+     * 
+     * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
+     */
+    public void afterPropertiesSet() throws Exception {
+        Assert.notNull(this.userDetailsService, "UserDetailsService must be set");
+        Assert.notNull(this.accountMapper, "AccountMapper must be set");
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.springframework.security.userdetails.AuthenticationUserDetailsService#loadUserDetails(org.springframework.security.Authentication)
+     */
+    public UserDetails loadUserDetails(Authentication authentication)
+            throws UsernameNotFoundException, DataAccessException {
+
+        // Determine username for the secondary authentication repository
+        String username = this.getAccountMapper().map(authentication);
+
+        // get the UserDetails object from the wrapped UserDetailsService implementation
+        return userDetailsService.loadUserByUsername(username);
+    }
+
+    /**
+     * Set the wrapped UserDetailsService implementation
+     * 
+     * @param aUserDetailsService The wrapped UserDetailsService to set
+     */
+    public void setUserDetailsService(UserDetailsService userDetailsService) {
+        Assert.notNull(userDetailsService, "UserDetailsService must not be null");
+        this.userDetailsService = userDetailsService;
+    }
+
+    /**
+     * @return the accountMapper
+     */
+    public AccountMapper getAccountMapper() {
+        return this.accountMapper;
+    }
+
+    /**
+     * @param accountMapper the accountMapper to set
+     */
+    public void setAccountMapper(AccountMapper accountMapper) {
+        Assert.notNull(accountMapper, "accountMapper must not be null");
+        this.accountMapper = accountMapper;
+    }
+
+    /**
+     * @return the userDetailsService
+     */
+    public UserDetailsService getUserDetailsService() {
+        return this.userDetailsService;
+    }
+}

+ 74 - 0
sandbox/other/src/main/java/org/springframework/security/userdetails/preauth/UsernameFromPropertyAccountMapper.java

@@ -0,0 +1,74 @@
+/* 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 org.springframework.security.userdetails.preauth;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.security.Authentication;
+import org.springframework.security.AuthenticationException;
+import org.springframework.util.Assert;
+
+/**
+ * Maps username (from the primary user accounts repository, e.g. LDAP) to username in secondary
+ * user accounts repository. Maps all users to the same <tt>username</tt>.
+ * 
+ * 
+ * @author Valery Tydykov
+ * 
+ */
+public class UsernameFromPropertyAccountMapper implements AccountMapper, InitializingBean {
+    /**
+     * Logger for this class and subclasses
+     */
+    protected final Log logger = LogFactory.getLog(this.getClass());
+
+    // single username to map to
+    private String username;
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.springframework.security.providers.preauth.AccountMapper#map(org.springframework.security.Authentication)
+     */
+    public String map(Authentication authenticationRequest) throws AuthenticationException {
+        if (this.logger.isDebugEnabled()) {
+            this.logger.debug("Mapping account=[" + authenticationRequest.getName()
+                    + "] to account=[" + this.getUsername() + "]");
+        }
+
+        // map all users to the same userName
+        return this.getUsername();
+    }
+
+    /**
+     * @return the username
+     */
+    public String getUsername() {
+        return username;
+    }
+
+    /**
+     * @param username the username to set
+     */
+    public void setUsername(String username) {
+        Assert.hasLength(username, "username must be not empty");
+        this.username = username;
+    }
+
+    public void afterPropertiesSet() throws Exception {
+        Assert.hasLength(username, "username must be set");
+    }
+}

+ 51 - 0
sandbox/other/src/main/java/org/springframework/security/userdetails/preauth/UsernameFromRequestAccountMapper.java

@@ -0,0 +1,51 @@
+/* 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 org.springframework.security.userdetails.preauth;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.security.Authentication;
+import org.springframework.security.AuthenticationException;
+
+/**
+ * Maps username (from the primary user accounts repository, e.g. LDAP) to username in secondary
+ * user accounts repository. Uses username supplied in the <tt>authenticationRequest</tt> as
+ * secondary authentication storage username.
+ * 
+ * 
+ * @author Valery Tydykov
+ * 
+ */
+public class UsernameFromRequestAccountMapper implements AccountMapper {
+    /**
+     * Logger for this class and subclasses
+     */
+    protected final Log logger = LogFactory.getLog(this.getClass());
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.springframework.security.providers.preauth.AccountMapper#map(org.springframework.security.Authentication)
+     */
+    public String map(Authentication authenticationRequest) throws AuthenticationException {
+        String username = authenticationRequest.getName();
+        if (this.logger.isDebugEnabled()) {
+            this.logger.debug("Mapping account=[" + username + "] to account=[" + username + "]");
+        }
+
+        // use SSO username as secondary authentication storage username
+        return username;
+    }
+}

+ 99 - 0
sandbox/other/src/main/java/org/springframework/security/util/ServletUtils.java

@@ -0,0 +1,99 @@
+/* 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 org.springframework.security.util;
+
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+
+import org.springframework.util.Assert;
+
+/**
+ * Servlet API-related methods.
+ * 
+ * @author Valery Tydykov
+ * 
+ */
+public final class ServletUtils {
+    /**
+     * This is a static class that should not be instantiated.
+     */
+    private ServletUtils() throws InstantiationException {
+    }
+
+    public static Map extractHeaderValues(HttpServletRequest request, List keys) {
+        Assert.notNull(request);
+        Assert.notNull(keys);
+
+        final Map headerValues = new HashMap();
+        // for each header name/value
+        for (Enumeration en = request.getHeaderNames(); en.hasMoreElements();) {
+            String key = (String) en.nextElement();
+
+            if (keys.contains(key)) {
+                // found key in the list of the keys to return
+                String value = request.getHeader(key);
+                headerValues.put(key, value);
+            }
+        }
+
+        return headerValues;
+    }
+
+    public static Map extractCookiesValues(HttpServletRequest request, List keys) {
+        Assert.notNull(request);
+        Assert.notNull(keys);
+
+        final Map cookiesValues = new HashMap();
+        final Cookie[] cookies = request.getCookies();
+        if (cookies != null) {
+            // for each cookie
+            for (int i = 0; i < cookies.length; i++) {
+                String key = cookies[i].getName();
+
+                if (keys.contains(key)) {
+                    // found key in the list of the keys to return
+                    String value = cookies[i].getValue();
+                    cookiesValues.put(key, value);
+                }
+            }
+        }
+
+        return cookiesValues;
+    }
+
+    public static String findCookieValue(final HttpServletRequest request, final String key) {
+        Assert.notNull(request);
+
+        String value = null;
+        final Cookie[] cookies = request.getCookies();
+        if (cookies != null) {
+            // find cookie key
+            for (int i = 0; i < cookies.length; i++) {
+                if (StringUtils.notNull(cookies[i].getName()).equals(key)) {
+                    // cookie key found
+                    value = cookies[i].getValue();
+                    break;
+                }
+            }
+        }
+
+        return value;
+    }
+}

+ 69 - 0
sandbox/other/src/main/java/org/springframework/security/util/StringUtils.java

@@ -0,0 +1,69 @@
+/* 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 org.springframework.security.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * String manipulation methods.
+ * 
+ * @author Valery Tydykov
+ * 
+ */
+public final class StringUtils {
+
+    /**
+     * This is a static class that should not be instantiated.
+     */
+    private StringUtils() throws InstantiationException {
+    }
+
+    /**
+     * Tokenizes source string using another string as separator.
+     * 
+     * @param source source string
+     * @param separator separator string
+     * @return List of tokens found in the source string.
+     */
+    public static List tokenizeString(String source, String separator) {
+        List tokens = new ArrayList();
+        if (source != null && source.length() > 0) {
+            while (source.indexOf(separator) != -1) {
+                int index = source.indexOf(separator);
+                tokens.add(source.substring(0, index));
+                source = source.substring(index + separator.length());
+            }
+            tokens.add(source);
+        }
+        return tokens;
+    }
+
+    /**
+     * Make sure a string is not null.
+     * 
+     * @param object string, might be null
+     * @return empty string if the original was null or not String, else the original
+     */
+    public static String notNull(Object object) {
+        if (object == null) {
+            return "";
+        } else if (!(object instanceof String)) {
+            return String.valueOf(object);
+        } else {
+            return (String) object;
+        }
+    }
+}

+ 32 - 0
sandbox/other/src/test/java/org/springframework/security/ui/AllTests.java

@@ -0,0 +1,32 @@
+/* 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 org.springframework.security.ui;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+public class AllTests extends TestCase {
+
+    public AllTests(String s) {
+        super(s);
+    }
+
+    public static Test suite() {
+        TestSuite suite = new TestSuite();
+        suite.addTest(org.springframework.security.ui.preauth.AllTests.suite());
+        return suite;
+    }
+}

+ 47 - 0
sandbox/other/src/test/java/org/springframework/security/ui/preauth/AllTests.java

@@ -0,0 +1,47 @@
+/* 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 org.springframework.security.ui.preauth;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+public class AllTests extends TestCase {
+
+    public AllTests(String s) {
+        super(s);
+    }
+
+    public static Test suite() {
+        TestSuite suite = new TestSuite();
+        suite
+            .addTestSuite(org.springframework.security.ui.preauth.AttributesSourceWebAuthenticationDetailsSourceTest.class);
+        suite
+            .addTestSuite(org.springframework.security.ui.preauth.CookieAttributesSourceTest.class);
+        suite.addTestSuite(org.springframework.security.ui.preauth.CookieUsernameSourceTest.class);
+        suite
+            .addTestSuite(org.springframework.security.ui.preauth.HeaderAttributesSourceTest.class);
+        suite.addTestSuite(org.springframework.security.ui.preauth.HeaderUsernameSourceTest.class);
+        suite
+            .addTestSuite(org.springframework.security.ui.preauth.PropertyAttributesSourceTest.class);
+        suite
+            .addTestSuite(org.springframework.security.ui.preauth.RemoteUserUsernameSourceTest.class);
+        suite
+            .addTestSuite(org.springframework.security.ui.preauth.RequestParameterUsernameSourceTest.class);
+        suite
+            .addTestSuite(org.springframework.security.ui.preauth.UsernameSourcePreAuthenticatedProcessingFilterTest.class);
+        return suite;
+    }
+}

+ 176 - 0
sandbox/other/src/test/java/org/springframework/security/ui/preauth/AttributesSourceWebAuthenticationDetailsSourceTest.java

@@ -0,0 +1,176 @@
+/**
+ * 
+ */
+package org.springframework.security.ui.preauth;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.Cookie;
+
+import junit.framework.TestCase;
+
+import org.springframework.mock.web.MockHttpServletRequest;
+
+/**
+ * @author Valery Tydykov
+ * 
+ */
+public class AttributesSourceWebAuthenticationDetailsSourceTest extends TestCase {
+
+    AttributesSourceWebAuthenticationDetailsSource authenticationDetailsSource;
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see junit.framework.TestCase#setUp()
+     */
+    protected void setUp() throws Exception {
+        authenticationDetailsSource = new AttributesSourceWebAuthenticationDetailsSource();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see junit.framework.TestCase#tearDown()
+     */
+    protected void tearDown() throws Exception {
+        authenticationDetailsSource = null;
+    }
+
+    /**
+     * Test method for
+     * {@link org.springframework.security.ui.preauth.AttributesSourceWebAuthenticationDetailsSource#buildDetails(java.lang.Object)}.
+     */
+    public final void testBuildDetailsObjectHeader() {
+        authenticationDetailsSource.setClazz(AuthenticationDetailsImpl.class);
+
+        String key1 = "key1";
+        String value1 = "value1";
+        String key2 = "key2";
+        String value2 = "value2";
+        String key3 = "key3";
+        String value3 = "value3";
+
+        {
+            HeaderAttributesSource attributesSource = new HeaderAttributesSource();
+
+            {
+                List keys = new ArrayList();
+                keys.add(key1);
+                keys.add(key2);
+                keys.add(key3);
+                attributesSource.setKeys(keys);
+            }
+
+            authenticationDetailsSource.setAttributesSource(attributesSource);
+        }
+
+        MockHttpServletRequest request = new MockHttpServletRequest();
+        request.addHeader(key1, value1);
+        request.addHeader(key2, value2);
+        request.addHeader(key3, value3);
+        AuthenticationDetailsImpl authenticationDetails = (AuthenticationDetailsImpl) authenticationDetailsSource
+            .buildDetails(request);
+
+        assertEquals(value1, authenticationDetails.getAttributes().get(key1));
+        assertEquals(value2, authenticationDetails.getAttributes().get(key2));
+        assertEquals(value3, authenticationDetails.getAttributes().get(key3));
+    }
+
+    public final void testBuildDetailsObjectCookie() {
+        authenticationDetailsSource.setClazz(AuthenticationDetailsImpl.class);
+
+        String key1 = "key1";
+        String value1 = "value1";
+        String key2 = "key2";
+        String value2 = "value2";
+        String key3 = "key3";
+        String value3 = "value3";
+
+        {
+            CookieAttributesSource attributesSource = new CookieAttributesSource();
+
+            {
+                List keys = new ArrayList();
+                keys.add(key1);
+                keys.add(key2);
+                keys.add(key3);
+                attributesSource.setKeys(keys);
+            }
+
+            authenticationDetailsSource.setAttributesSource(attributesSource);
+        }
+
+        MockHttpServletRequest request = new MockHttpServletRequest();
+
+        {
+            Cookie[] cookies = new Cookie[] { new Cookie(key1, value1), new Cookie(key2, value2),
+                    new Cookie(key3, value3) };
+            request.setCookies(cookies);
+        }
+
+        AuthenticationDetailsImpl authenticationDetails = (AuthenticationDetailsImpl) authenticationDetailsSource
+            .buildDetails(request);
+
+        assertEquals(value1, authenticationDetails.getAttributes().get(key1));
+        assertEquals(value2, authenticationDetails.getAttributes().get(key2));
+        assertEquals(value3, authenticationDetails.getAttributes().get(key3));
+    }
+
+    public final void testBuildDetailsObjectProperty() {
+        authenticationDetailsSource.setClazz(AuthenticationDetailsImpl.class);
+
+        String key1 = "key1";
+        String value1 = "value1";
+        String key2 = "key2";
+        String value2 = "value2";
+        String key3 = "key3";
+        String value3 = "value3";
+
+        {
+            PropertyAttributesSource attributesSource = new PropertyAttributesSource();
+
+            {
+                Map attributes = new HashMap();
+                attributes.put(key1, value1);
+                attributes.put(key2, value2);
+                attributes.put(key3, value3);
+                attributesSource.setAttributes(attributes);
+            }
+
+            authenticationDetailsSource.setAttributesSource(attributesSource);
+        }
+
+        MockHttpServletRequest request = new MockHttpServletRequest();
+
+        AuthenticationDetailsImpl authenticationDetails = (AuthenticationDetailsImpl) authenticationDetailsSource
+            .buildDetails(request);
+
+        assertEquals(value1, authenticationDetails.getAttributes().get(key1));
+        assertEquals(value2, authenticationDetails.getAttributes().get(key2));
+        assertEquals(value3, authenticationDetails.getAttributes().get(key3));
+    }
+
+    public final void testSetUsername() {
+        try {
+            authenticationDetailsSource.setAttributesSource(null);
+            fail("exception expected");
+        } catch (IllegalArgumentException expected) {
+        } catch (Exception unexpected) {
+            fail("unexpected exception");
+        }
+    }
+
+    public final void testAfterPropertiesSet() {
+        try {
+            authenticationDetailsSource.afterPropertiesSet();
+            fail("expected exception");
+        } catch (IllegalArgumentException expected) {
+        } catch (Exception unexpected) {
+            fail("unexpected exception");
+        }
+    }
+}

+ 80 - 0
sandbox/other/src/test/java/org/springframework/security/ui/preauth/CookieAttributesSourceTest.java

@@ -0,0 +1,80 @@
+/* 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 org.springframework.security.ui.preauth;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.Cookie;
+
+import junit.framework.TestCase;
+
+import org.springframework.mock.web.MockHttpServletRequest;
+
+/**
+ * @author Valery Tydykov
+ * 
+ */
+public class CookieAttributesSourceTest extends TestCase {
+
+    CookieAttributesSource attributesSource;
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see junit.framework.TestCase#setUp()
+     */
+    protected void setUp() throws Exception {
+        attributesSource = new CookieAttributesSource();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see junit.framework.TestCase#tearDown()
+     */
+    protected void tearDown() throws Exception {
+        attributesSource = null;
+    }
+
+    public final void testObtainAttributes() {
+        String key1 = "key1";
+        String value1 = "value1";
+        String key2 = "key2";
+        String value2 = "value2";
+        String key3 = "key3";
+
+        {
+            List keys = new ArrayList();
+            keys.add(key1);
+            keys.add(key2);
+            keys.add(key3);
+            attributesSource.setKeys(keys);
+        }
+
+        MockHttpServletRequest request = new MockHttpServletRequest();
+        {
+            Cookie[] cookies = new Cookie[] { new Cookie(key1, value1), new Cookie(key2, value2) };
+            request.setCookies(cookies);
+        }
+
+        Map attributes = attributesSource.obtainAttributes(request);
+
+        assertEquals(value1, attributes.get(key1));
+        assertEquals(value2, attributes.get(key2));
+        assertEquals(null, attributes.get(key3));
+    }
+}

+ 64 - 0
sandbox/other/src/test/java/org/springframework/security/ui/preauth/CookieUsernameSourceTest.java

@@ -0,0 +1,64 @@
+/**
+ * 
+ */
+package org.springframework.security.ui.preauth;
+
+import javax.servlet.http.Cookie;
+
+import junit.framework.TestCase;
+
+import org.springframework.mock.web.MockHttpServletRequest;
+
+/**
+ * @author tydykov
+ * 
+ */
+public class CookieUsernameSourceTest extends TestCase {
+
+    CookieUsernameSource usernameSource;
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see junit.framework.TestCase#setUp()
+     */
+    protected void setUp() throws Exception {
+        usernameSource = new CookieUsernameSource();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see junit.framework.TestCase#tearDown()
+     */
+    protected void tearDown() throws Exception {
+        usernameSource = null;
+    }
+
+    public final void testObtainUsernameSupplied() {
+        String key1 = "key1";
+        String value1 = "value1";
+
+        MockHttpServletRequest request = new MockHttpServletRequest();
+        {
+            Cookie[] cookies = new Cookie[] { new Cookie(key1, value1) };
+            request.setCookies(cookies);
+        }
+
+        usernameSource.setUsernameKey(key1);
+        String username = usernameSource.obtainUsername(request);
+
+        assertEquals(value1, username);
+    }
+
+    public final void testObtainUsernameNotSupplied() {
+        String key1 = "key1";
+
+        MockHttpServletRequest request = new MockHttpServletRequest();
+
+        usernameSource.setUsernameKey(key1);
+        String username = usernameSource.obtainUsername(request);
+
+        assertEquals(null, username);
+    }
+}

+ 76 - 0
sandbox/other/src/test/java/org/springframework/security/ui/preauth/HeaderAttributesSourceTest.java

@@ -0,0 +1,76 @@
+/* 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 org.springframework.security.ui.preauth;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+import org.springframework.mock.web.MockHttpServletRequest;
+
+/**
+ * @author Valery Tydykov
+ * 
+ */
+public class HeaderAttributesSourceTest extends TestCase {
+
+    HeaderAttributesSource attributesSource;
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see junit.framework.TestCase#setUp()
+     */
+    protected void setUp() throws Exception {
+        attributesSource = new HeaderAttributesSource();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see junit.framework.TestCase#tearDown()
+     */
+    protected void tearDown() throws Exception {
+        attributesSource = null;
+    }
+
+    public final void testObtainAttributes() {
+        String key1 = "key1";
+        String value1 = "value1";
+        String key2 = "key2";
+        String value2 = "value2";
+        String key3 = "key3";
+
+        {
+            List keys = new ArrayList();
+            keys.add(key1);
+            keys.add(key2);
+            keys.add(key3);
+            attributesSource.setKeys(keys);
+        }
+
+        MockHttpServletRequest request = new MockHttpServletRequest();
+        request.addHeader(key1, value1);
+        request.addHeader(key2, value2);
+
+        Map attributes = attributesSource.obtainAttributes(request);
+
+        assertEquals(value1, attributes.get(key1));
+        assertEquals(value2, attributes.get(key2));
+        assertEquals(null, attributes.get(key3));
+    }
+}

+ 70 - 0
sandbox/other/src/test/java/org/springframework/security/ui/preauth/HeaderUsernameSourceTest.java

@@ -0,0 +1,70 @@
+/* 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 org.springframework.security.ui.preauth;
+
+import junit.framework.TestCase;
+
+import org.springframework.mock.web.MockHttpServletRequest;
+
+/**
+ * @author Valery Tydykov
+ * 
+ */
+public class HeaderUsernameSourceTest extends TestCase {
+
+    HeaderUsernameSource usernameSource;
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see junit.framework.TestCase#setUp()
+     */
+    protected void setUp() throws Exception {
+        usernameSource = new HeaderUsernameSource();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see junit.framework.TestCase#tearDown()
+     */
+    protected void tearDown() throws Exception {
+        usernameSource = null;
+    }
+
+    public final void testObtainUsernameSupplied() {
+        String key1 = "key1";
+        String value1 = "value1";
+
+        MockHttpServletRequest request = new MockHttpServletRequest();
+        request.addHeader(key1, value1);
+
+        usernameSource.setUsernameKey(key1);
+        String username = usernameSource.obtainUsername(request);
+
+        assertEquals(value1, username);
+    }
+
+    public final void testObtainUsernameNotSupplied() {
+        String key1 = "key1";
+
+        MockHttpServletRequest request = new MockHttpServletRequest();
+
+        usernameSource.setUsernameKey(key1);
+        String username = usernameSource.obtainUsername(request);
+
+        assertEquals(null, username);
+    }
+}

+ 74 - 0
sandbox/other/src/test/java/org/springframework/security/ui/preauth/PropertyAttributesSourceTest.java

@@ -0,0 +1,74 @@
+/* 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 org.springframework.security.ui.preauth;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+/**
+ * @author Valery Tydykov
+ * 
+ */
+public class PropertyAttributesSourceTest extends TestCase {
+
+    PropertyAttributesSource attributesSource;
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see junit.framework.TestCase#setUp()
+     */
+    protected void setUp() throws Exception {
+        attributesSource = new PropertyAttributesSource();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see junit.framework.TestCase#tearDown()
+     */
+    protected void tearDown() throws Exception {
+        attributesSource = null;
+    }
+
+    /**
+     * Test method for
+     * {@link org.springframework.security.ui.preauth.PropertyAttributesSource#obtainAttributes(javax.servlet.http.HttpServletRequest)}.
+     */
+    public final void testObtainAttributes() {
+        String key1 = "key1";
+        String value1 = "value1";
+        String key2 = "key2";
+        String value2 = "value2";
+        String key3 = "key3";
+        String value3 = "value3";
+
+        {
+            Map attributes = new HashMap();
+            attributes.put(key1, value1);
+            attributes.put(key2, value2);
+            attributes.put(key3, value3);
+            attributesSource.setAttributes(attributes);
+        }
+
+        Map attributes = attributesSource.obtainAttributes(null);
+
+        assertEquals(value1, attributes.get(key1));
+        assertEquals(value2, attributes.get(key2));
+        assertEquals(value3, attributes.get(key3));
+    }
+}

+ 65 - 0
sandbox/other/src/test/java/org/springframework/security/ui/preauth/RemoteUserUsernameSourceTest.java

@@ -0,0 +1,65 @@
+/* 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 org.springframework.security.ui.preauth;
+
+import junit.framework.TestCase;
+
+import org.springframework.mock.web.MockHttpServletRequest;
+
+/**
+ * @author Valery Tydykov
+ * 
+ */
+public class RemoteUserUsernameSourceTest extends TestCase {
+
+    RemoteUserUsernameSource usernameSource;
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see junit.framework.TestCase#setUp()
+     */
+    protected void setUp() throws Exception {
+        usernameSource = new RemoteUserUsernameSource();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see junit.framework.TestCase#tearDown()
+     */
+    protected void tearDown() throws Exception {
+        usernameSource = null;
+    }
+
+    public final void testObtainUsernameSupplied() {
+        String value1 = "value1";
+
+        MockHttpServletRequest request = new MockHttpServletRequest();
+        request.setRemoteUser(value1);
+
+        String username = usernameSource.obtainUsername(request);
+
+        assertEquals(value1, username);
+    }
+
+    public final void testObtainUsernameNotSupplied() {
+        MockHttpServletRequest request = new MockHttpServletRequest();
+
+        String username = usernameSource.obtainUsername(request);
+
+        assertEquals(null, username);
+    }
+}

+ 70 - 0
sandbox/other/src/test/java/org/springframework/security/ui/preauth/RequestParameterUsernameSourceTest.java

@@ -0,0 +1,70 @@
+/* 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 org.springframework.security.ui.preauth;
+
+import junit.framework.TestCase;
+
+import org.springframework.mock.web.MockHttpServletRequest;
+
+/**
+ * @author Valery Tydykov
+ * 
+ */
+public class RequestParameterUsernameSourceTest extends TestCase {
+
+    RequestParameterUsernameSource usernameSource;
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see junit.framework.TestCase#setUp()
+     */
+    protected void setUp() throws Exception {
+        usernameSource = new RequestParameterUsernameSource();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see junit.framework.TestCase#tearDown()
+     */
+    protected void tearDown() throws Exception {
+        usernameSource = null;
+    }
+
+    public final void testObtainUsernameSupplied() {
+        String key1 = "key1";
+        String value1 = "value1";
+
+        MockHttpServletRequest request = new MockHttpServletRequest();
+        request.addParameter(key1, value1);
+
+        usernameSource.setUsernameKey(key1);
+        String username = usernameSource.obtainUsername(request);
+
+        assertEquals(value1, username);
+    }
+
+    public final void testObtainUsernameNotSupplied() {
+        String key1 = "key1";
+
+        MockHttpServletRequest request = new MockHttpServletRequest();
+
+        usernameSource.setUsernameKey(key1);
+        String username = usernameSource.obtainUsername(request);
+
+        assertEquals(null, username);
+    }
+}

+ 232 - 0
sandbox/other/src/test/java/org/springframework/security/ui/preauth/UsernameSourcePreAuthenticatedProcessingFilterTest.java

@@ -0,0 +1,232 @@
+/* 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 org.springframework.security.ui.preauth;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.servlet.FilterChain;
+import javax.servlet.http.Cookie;
+
+import junit.framework.TestCase;
+
+import org.springframework.mock.web.MockFilterChain;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+import org.springframework.security.Authentication;
+import org.springframework.security.MockAuthenticationManager;
+import org.springframework.security.context.SecurityContextHolder;
+import org.springframework.security.ui.WebAuthenticationDetails;
+
+/**
+ * 
+ * @author Valery Tydykov
+ */
+public class UsernameSourcePreAuthenticatedProcessingFilterTest extends TestCase {
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see junit.framework.TestCase#setUp()
+     */
+    protected void setUp() throws Exception {
+        super.setUp();
+        // crear security context
+        SecurityContextHolder.getContext().setAuthentication(null);
+    }
+
+    public static final String PROJECT_ID_KEY = "projectIdKey";
+
+    public static final String PROJECT_ID = "projectId";
+
+    public static final String USERNAME_KEY = "usernameKey";
+
+    public static final String USERNAME = "username";
+
+    public void tearDown() throws Exception {
+        // crear security context
+        SecurityContextHolder.getContext().setAuthentication(null);
+        super.tearDown();
+    }
+
+    public void testAttemptAuthenticationNormalOperation() throws Exception {
+        MockHttpServletRequest request = new MockHttpServletRequest();
+        // supply username in request header
+        request.addHeader(USERNAME_KEY, USERNAME);
+
+        UsernameSourcePreAuthenticatedProcessingFilter filter = new UsernameSourcePreAuthenticatedProcessingFilter();
+        {
+            MockAuthenticationManager authMgr = new MockAuthenticationManager(true);
+            filter.setAuthenticationManager(authMgr);
+        }
+        {
+            HeaderUsernameSource usernameSource = new HeaderUsernameSource();
+            usernameSource.setUsernameKey(USERNAME_KEY);
+            filter.setUsernameSource(usernameSource);
+        }
+
+        FilterChain filterChain = new MockFilterChain();
+        MockHttpServletResponse response = new MockHttpServletResponse();
+        filter.doFilterHttp(request, response, filterChain);
+
+        Authentication result = SecurityContextHolder.getContext().getAuthentication();
+
+        assertTrue(result != null);
+        assertEquals(USERNAME, result.getPrincipal());
+        assertEquals("127.0.0.1", ((WebAuthenticationDetails) result.getDetails())
+            .getRemoteAddress());
+    }
+
+    public void testAttemptAuthenticationNoUsername() throws Exception {
+        MockHttpServletRequest request = new MockHttpServletRequest();
+        // no username in request
+
+        UsernameSourcePreAuthenticatedProcessingFilter filter = new UsernameSourcePreAuthenticatedProcessingFilter();
+        {
+            HeaderUsernameSource usernameSource = new HeaderUsernameSource();
+            usernameSource.setUsernameKey(USERNAME_KEY);
+            filter.setUsernameSource(usernameSource);
+        }
+
+        FilterChain filterChain = new MockFilterChain();
+        MockHttpServletResponse response = new MockHttpServletResponse();
+
+        filter.doFilterHttp(request, response, filterChain);
+
+        Authentication result = SecurityContextHolder.getContext().getAuthentication();
+        assertTrue(result == null);
+    }
+
+    public void testAttemptAuthenticationContextPopulatingWebAuthenticationDetailsSourceFromHeader()
+            throws Exception {
+        MockHttpServletRequest request = new MockHttpServletRequest();
+
+        request.addHeader(USERNAME_KEY, USERNAME);
+        request.addHeader(PROJECT_ID_KEY, PROJECT_ID);
+
+        String key3 = "key3";
+        String value3 = "value3";
+        request.addHeader(key3, value3);
+
+        UsernameSourcePreAuthenticatedProcessingFilter filter = new UsernameSourcePreAuthenticatedProcessingFilter();
+
+        {
+            MockAuthenticationManager authMgr = new MockAuthenticationManager(true);
+            filter.setAuthenticationManager(authMgr);
+        }
+        {
+            AttributesSourceWebAuthenticationDetailsSource authenticationDetailsSource = new AttributesSourceWebAuthenticationDetailsSource();
+            authenticationDetailsSource.setClazz(AuthenticationDetailsImpl.class);
+            {
+                HeaderAttributesSource attributesSource = new HeaderAttributesSource();
+
+                {
+                    List keys = new ArrayList();
+                    keys.add(PROJECT_ID_KEY);
+                    keys.add(key3);
+                    attributesSource.setKeys(keys);
+                }
+
+                authenticationDetailsSource.setAttributesSource(attributesSource);
+            }
+
+            filter.setAuthenticationDetailsSource(authenticationDetailsSource);
+        }
+        {
+            HeaderUsernameSource usernameSource = new HeaderUsernameSource();
+            usernameSource.setUsernameKey(USERNAME_KEY);
+            filter.setUsernameSource(usernameSource);
+        }
+
+        FilterChain filterChain = new MockFilterChain();
+        MockHttpServletResponse response = new MockHttpServletResponse();
+        filter.doFilterHttp(request, response, filterChain);
+
+        Authentication result = SecurityContextHolder.getContext().getAuthentication();
+
+        assertTrue(result != null);
+        assertEquals(USERNAME, result.getPrincipal());
+        assertEquals("127.0.0.1", ((WebAuthenticationDetails) result.getDetails())
+            .getRemoteAddress());
+        assertEquals(PROJECT_ID, ((AuthenticationDetailsImpl) result.getDetails()).getAttributes()
+            .get(PROJECT_ID_KEY));
+        assertEquals(value3, ((AuthenticationDetailsImpl) result.getDetails()).getAttributes().get(
+            key3));
+    }
+
+    public void testAttemptAuthenticationContextPopulatingWebAuthenticationDetailsSourceFromCookies()
+            throws Exception {
+        MockHttpServletRequest request = new MockHttpServletRequest();
+        String usernameKey = "usernameKey1";
+        String username = "username1";
+        request.addHeader(usernameKey, username);
+
+        String key2 = "key2";
+        String value2 = "value2";
+        String key3 = "key3";
+        String value3 = "value3";
+
+        {
+            Cookie[] cookies = new Cookie[] { new Cookie(key2, value2), new Cookie(key3, value3) };
+            request.setCookies(cookies);
+        }
+
+        UsernameSourcePreAuthenticatedProcessingFilter filter = new UsernameSourcePreAuthenticatedProcessingFilter();
+        {
+            MockAuthenticationManager authMgr = new MockAuthenticationManager(true);
+            filter.setAuthenticationManager(authMgr);
+        }
+        {
+            AttributesSourceWebAuthenticationDetailsSource authenticationDetailsSource = new AttributesSourceWebAuthenticationDetailsSource();
+            authenticationDetailsSource.setClazz(AuthenticationDetailsImpl.class);
+
+            {
+                CookieAttributesSource attributesSource = new CookieAttributesSource();
+
+                {
+                    List keys = new ArrayList();
+                    keys.add(key2);
+                    keys.add(key3);
+                    attributesSource.setKeys(keys);
+                }
+
+                authenticationDetailsSource.setAttributesSource(attributesSource);
+            }
+
+            filter.setAuthenticationDetailsSource(authenticationDetailsSource);
+        }
+        {
+            HeaderUsernameSource usernameSource = new HeaderUsernameSource();
+            usernameSource.setUsernameKey(usernameKey);
+            filter.setUsernameSource(usernameSource);
+        }
+
+        FilterChain filterChain = new MockFilterChain();
+        MockHttpServletResponse response = new MockHttpServletResponse();
+        filter.doFilterHttp(request, response, filterChain);
+
+        Authentication result = SecurityContextHolder.getContext().getAuthentication();
+
+        assertTrue(result != null);
+        assertEquals(username, result.getPrincipal());
+        assertEquals("127.0.0.1", ((WebAuthenticationDetails) result.getDetails())
+            .getRemoteAddress());
+        assertEquals(value2, ((AuthenticationDetailsImpl) result.getDetails()).getAttributes().get(
+            key2));
+        assertEquals(value3, ((AuthenticationDetailsImpl) result.getDetails()).getAttributes().get(
+            key3));
+
+    }
+}

+ 33 - 0
sandbox/other/src/test/java/org/springframework/security/userdetails/AllTests.java

@@ -0,0 +1,33 @@
+/* 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 org.springframework.security.userdetails;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+public class AllTests extends TestCase {
+
+    public AllTests(String s) {
+        super(s);
+    }
+
+    public static Test suite() {
+        TestSuite suite = new TestSuite();
+        suite.addTest(org.springframework.security.userdetails.ldap.AllTests.suite());
+        suite.addTest(org.springframework.security.userdetails.preauth.AllTests.suite());
+        return suite;
+    }
+}

+ 37 - 0
sandbox/other/src/test/java/org/springframework/security/userdetails/ldap/AllTests.java

@@ -0,0 +1,37 @@
+/* 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 org.springframework.security.userdetails.ldap;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+public class AllTests extends TestCase {
+
+    public AllTests(String s) {
+        super(s);
+    }
+
+    public static Test suite() {
+        TestSuite suite = new TestSuite();
+        suite
+            .addTestSuite(org.springframework.security.userdetails.ldap.AuthorityByPrefixAccountMapperTest.class);
+        suite
+            .addTestSuite(org.springframework.security.userdetails.ldap.ReplacingUserDetailsMapperTest.class);
+        suite
+            .addTestSuite(org.springframework.security.userdetails.ldap.UsernameFromPropertyAccountMapperTest.class);
+        return suite;
+    }
+}

+ 103 - 0
sandbox/other/src/test/java/org/springframework/security/userdetails/ldap/AuthorityByPrefixAccountMapperTest.java

@@ -0,0 +1,103 @@
+/**
+ * 
+ */
+package org.springframework.security.userdetails.ldap;
+
+import junit.framework.TestCase;
+
+import org.springframework.security.GrantedAuthority;
+import org.springframework.security.GrantedAuthorityImpl;
+import org.springframework.security.userdetails.User;
+import org.springframework.security.userdetails.UserDetails;
+
+/**
+ * @author Valery Tydykov
+ * 
+ */
+public class AuthorityByPrefixAccountMapperTest extends TestCase {
+    AuthorityByPrefixAccountMapper mapper;
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see junit.framework.TestCase#setUp()
+     */
+    protected void setUp() throws Exception {
+        mapper = new AuthorityByPrefixAccountMapper();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see junit.framework.TestCase#tearDown()
+     */
+    protected void tearDown() throws Exception {
+        mapper = null;
+    }
+
+    /**
+     * Test method for
+     * {@link org.springframework.security.userdetails.ldap.AuthorityByPrefixAccountMapper#map(org.springframework.security.userdetails.UserDetails)}.
+     */
+    public final void testNormalOperation() {
+        String expectedAuthority = "prefix1_role1";
+        GrantedAuthority[] authorities = { new GrantedAuthorityImpl(expectedAuthority),
+                new GrantedAuthorityImpl("prefix1_role2") };
+        UserDetails user = new User("username1", "password1", false, authorities);
+        mapper.setAuthorityPrefix("prefix1_");
+        String authority = mapper.map(user);
+
+        assertEquals(expectedAuthority, authority);
+    }
+
+    /**
+     * Test method for
+     * {@link org.springframework.security.userdetails.ldap.AuthorityByPrefixAccountMapper#map(org.springframework.security.userdetails.UserDetails)}.
+     */
+    public final void testAuthorityNotFoundThrowsException() {
+        String expectedAuthority = "prefix1_role1";
+        GrantedAuthority[] authorities = { new GrantedAuthorityImpl(expectedAuthority) };
+        UserDetails user = new User("username1", "password1", false, authorities);
+        mapper.setAuthorityPrefix("NoMatchPrefix");
+
+        try {
+            mapper.map(user);
+            fail("exception expected");
+        } catch (AuthorityNotFoundException expected) {
+        } catch (Exception unexpected) {
+            fail("map throws unexpected exception");
+        }
+    }
+
+    /**
+     * Test method for
+     * {@link org.springframework.security.userdetails.ldap.AuthorityByPrefixAccountMapper#afterPropertiesSet()}.
+     */
+    public final void testAfterPropertiesSet() {
+        try {
+            mapper.afterPropertiesSet();
+            fail("exception expected");
+        } catch (IllegalArgumentException expected) {
+        } catch (Exception unexpected) {
+            fail("unexpected exception");
+        }
+    }
+
+    public final void testEmptyPrefixThrowsException() {
+        try {
+            mapper.setAuthorityPrefix("");
+            fail("expected exception");
+        } catch (IllegalArgumentException expected) {
+        } catch (Exception unexpected) {
+            fail("unexpected exception");
+        }
+
+        try {
+            mapper.setAuthorityPrefix(null);
+            fail("AfterPropertiesSet didn't throw expected exception");
+        } catch (IllegalArgumentException expected) {
+        } catch (Exception unexpected) {
+            fail("AfterPropertiesSet throws unexpected exception");
+        }
+    }
+}

+ 154 - 0
sandbox/other/src/test/java/org/springframework/security/userdetails/ldap/ReplacingUserDetailsMapperTest.java

@@ -0,0 +1,154 @@
+/* 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 org.springframework.security.userdetails.ldap;
+
+import junit.framework.TestCase;
+
+import org.springframework.ldap.core.DirContextAdapter;
+import org.springframework.security.GrantedAuthority;
+import org.springframework.security.userdetails.UserDetails;
+import org.springframework.security.userdetails.UsernameNotFoundException;
+import org.springframework.security.userdetails.memory.InMemoryDaoImpl;
+import org.springframework.security.userdetails.memory.UserMap;
+import org.springframework.security.userdetails.memory.UserMapEditor;
+
+/**
+ * @author Valery Tydykov
+ * 
+ */
+public class ReplacingUserDetailsMapperTest extends TestCase {
+
+    ReplacingUserDetailsMapper mapper;
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see junit.framework.TestCase#setUp()
+     */
+    protected void setUp() throws Exception {
+        mapper = new ReplacingUserDetailsMapper();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see junit.framework.TestCase#tearDown()
+     */
+    protected void tearDown() throws Exception {
+        mapper = null;
+    }
+
+    /**
+     * Test method for
+     * {@link org.springframework.security.userdetails.ldap.ReplacingUserDetailsMapper#setUserDetailsService(org.springframework.security.userdetails.UserDetailsService)}.
+     */
+    public final void testSetUserDetailsServiceNullThrowsException() {
+        try {
+            mapper.setUserDetailsService(null);
+            fail("exception expected");
+        } catch (IllegalArgumentException expected) {
+        } catch (Exception unexpected) {
+            fail("unexpected exception");
+        }
+    }
+
+    /**
+     * Test method for
+     * {@link org.springframework.security.userdetails.ldap.ReplacingUserDetailsMapper#setAccountMapper(org.springframework.security.userdetails.ldap.AccountMapper)}.
+     */
+    public final void testSetAccountMapperNullThrowsException() {
+        try {
+            mapper.setAccountMapper(null);
+            fail("exception expected");
+        } catch (IllegalArgumentException expected) {
+        } catch (Exception unexpected) {
+            fail("unexpected exception");
+        }
+    }
+
+    /**
+     * Test method for
+     * {@link org.springframework.security.userdetails.ldap.ReplacingUserDetailsMapper#afterPropertiesSet()}.
+     */
+    public final void testAfterPropertiesSet() {
+        try {
+            mapper.afterPropertiesSet();
+            fail("expected exception");
+        } catch (IllegalArgumentException expected) {
+        } catch (Exception unexpected) {
+            fail("unexpected exception");
+        }
+    }
+
+    /**
+     * Test method for
+     * {@link org.springframework.security.userdetails.ldap.ReplacingUserDetailsMapper#mapUserFromContext(org.springframework.ldap.core.DirContextOperations, java.lang.String, org.springframework.security.GrantedAuthority[])}.
+     */
+    public final void testNormalOperation() {
+        String userName = "rod,ok";
+        UsernameFromPropertyAccountMapper accountMapper = new UsernameFromPropertyAccountMapper();
+        accountMapper.setUsername(userName);
+        mapper.setAccountMapper(accountMapper);
+        mapper.setConvertToUpperCase(false);
+
+        {
+            // create secondary user accounts repository
+            InMemoryDaoImpl dao = new InMemoryDaoImpl();
+            UserMapEditor editor = new UserMapEditor();
+            editor.setAsText("rod,ok=koala,ROLE_ONE,ROLE_TWO,enabled\r\n");
+            dao.setUserMap((UserMap) editor.getValue());
+
+            mapper.setUserDetailsService(dao);
+        }
+
+        DirContextAdapter ctx = new DirContextAdapter();
+
+        ctx.setAttributeValues("userRole", new String[] { "X", "Y", "Z" });
+        ctx.setAttributeValue("uid", "ani");
+
+        UserDetails userDetails = mapper.mapUserFromContext(ctx, "ani", new GrantedAuthority[0]);
+        // verify that userDetails came from the secondary repository
+        assertEquals("ROLE_ONE", userDetails.getAuthorities()[0].getAuthority());
+    }
+
+    /**
+     * Test method for
+     * {@link org.springframework.security.userdetails.ldap.ReplacingUserDetailsMapper#retrieveUser(java.lang.String)}.
+     */
+    public final void testRetrieveUser() {
+        String username = "rod,ok";
+        {
+            // secondary user accounts repository
+            InMemoryDaoImpl dao = new InMemoryDaoImpl();
+            UserMapEditor editor = new UserMapEditor();
+            editor.setAsText("rod,ok=koala,ROLE_ONE,ROLE_TWO,enabled\r\n");
+            dao.setUserMap((UserMap) editor.getValue());
+
+            mapper.setUserDetailsService(dao);
+        }
+
+        UserDetails userDetails = mapper.retrieveUser(username);
+
+        assertEquals("ROLE_ONE", userDetails.getAuthorities()[0].getAuthority());
+
+        try {
+            mapper.retrieveUser("noMatchUsername");
+            fail("exception expected");
+        } catch (UsernameNotFoundException expected) {
+        } catch (Exception unexpected) {
+            fail("unexpected exception");
+        }
+    }
+}

+ 89 - 0
sandbox/other/src/test/java/org/springframework/security/userdetails/ldap/UsernameFromPropertyAccountMapperTest.java

@@ -0,0 +1,89 @@
+/* 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 org.springframework.security.userdetails.ldap;
+
+import junit.framework.TestCase;
+
+import org.springframework.security.GrantedAuthority;
+import org.springframework.security.userdetails.User;
+import org.springframework.security.userdetails.UserDetails;
+
+/**
+ * @author Valery Tydykov
+ * 
+ */
+public class UsernameFromPropertyAccountMapperTest extends TestCase {
+
+    UsernameFromPropertyAccountMapper mapper;
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see junit.framework.TestCase#setUp()
+     */
+    protected void setUp() throws Exception {
+        mapper = new UsernameFromPropertyAccountMapper();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see junit.framework.TestCase#tearDown()
+     */
+    protected void tearDown() throws Exception {
+        mapper = null;
+    }
+
+    /**
+     * Test method for
+     * {@link org.springframework.security.userdetails.ldap.UsernameFromPropertyAccountMapper#map(org.springframework.security.userdetails.UserDetails)}.
+     */
+    public final void testNormalOperation() {
+        String usernameExpected = "username1";
+        UserDetails user = new User(usernameExpected, "password1", false, new GrantedAuthority[0]);
+        mapper.setUsername(usernameExpected);
+        String username = mapper.map(user);
+
+        assertEquals(usernameExpected, username);
+    }
+
+    /**
+     * Test method for
+     * {@link org.springframework.security.userdetails.ldap.UsernameFromPropertyAccountMapper#setUsername(java.lang.String)}.
+     */
+    public final void testSetUserName() {
+        try {
+            mapper.setUsername(null);
+            fail("exception expected");
+        } catch (IllegalArgumentException expected) {
+        } catch (Exception unexpected) {
+            fail("unexpected exception");
+        }
+    }
+
+    /**
+     * Test method for
+     * {@link org.springframework.security.userdetails.ldap.UsernameFromPropertyAccountMapper#afterPropertiesSet()}.
+     */
+    public final void testAfterPropertiesSet() {
+        try {
+            mapper.afterPropertiesSet();
+            fail("expected exception");
+        } catch (IllegalArgumentException expected) {
+        } catch (Exception unexpected) {
+            fail("unexpected exception");
+        }
+    }
+}

+ 37 - 0
sandbox/other/src/test/java/org/springframework/security/userdetails/preauth/AllTests.java

@@ -0,0 +1,37 @@
+/* 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 org.springframework.security.userdetails.preauth;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+public class AllTests extends TestCase {
+
+    public AllTests(String s) {
+        super(s);
+    }
+
+    public static Test suite() {
+        TestSuite suite = new TestSuite();
+        suite
+            .addTestSuite(org.springframework.security.userdetails.preauth.UserDetailsMappingServiceWrapperTest.class);
+        suite
+            .addTestSuite(org.springframework.security.userdetails.preauth.UsernameFromPropertyAccountMapperTest.class);
+        suite
+            .addTestSuite(org.springframework.security.userdetails.preauth.UsernameFromRequestAccountMapperTest.class);
+        return suite;
+    }
+}

+ 121 - 0
sandbox/other/src/test/java/org/springframework/security/userdetails/preauth/UserDetailsMappingServiceWrapperTest.java

@@ -0,0 +1,121 @@
+/* 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 org.springframework.security.userdetails.preauth;
+
+import junit.framework.TestCase;
+
+import org.springframework.security.Authentication;
+import org.springframework.security.providers.TestingAuthenticationToken;
+import org.springframework.security.userdetails.UserDetails;
+import org.springframework.security.userdetails.memory.InMemoryDaoImpl;
+import org.springframework.security.userdetails.memory.UserMap;
+import org.springframework.security.userdetails.memory.UserMapEditor;
+
+/**
+ * @author Valery Tydykov
+ * 
+ */
+public class UserDetailsMappingServiceWrapperTest extends TestCase {
+
+    UserDetailsMappingServiceWrapper service;
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see junit.framework.TestCase#setUp()
+     */
+    protected void setUp() throws Exception {
+        service = new UserDetailsMappingServiceWrapper();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see junit.framework.TestCase#tearDown()
+     */
+    protected void tearDown() throws Exception {
+        service = null;
+    }
+
+    /**
+     * Test method for
+     * {@link org.springframework.security.userdetails.preauth.UserDetailsMappingServiceWrapper#afterPropertiesSet()}.
+     */
+    public final void testAfterPropertiesSet() {
+        try {
+            service.afterPropertiesSet();
+            fail("expected exception");
+        } catch (IllegalArgumentException expected) {
+        } catch (Exception unexpected) {
+            fail("unexpected exception");
+        }
+    }
+
+    /**
+     * Test method for
+     * {@link org.springframework.security.userdetails.preauth.UserDetailsMappingServiceWrapper#loadUserDetails(org.springframework.security.Authentication)}.
+     */
+    public final void testLoadUserDetails() {
+        String username = "rod,ok";
+        UsernameFromPropertyAccountMapper accountMapper = new UsernameFromPropertyAccountMapper();
+        accountMapper.setUsername(username);
+
+        service.setAccountMapper(accountMapper);
+
+        // secondary user accounts repository
+        {
+            InMemoryDaoImpl dao = new InMemoryDaoImpl();
+            UserMapEditor editor = new UserMapEditor();
+            editor.setAsText("rod,ok=koala,ROLE_ONE,ROLE_TWO,enabled\r\n");
+            dao.setUserMap((UserMap) editor.getValue());
+
+            service.setUserDetailsService(dao);
+        }
+
+        Authentication authentication = new TestingAuthenticationToken("any", "any", null);
+        UserDetails user = service.loadUserDetails(authentication);
+
+        // verify that userDetails came from the secondary repository
+        assertEquals("ROLE_ONE", user.getAuthorities()[0].getAuthority());
+    }
+
+    /**
+     * Test method for
+     * {@link org.springframework.security.userdetails.preauth.UserDetailsMappingServiceWrapper#setUserDetailsService(org.springframework.security.userdetails.UserDetailsService)}.
+     */
+    public final void testSetUserDetailsService() {
+        try {
+            service.setUserDetailsService(null);
+            fail("exception expected");
+        } catch (IllegalArgumentException expected) {
+        } catch (Exception unexpected) {
+            fail("unexpected exception");
+        }
+    }
+
+    /**
+     * Test method for
+     * {@link org.springframework.security.userdetails.preauth.UserDetailsMappingServiceWrapper#setAccountMapper(org.springframework.security.userdetails.preauth.AccountMapper)}.
+     */
+    public final void testSetAccountMapper() {
+        try {
+            service.setAccountMapper(null);
+            fail("exception expected");
+        } catch (IllegalArgumentException expected) {
+        } catch (Exception unexpected) {
+            fail("unexpected exception");
+        }
+    }
+}

+ 89 - 0
sandbox/other/src/test/java/org/springframework/security/userdetails/preauth/UsernameFromPropertyAccountMapperTest.java

@@ -0,0 +1,89 @@
+/* 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 org.springframework.security.userdetails.preauth;
+
+import junit.framework.TestCase;
+
+import org.springframework.security.Authentication;
+import org.springframework.security.providers.TestingAuthenticationToken;
+
+/**
+ * @author Valery Tydykov
+ * 
+ */
+public class UsernameFromPropertyAccountMapperTest extends TestCase {
+
+    UsernameFromPropertyAccountMapper mapper;
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see junit.framework.TestCase#setUp()
+     */
+    protected void setUp() throws Exception {
+        mapper = new UsernameFromPropertyAccountMapper();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see junit.framework.TestCase#tearDown()
+     */
+    protected void tearDown() throws Exception {
+        mapper = null;
+    }
+
+    /**
+     * Test method for
+     * {@link org.springframework.security.userdetails.preauth.UsernameFromPropertyAccountMapper#map(org.springframework.security.Authentication)}.
+     */
+    public final void testNormalOperation() {
+        String usernameExpected = "username1";
+        Authentication authenticationRequest = new TestingAuthenticationToken("any", "any", null);
+        mapper.setUsername(usernameExpected);
+
+        String username = mapper.map(authenticationRequest);
+
+        assertEquals(usernameExpected, username);
+    }
+
+    /**
+     * Test method for
+     * {@link org.springframework.security.userdetails.preauth.UsernameFromPropertyAccountMapper#setUsername(java.lang.String)}.
+     */
+    public final void testSetUsername() {
+        try {
+            mapper.setUsername(null);
+            fail("exception expected");
+        } catch (IllegalArgumentException expected) {
+        } catch (Exception unexpected) {
+            fail("unexpected exception");
+        }
+    }
+
+    /**
+     * Test method for
+     * {@link org.springframework.security.userdetails.preauth.UsernameFromPropertyAccountMapper#afterPropertiesSet()}.
+     */
+    public final void testAfterPropertiesSet() {
+        try {
+            mapper.afterPropertiesSet();
+            fail("expected exception");
+        } catch (IllegalArgumentException expected) {
+        } catch (Exception unexpected) {
+            fail("unexpected exception");
+        }
+    }
+}

+ 60 - 0
sandbox/other/src/test/java/org/springframework/security/userdetails/preauth/UsernameFromRequestAccountMapperTest.java

@@ -0,0 +1,60 @@
+/* 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 org.springframework.security.userdetails.preauth;
+
+import junit.framework.TestCase;
+
+import org.springframework.security.Authentication;
+import org.springframework.security.providers.TestingAuthenticationToken;
+
+/**
+ * @author Valery Tydykov
+ * 
+ */
+public class UsernameFromRequestAccountMapperTest extends TestCase {
+
+    UsernameFromRequestAccountMapper mapper;
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see junit.framework.TestCase#setUp()
+     */
+    protected void setUp() throws Exception {
+        mapper = new UsernameFromRequestAccountMapper();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see junit.framework.TestCase#tearDown()
+     */
+    protected void tearDown() throws Exception {
+        mapper = null;
+    }
+
+    /**
+     * Test method for
+     * {@link org.springframework.security.userdetails.preauth.UsernameFromRequestAccountMapper#map(org.springframework.security.Authentication)}.
+     */
+    public final void testNormalOperation() {
+        String usernameExpected = "username1";
+        Authentication authenticationRequest = new TestingAuthenticationToken(usernameExpected,
+            "password1", null);
+        String username = mapper.map(authenticationRequest);
+
+        assertEquals(usernameExpected, username);
+    }
+}

+ 33 - 0
sandbox/other/src/test/java/org/springframework/security/util/AllTests.java

@@ -0,0 +1,33 @@
+/* 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 org.springframework.security.util;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+public class AllTests extends TestCase {
+
+    public AllTests(String s) {
+        super(s);
+    }
+
+    public static Test suite() {
+        TestSuite suite = new TestSuite();
+        suite.addTestSuite(org.springframework.security.util.ServletUtilsTest.class);
+        suite.addTestSuite(org.springframework.security.util.StringUtilsTest.class);
+        return suite;
+    }
+}

+ 124 - 0
sandbox/other/src/test/java/org/springframework/security/util/ServletUtilsTest.java

@@ -0,0 +1,124 @@
+/* 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 org.springframework.security.util;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.Cookie;
+
+import junit.framework.TestCase;
+
+import org.springframework.mock.web.MockHttpServletRequest;
+
+/**
+ * @author Valery Tydykov
+ * 
+ */
+public class ServletUtilsTest extends TestCase {
+
+    /**
+     * Test method for
+     * {@link org.springframework.security.util.ServletUtils#extractHeaderValues(javax.servlet.http.HttpServletRequest, java.util.List)}.
+     */
+    public final void testExtractHeaderValues() {
+        List keys = new ArrayList();
+        String key1 = "key1";
+        keys.add(key1);
+        String key2 = "key2";
+        keys.add(key2);
+        String key3 = "key3";
+        keys.add(key3);
+
+        MockHttpServletRequest request = new MockHttpServletRequest();
+        String value1 = "value1";
+        request.addHeader(key1, value1);
+        String value2 = "value2";
+        request.addHeader(key2, value2);
+
+        Map values = ServletUtils.extractHeaderValues(request, keys);
+
+        assertEquals(value1, values.get(key1));
+        assertEquals(value2, values.get(key2));
+        assertEquals(null, values.get(key3));
+    }
+
+    /**
+     * Test method for
+     * {@link org.springframework.security.util.ServletUtils#extractCookiesValues(javax.servlet.http.HttpServletRequest, java.util.List)}.
+     */
+    public final void testExtractCookiesValues() {
+        List keys = new ArrayList();
+        String key1 = "key1";
+        keys.add(key1);
+        String key2 = "key2";
+        keys.add(key2);
+        String key3 = "key3";
+        keys.add(key3);
+
+        MockHttpServletRequest request = new MockHttpServletRequest();
+        String value1 = "value1";
+        String value2 = "value2";
+
+        {
+            Cookie[] cookies = new Cookie[] { new Cookie(key1, value1), new Cookie(key2, value2) };
+            request.setCookies(cookies);
+        }
+
+        Map values = ServletUtils.extractCookiesValues(request, keys);
+
+        assertEquals(value1, values.get(key1));
+        assertEquals(value2, values.get(key2));
+        assertEquals(null, values.get(key3));
+    }
+
+    /**
+     * Test method for
+     * {@link org.springframework.security.util.ServletUtils#findCookieValue(javax.servlet.http.HttpServletRequest, java.lang.String)}.
+     */
+    public final void testFindCookieValue() {
+        List keys = new ArrayList();
+        String key1 = "key1";
+        keys.add(key1);
+
+        MockHttpServletRequest request = new MockHttpServletRequest();
+        String valueExpected = "value1";
+        {
+            Cookie[] cookies = new Cookie[] { new Cookie(key1, valueExpected), };
+            request.setCookies(cookies);
+        }
+
+        String value = ServletUtils.findCookieValue(request, key1);
+
+        assertEquals(valueExpected, value);
+    }
+
+    public final void testFindCookieValueNotFound() {
+        List keys = new ArrayList();
+        String key1 = "key1";
+        keys.add(key1);
+
+        MockHttpServletRequest request = new MockHttpServletRequest();
+        {
+            Cookie[] cookies = new Cookie[0];
+            request.setCookies(cookies);
+        }
+
+        String value = ServletUtils.findCookieValue(request, key1);
+
+        assertEquals(null, value);
+    }
+}

+ 79 - 0
sandbox/other/src/test/java/org/springframework/security/util/StringUtilsTest.java

@@ -0,0 +1,79 @@
+/* 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 org.springframework.security.util;
+
+import java.util.List;
+
+import junit.framework.TestCase;
+
+/**
+ * @author Valery Tydykov
+ * 
+ */
+public class StringUtilsTest extends TestCase {
+
+    /**
+     * Test method for
+     * {@link org.springframework.security.util.StringUtils#tokenizeString(java.lang.String, java.lang.String)}.
+     */
+    public final void testTokenizeString() {
+        {
+            String source = "one,two,three";
+            String separator = ",";
+            List result = StringUtils.tokenizeString(source, separator);
+
+            assertTrue(result.contains("one"));
+            assertTrue(result.contains("two"));
+            assertTrue(result.contains("three"));
+        }
+        {
+            String source = null;
+            String separator = null;
+            List result = StringUtils.tokenizeString(source, separator);
+
+            assertTrue(result.isEmpty());
+        }
+        {
+            String source = "one,two,three";
+            String separator = "noMatch";
+            List result = StringUtils.tokenizeString(source, separator);
+
+            assertTrue(result.contains(source));
+        }
+    }
+
+    /**
+     * Test method for
+     * {@link org.springframework.security.util.StringUtils#notNull(java.lang.Object)}.
+     */
+    public final void testNotNull() {
+        {
+            Object object = null;
+            String result = StringUtils.notNull(object);
+            assertEquals("", result);
+        }
+        {
+            Object object = "myString";
+            String result = StringUtils.notNull(object);
+            assertEquals(object, result);
+        }
+        {
+            String expected = "12345";
+            Object object = new Integer(expected);
+            String result = StringUtils.notNull(object);
+            assertEquals(expected, result);
+        }
+    }
+}

+ 51 - 0
sandbox/other/src/test/java/org/springframework/security/vote/FirstDecisionBased.java

@@ -0,0 +1,51 @@
+/* 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 org.springframework.security.vote;
+
+import java.util.Iterator;
+
+import org.springframework.security.AccessDeniedException;
+import org.springframework.security.Authentication;
+import org.springframework.security.ConfigAttributeDefinition;
+
+/**
+ * AccessDecisionManager which bases its result on the first non-abstention from
+ * its list of voters. 
+ * 
+ * @author Janning Vygen 
+ */
+public class FirstDecisionBased extends AbstractAccessDecisionManager {
+
+	public void decide(Authentication authentication, Object object, ConfigAttributeDefinition config ) throws AccessDeniedException {
+		Iterator voters = this.getDecisionVoters().iterator();
+
+		while (voters.hasNext()) {
+			AccessDecisionVoter voter = (AccessDecisionVoter) voters.next();
+			int result = voter.vote(authentication, object, config);
+			
+			switch (result) {
+				case AccessDecisionVoter.ACCESS_GRANTED:
+				return;
+				
+				case AccessDecisionVoter.ACCESS_DENIED:
+					throw new AccessDeniedException(messages.getMessage("AbstractAccessDecisionManager.accessDenied", "Access is denied"));
+			}
+		}
+		
+		// To get this far, every AccessDecisionVoter abstained
+		checkAllowIfAllAbstainDecisions();
+	}
+}