Forráskód Böngészése

SEC-1036: Upgraded Spring LDAP to 1.3 and made corresponding code changes. Also some general tidying up of LDAP code. Removed deprecated context factory classes.

Luke Taylor 17 éve
szülő
commit
66897e1849

+ 1 - 1
core/pom.xml

@@ -62,7 +62,7 @@
         </dependency>
         <dependency>
             <groupId>org.springframework.ldap</groupId>
-            <artifactId>spring-ldap</artifactId>
+            <artifactId>spring-ldap-core</artifactId>
             <optional>true</optional>
         </dependency>
         <dependency>

+ 0 - 16
core/src/main/java/org/springframework/security/context/HttpSessionContextIntegrationFilter.java

@@ -15,22 +15,9 @@
 
 package org.springframework.security.context;
 
-import java.io.IOException;
-import java.lang.reflect.Method;
-
-import javax.servlet.FilterChain;
 import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpServletResponseWrapper;
-import javax.servlet.http.HttpSession;
 
 import org.springframework.beans.factory.InitializingBean;
-import org.springframework.util.Assert;
-import org.springframework.util.ReflectionUtils;
-import org.springframework.security.AuthenticationTrustResolver;
-import org.springframework.security.AuthenticationTrustResolverImpl;
-import org.springframework.security.ui.SpringSecurityFilter;
 import org.springframework.security.ui.FilterChainOrder;
 
 /**
@@ -110,8 +97,6 @@ public class HttpSessionContextIntegrationFilter extends SecurityContextPersiste
 
     private Class<? extends SecurityContext> contextClass = SecurityContextImpl.class;
 
-//    private Object contextObject;
-
     /**
      * Indicates if this filter can create a <code>HttpSession</code> if
      * needed (sessions are always created sparingly, but setting this value to
@@ -160,7 +145,6 @@ public class HttpSessionContextIntegrationFilter extends SecurityContextPersiste
     private HttpSessionSecurityContextRepository repo = new HttpSessionSecurityContextRepository();
 
     public HttpSessionContextIntegrationFilter() throws ServletException {
-//        this.contextObject = generateNewContext();
         super.setSecurityContextRepository(repo);
     }
 

+ 0 - 364
core/src/main/java/org/springframework/security/ldap/DefaultInitialDirContextFactory.java

@@ -1,364 +0,0 @@
-/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.security.ldap;
-
-import org.springframework.security.SpringSecurityMessageSource;
-import org.springframework.security.BadCredentialsException;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.springframework.context.MessageSource;
-import org.springframework.context.MessageSourceAware;
-import org.springframework.context.support.MessageSourceAccessor;
-
-import org.springframework.util.Assert;
-import org.springframework.ldap.UncategorizedLdapException;
-import org.springframework.ldap.core.support.DefaultDirObjectFactory;
-import org.springframework.ldap.core.DistinguishedName;
-import org.springframework.dao.DataAccessException;
-
-import java.util.Hashtable;
-import java.util.Map;
-import java.util.StringTokenizer;
-
-import javax.naming.CommunicationException;
-import javax.naming.Context;
-import javax.naming.NamingException;
-import javax.naming.OperationNotSupportedException;
-import javax.naming.ldap.InitialLdapContext;
-import javax.naming.directory.DirContext;
-import javax.naming.directory.InitialDirContext;
-
-
-/**
- * Encapsulates the information for connecting to an LDAP server and provides an access point for obtaining
- * <tt>DirContext</tt> references.
- * <p>
- * The directory location is configured using by setting the constructor argument
- * <tt>providerUrl</tt>. This should be in the form <tt>ldap://monkeymachine.co.uk:389/dc=springframework,dc=org</tt>.
- * The Sun JNDI provider also supports lists of space-separated URLs, each of which will be tried in turn until a
- * connection is obtained.
- * </p>
- *  <p>To obtain an initial context, the client calls the <tt>newInitialDirContext</tt> method. There are two
- * signatures - one with no arguments and one which allows binding with a specific username and password.
- * </p>
- *  <p>The no-args version will bind anonymously unless a manager login has been configured using the properties
- * <tt>managerDn</tt> and <tt>managerPassword</tt>, in which case it will bind as the manager user.</p>
- *  <p>Connection pooling is enabled by default for anonymous or manager connections, but not when binding as a
- * specific user.</p>
- *
- * @author Robert Sanders
- * @author Luke Taylor
- * @version $Id$
- *
- *
- * @deprecated use {@link DefaultSpringSecurityContextSource} instead.
- *
- * @see <a href="http://java.sun.com/products/jndi/tutorial/ldap/connect/pool.html">The Java tutorial's guide to LDAP
- *      connection pooling</a>
- */
-public class DefaultInitialDirContextFactory implements InitialDirContextFactory,
-        SpringSecurityContextSource, MessageSourceAware {
-    //~ Static fields/initializers =====================================================================================
-
-    private static final Log logger = LogFactory.getLog(DefaultInitialDirContextFactory.class);
-    private static final String CONNECTION_POOL_KEY = "com.sun.jndi.ldap.connect.pool";
-    private static final String AUTH_TYPE_NONE = "none";
-
-    //~ Instance fields ================================================================================================
-
-    /** Allows extra environment variables to be added at config time. */
-    private Map extraEnvVars = null;
-    protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
-
-    /** Type of authentication within LDAP; default is simple. */
-    private String authenticationType = "simple";
-
-    /**
-     * The INITIAL_CONTEXT_FACTORY used to create the JNDI Factory. Default is
-     * "com.sun.jndi.ldap.LdapCtxFactory"; you <b>should not</b> need to set this unless you have unusual needs.
-     */
-    private String initialContextFactory = "com.sun.jndi.ldap.LdapCtxFactory";
-
-    private String dirObjectFactoryClass = DefaultDirObjectFactory.class.getName();
-
-    /**
-     * If your LDAP server does not allow anonymous searches then you will need to provide a "manager" user's
-     * DN to log in with.
-     */
-    private String managerDn = null;
-
-    /** The manager user's password. */
-    private String managerPassword = "manager_password_not_set";
-
-    /** The LDAP url of the server (and root context) to connect to. */
-    private String providerUrl;
-
-    /**
-     * The root DN. This is worked out from the url. It is used by client classes when forming a full DN for
-     * bind authentication (for example).
-     */
-    private String rootDn = null;
-
-    /**
-     * Use the LDAP Connection pool; if true, then the LDAP environment property
-     * "com.sun.jndi.ldap.connect.pool" is added to any other JNDI properties.
-     */
-    private boolean useConnectionPool = true;
-
-    /** Set to true for ldap v3 compatible servers */
-    private boolean useLdapContext = false;
-
-    //~ Constructors ===================================================================================================
-
-    /**
-     * Create and initialize an instance to the LDAP url provided
-     *
-     * @param providerUrl a String of the form <code>ldap://localhost:389/base_dn<code>
-     */
-    public DefaultInitialDirContextFactory(String providerUrl) {
-        this.setProviderUrl(providerUrl);
-    }
-
-    //~ Methods ========================================================================================================
-
-    /**
-     * Set the LDAP url
-     *
-     * @param providerUrl a String of the form <code>ldap://localhost:389/base_dn<code>
-     */
-    private void setProviderUrl(String providerUrl) {
-        Assert.hasLength(providerUrl, "An LDAP connection URL must be supplied.");
-
-        this.providerUrl = providerUrl;
-
-        StringTokenizer st = new StringTokenizer(providerUrl);
-
-        // Work out rootDn from the first URL and check that the other URLs (if any) match
-        while (st.hasMoreTokens()) {
-            String url = st.nextToken();
-            String urlRootDn = LdapUtils.parseRootDnFromUrl(url);
-
-            logger.info(" URL '" + url + "', root DN is '" + urlRootDn + "'");
-
-            if (rootDn == null) {
-                rootDn = urlRootDn;
-            } else if (!rootDn.equals(urlRootDn)) {
-                throw new IllegalArgumentException("Root DNs must be the same when using multiple URLs");
-            }
-        }
-
-        // This doesn't necessarily hold for embedded servers.
-        //Assert.isTrue(uri.getScheme().equals("ldap"), "Ldap URL must start with 'ldap://'");
-    }
-
-    /**
-     * Get the LDAP url
-     *
-     * @return the url
-     */
-    private String getProviderUrl() {
-        return providerUrl;
-    }
-
-    private InitialDirContext connect(Hashtable env) {
-        if (logger.isDebugEnabled()) {
-            Hashtable envClone = (Hashtable) env.clone();
-
-            if (envClone.containsKey(Context.SECURITY_CREDENTIALS)) {
-                envClone.put(Context.SECURITY_CREDENTIALS, "******");
-            }
-
-            logger.debug("Creating InitialDirContext with environment " + envClone);
-        }
-
-        try {
-            return useLdapContext ? new InitialLdapContext(env, null) : new InitialDirContext(env);
-        } catch (NamingException ne) {
-            if ((ne instanceof javax.naming.AuthenticationException)
-                    || (ne instanceof OperationNotSupportedException)) {
-                throw new BadCredentialsException(messages.getMessage("DefaultIntitalDirContextFactory.badCredentials",
-                        "Bad credentials"), ne);
-            }
-
-            if (ne instanceof CommunicationException) {
-                throw new UncategorizedLdapException(messages.getMessage(
-                        "DefaultIntitalDirContextFactory.communicationFailure", "Unable to connect to LDAP server"), ne);
-            }
-
-            throw new UncategorizedLdapException(messages.getMessage(
-                    "DefaultIntitalDirContextFactory.unexpectedException",
-                    "Failed to obtain InitialDirContext due to unexpected exception"), ne);
-        }
-    }
-
-    /**
-     * Sets up the environment parameters for creating a new context.
-     *
-     * @return the Hashtable describing the base DirContext that will be created, minus the username/password if any.
-     */
-    protected Hashtable getEnvironment() {
-        Hashtable env = new Hashtable();
-
-        env.put(Context.SECURITY_AUTHENTICATION, authenticationType);
-        env.put(Context.INITIAL_CONTEXT_FACTORY, initialContextFactory);
-        env.put(Context.PROVIDER_URL, getProviderUrl());
-
-        if (useConnectionPool) {
-            env.put(CONNECTION_POOL_KEY, "true");
-        }
-
-        if ((extraEnvVars != null) && (extraEnvVars.size() > 0)) {
-            env.putAll(extraEnvVars);
-        }
-
-        return env;
-    }
-
-    /**
-     * Returns the root DN of the configured provider URL. For example, if the URL is
-     * <tt>ldap://monkeymachine.co.uk:389/dc=springframework,dc=org</tt> the value will be
-     * <tt>dc=springframework,dc=org</tt>.
-     *
-     * @return the root DN calculated from the path of the LDAP url.
-     */
-    public String getRootDn() {
-        return rootDn;
-    }
-
-    /**
-     * Connects anonymously unless a manager user has been specified, in which case it will bind as the
-     * manager.
-     *
-     * @return the resulting context object.
-     */
-    public DirContext newInitialDirContext() {
-        if (managerDn != null) {
-            return newInitialDirContext(managerDn, managerPassword);
-        }
-
-        Hashtable env = getEnvironment();
-        env.put(Context.SECURITY_AUTHENTICATION, AUTH_TYPE_NONE);
-
-        return connect(env);
-    }
-
-    public DirContext newInitialDirContext(String username, String password) {
-        Hashtable env = getEnvironment();
-
-        // Don't pool connections for individual users
-        if (!username.equals(managerDn)) {
-            env.remove(CONNECTION_POOL_KEY);
-        }
-
-        env.put(Context.SECURITY_PRINCIPAL, username);
-        env.put(Context.SECURITY_CREDENTIALS, password);
-
-        if(dirObjectFactoryClass != null) {
-            env.put(Context.OBJECT_FACTORIES, dirObjectFactoryClass);
-        }
-
-        return connect(env);
-    }
-
-    /** Spring LDAP <tt>ContextSource</tt> method */
-    public DirContext getReadOnlyContext() throws DataAccessException {
-        return newInitialDirContext();
-    }
-
-    /** Spring LDAP <tt>ContextSource</tt> method */
-    public DirContext getReadWriteContext() throws DataAccessException {
-        return newInitialDirContext();
-    }
-
-    public void setAuthenticationType(String authenticationType) {
-        Assert.hasLength(authenticationType, "LDAP Authentication type must not be empty or null");
-        this.authenticationType = authenticationType;
-    }
-
-    /**
-     * Sets any custom environment variables which will be added to the those returned
-     * by the <tt>getEnvironment</tt> method.
-     *
-     * @param extraEnvVars extra environment variables to be added at config time.
-     */
-    public void setExtraEnvVars(Map extraEnvVars) {
-        Assert.notNull(extraEnvVars, "Extra environment map cannot be null.");
-        this.extraEnvVars = extraEnvVars;
-    }
-
-    public void setInitialContextFactory(String initialContextFactory) {
-        Assert.hasLength(initialContextFactory, "Initial context factory name cannot be empty or null");
-        this.initialContextFactory = initialContextFactory;
-    }
-
-    /**
-     * Sets the directory user to authenticate as when obtaining a context using the
-     * <tt>newInitialDirContext()</tt> method.
-     * If no name is supplied then the context will be obtained anonymously.
-     *
-     * @param managerDn The name of the "manager" user for default authentication.
-     */
-    public void setManagerDn(String managerDn) {
-        Assert.hasLength(managerDn, "Manager user name  cannot be empty or null.");
-        this.managerDn = managerDn;
-    }
-
-    /**
-     * Sets the password which will be used in combination with the manager DN.
-     *
-     * @param managerPassword The "manager" user's password.
-     */
-    public void setManagerPassword(String managerPassword) {
-        Assert.hasLength(managerPassword, "Manager password must not be empty or null.");
-        this.managerPassword = managerPassword;
-    }
-
-    public void setMessageSource(MessageSource messageSource) {
-        this.messages = new MessageSourceAccessor(messageSource);
-    }
-
-    /**
-     * Connection pooling is enabled by default for anonymous or "manager" connections when using the default
-     * Sun provider. To disable all connection pooling, set this property to false.
-     *
-     * @param useConnectionPool whether to pool connections for non-specific users.
-     */
-    public void setUseConnectionPool(boolean useConnectionPool) {
-        this.useConnectionPool = useConnectionPool;
-    }
-
-    public void setUseLdapContext(boolean useLdapContext) {
-        this.useLdapContext = useLdapContext;
-    }
-
-    public void setDirObjectFactory(String dirObjectFactory) {
-        this.dirObjectFactoryClass = dirObjectFactory;
-    }
-
-    public DirContext getReadWriteContext(String userDn, Object credentials) {
-        return newInitialDirContext(userDn, (String) credentials);
-    }
-
-    public DistinguishedName getBaseLdapPath() {
-        return new DistinguishedName(rootDn);
-    }
-
-    public String getBaseLdapPathAsString() {
-        return getBaseLdapPath().toString();
-    }
-}

+ 0 - 58
core/src/main/java/org/springframework/security/ldap/InitialDirContextFactory.java

@@ -1,58 +0,0 @@
-/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.security.ldap;
-
-import javax.naming.directory.DirContext;
-
-
-/**
- * Access point for obtaining LDAP contexts.
- *
- * @see org.springframework.security.ldap.DefaultInitialDirContextFactory
- *
- * @deprecated Use SpringSecurityContextSource instead
- * @author Luke Taylor
- * @version $Id$
- */
-public interface InitialDirContextFactory {
-    //~ Methods ========================================================================================================
-
-    /**
-     * Returns the root DN of the contexts supplied by this factory.
-     * The names for searches etc. which are performed against contexts
-     * returned by this factory should be relative to the root DN.
-     *
-     * @return The DN of the contexts returned by this factory.
-     */
-    String getRootDn();
-
-    /**
-     * Provides an initial context without specific user information.
-     *
-     * @return An initial context for the LDAP directory
-     */
-    DirContext newInitialDirContext();
-
-    /**
-     * Provides an initial context by binding as a specific user.
-     *
-     * @param userDn the user to authenticate as when obtaining the context.
-     * @param password the user's password.
-     *
-     * @return An initial context for the LDAP directory
-     */
-    DirContext newInitialDirContext(String userDn, String password);
-}

+ 2 - 0
core/src/main/java/org/springframework/security/ldap/SpringSecurityContextSource.java

@@ -11,6 +11,8 @@ import javax.naming.directory.DirContext;
  * @author Luke Taylor
  * @version $Id$
  * @since 2.0
+ *
+ * @deprecated As of Spring LDAP 1.3, ContextSource provides this method itself.
  */
 public interface SpringSecurityContextSource extends BaseLdapPathContextSource {
 

+ 6 - 6
core/src/main/java/org/springframework/security/ldap/SpringSecurityLdapTemplate.java

@@ -90,7 +90,7 @@ public class SpringSecurityLdapTemplate extends LdapTemplate {
                 ctls.setReturningAttributes(NO_ATTRS);
                 ctls.setSearchScope(SearchControls.OBJECT_SCOPE);
 
-                NamingEnumeration results = ctx.search(dn, comparisonFilter, new Object[] {value}, ctls);
+                NamingEnumeration<SearchResult> results = ctx.search(dn, comparisonFilter, new Object[] {value}, ctls);
 
                 return Boolean.valueOf(results.hasMore());
             }
@@ -135,7 +135,7 @@ public class SpringSecurityLdapTemplate extends LdapTemplate {
      *
      * @return the set of String values for the attribute as a union of the values found in all the matching entries.
      */
-    public Set searchForSingleAttributeValues(final String base, final String filter, final Object[] params,
+    public Set<String> searchForSingleAttributeValues(final String base, final String filter, final Object[] params,
             final String attributeName) {
         // Escape the params acording to RFC2254
         Object[] encodedParams = new String[params.length];
@@ -147,7 +147,7 @@ public class SpringSecurityLdapTemplate extends LdapTemplate {
         String formattedFilter = MessageFormat.format(filter, encodedParams);
         logger.debug("Using filter: " + formattedFilter);
 
-        final HashSet set = new HashSet();
+        final HashSet<String> set = new HashSet<String>();
 
         ContextMapper roleMapper = new ContextMapper() {
             public Object mapFromContext(Object ctx) {
@@ -193,12 +193,12 @@ public class SpringSecurityLdapTemplate extends LdapTemplate {
         return (DirContextOperations) executeReadOnly(new ContextExecutor() {
                 public Object executeWithContext(DirContext ctx) throws NamingException {
                     DistinguishedName ctxBaseDn = new DistinguishedName(ctx.getNameInNamespace());
-                    NamingEnumeration resultsEnum = ctx.search(base, filter, params, searchControls);
-                    Set results = new HashSet();
+                    NamingEnumeration<SearchResult> resultsEnum = ctx.search(base, filter, params, searchControls);
+                    Set<DirContextOperations> results = new HashSet<DirContextOperations>();
                     try {
                         while (resultsEnum.hasMore()) {
 
-                            SearchResult searchResult = (SearchResult) resultsEnum.next();
+                            SearchResult searchResult = resultsEnum.next();
                             // Work out the DN of the matched entry
                             StringBuffer dn = new StringBuffer(searchResult.getName());
 

+ 32 - 46
core/src/main/java/org/springframework/security/providers/ldap/authenticator/BindAuthenticator.java

@@ -15,23 +15,22 @@
 
 package org.springframework.security.providers.ldap.authenticator;
 
+import javax.naming.directory.Attributes;
+import javax.naming.directory.DirContext;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.ldap.NamingException;
+import org.springframework.ldap.core.DirContextAdapter;
+import org.springframework.ldap.core.DirContextOperations;
+import org.springframework.ldap.core.DistinguishedName;
+import org.springframework.ldap.core.support.BaseLdapPathContextSource;
+import org.springframework.ldap.support.LdapUtils;
 import org.springframework.security.Authentication;
 import org.springframework.security.BadCredentialsException;
-import org.springframework.security.ldap.SpringSecurityContextSource;
-import org.springframework.security.ldap.SpringSecurityLdapTemplate;
 import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
-import org.springframework.dao.DataAccessException;
-import org.springframework.ldap.core.ContextSource;
-import org.springframework.ldap.core.DirContextOperations;
-import org.springframework.ldap.core.DistinguishedName;
 import org.springframework.util.Assert;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import javax.naming.directory.DirContext;
-import java.util.Iterator;
-
 
 /**
  * An authenticator which binds as a user.
@@ -55,7 +54,7 @@ public class BindAuthenticator extends AbstractLdapAuthenticator {
      * performed.
      *
      */
-    public BindAuthenticator(SpringSecurityContextSource contextSource) {
+    public BindAuthenticator(BaseLdapPathContextSource contextSource) {
         super(contextSource);
     }
 
@@ -70,14 +69,11 @@ public class BindAuthenticator extends AbstractLdapAuthenticator {
         String password = (String)authentication.getCredentials();
 
         // If DN patterns are configured, try authenticating with them directly
-        Iterator dns = getUserDns(username).iterator();
-
-        while (dns.hasNext() && user == null) {
-            user = bindWithDn((String) dns.next(), username, password);
+        for (String dn : getUserDns(username)) {
+            user = bindWithDn(dn, username, password);
         }
 
-        // Otherwise use the configured locator to find the user
-        // and authenticate with the returned DN.
+        // Otherwise use the configured search object to find the user and authenticate with the returned DN.
         if (user == null && getUserSearch() != null) {
             DirContextOperations userFromSearch = getUserSearch().searchForUser(username);
             user = bindWithDn(userFromSearch.getDn().toString(), username, password);
@@ -92,17 +88,29 @@ public class BindAuthenticator extends AbstractLdapAuthenticator {
     }
 
     private DirContextOperations bindWithDn(String userDn, String username, String password) {
-        SpringSecurityLdapTemplate template = new SpringSecurityLdapTemplate(
-                new BindWithSpecificDnContextSource((SpringSecurityContextSource) getContextSource(), userDn, password));
+        BaseLdapPathContextSource ctxSource = (BaseLdapPathContextSource) getContextSource();
+        DistinguishedName fullDn = new DistinguishedName(userDn);
+        fullDn.prepend(ctxSource.getBaseLdapPath());
+
+        logger.debug("Attempting to bind as " + fullDn);
 
         try {
-            return template.retrieveEntry(userDn, getUserAttributes());
+            DirContext ctx = getContextSource().getContext(fullDn.toString(), password);
+            Attributes attrs = ctx.getAttributes(userDn, getUserAttributes());
 
-        } catch (BadCredentialsException e) {
+            return new DirContextAdapter(attrs, new DistinguishedName(userDn), ctxSource.getBaseLdapPath());
+        } catch (NamingException e) {
             // This will be thrown if an invalid user name is used and the method may
             // be called multiple times to try different names, so we trap the exception
             // unless a subclass wishes to implement more specialized behaviour.
-            handleBindException(userDn, username, e.getCause());
+            if ((e instanceof org.springframework.ldap.AuthenticationException)
+                    || (e instanceof org.springframework.ldap.OperationNotSupportedException)) {
+                handleBindException(userDn, username, e);
+            } else {
+                throw e;
+            }
+        } catch (javax.naming.NamingException e) {
+            throw LdapUtils.convertLdapException(e);
         }
 
         return null;
@@ -117,26 +125,4 @@ public class BindAuthenticator extends AbstractLdapAuthenticator {
             logger.debug("Failed to bind as " + userDn + ": " + cause);
         }
     }
-
-    private class BindWithSpecificDnContextSource implements ContextSource {
-        private SpringSecurityContextSource ctxFactory;
-        DistinguishedName userDn;
-        private String password;
-
-        public BindWithSpecificDnContextSource(SpringSecurityContextSource ctxFactory, String userDn, String password) {
-            this.ctxFactory = ctxFactory;
-            this.userDn = new DistinguishedName(userDn);
-            this.userDn.prepend(ctxFactory.getBaseLdapPath());
-            this.password = password;
-        }
-
-        public DirContext getReadOnlyContext() throws DataAccessException {
-            return ctxFactory.getReadWriteContext(userDn.toString(), password);
-        }
-
-        public DirContext getReadWriteContext() throws DataAccessException {
-            return getReadOnlyContext();
-        }
-    }
-
 }

+ 21 - 28
core/src/test/java/org/springframework/security/ldap/AbstractLdapIntegrationTests.java

@@ -14,24 +14,25 @@
  */
 package org.springframework.security.ldap;
 
-import org.springframework.security.config.BeanIds;
-import org.springframework.ldap.core.DistinguishedName;
-import org.springframework.core.io.ClassPathResource;
-import org.springframework.context.support.ClassPathXmlApplicationContext;
-import org.junit.BeforeClass;
-import org.junit.Before;
-import org.junit.AfterClass;
-import org.junit.After;
-import org.apache.directory.server.protocol.shared.store.LdifFileLoader;
-import org.apache.directory.server.core.DirectoryService;
-
-import javax.naming.directory.DirContext;
-import javax.naming.Name;
-import javax.naming.NamingException;
-import javax.naming.NamingEnumeration;
 import javax.naming.Binding;
 import javax.naming.ContextNotEmptyException;
+import javax.naming.Name;
 import javax.naming.NameNotFoundException;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.DirContext;
+
+import org.apache.directory.server.core.DirectoryService;
+import org.apache.directory.server.protocol.shared.store.LdifFileLoader;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.ldap.core.DistinguishedName;
+import org.springframework.ldap.core.support.BaseLdapPathContextSource;
+import org.springframework.security.config.BeanIds;
+import org.springframework.security.util.InMemoryXmlApplicationContext;
 
 /**
  * Based on class borrowed from Spring Ldap project.
@@ -40,7 +41,7 @@ import javax.naming.NameNotFoundException;
  * @version $Id$
  */
 public abstract class AbstractLdapIntegrationTests {
-    private static ClassPathXmlApplicationContext appContext;
+    private static InMemoryXmlApplicationContext appContext;
 
     protected AbstractLdapIntegrationTests() {
     }
@@ -48,7 +49,7 @@ public abstract class AbstractLdapIntegrationTests {
     @BeforeClass
     public static void loadContext() throws NamingException {
         shutdownRunningServers();
-        appContext = new ClassPathXmlApplicationContext("/org/springframework/security/ldap/ldapIntegrationTestContext.xml");
+        appContext = new InMemoryXmlApplicationContext("<ldap-server port='53389' ldif='classpath:test-server.ldif'/>");
 
     }
 
@@ -98,22 +99,14 @@ public abstract class AbstractLdapIntegrationTests {
         }
     }
 
-    public SpringSecurityContextSource getContextSource() {
-        return (SpringSecurityContextSource) appContext.getBean(BeanIds.CONTEXT_SOURCE);
+    public BaseLdapPathContextSource getContextSource() {
+        return (BaseLdapPathContextSource)appContext.getBean(BeanIds.CONTEXT_SOURCE);
     }
 
-    /**
-     * We have both a context source and intitialdircontextfactory. The former is also used in
-     * the cleanAndSetup method so any mods during tests can mess it up.
-     * TODO: Once the initialdircontextfactory stuff has been refactored, revisit this and remove this property.
-     */
-    protected DefaultInitialDirContextFactory getInitialDirContextFactory() {
-        return (DefaultInitialDirContextFactory) appContext.getBean("initialDirContextFactory");
-    }
 
     private void clearSubContexts(DirContext ctx, Name name) throws NamingException {
 
-        NamingEnumeration enumeration = null;
+        NamingEnumeration<Binding> enumeration = null;
         try {
             enumeration = ctx.listBindings(name);
             while (enumeration.hasMore()) {

+ 0 - 209
core/src/test/java/org/springframework/security/ldap/DefaultInitialDirContextFactoryTests.java

@@ -1,209 +0,0 @@
-/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.security.ldap;
-
-import org.springframework.security.SpringSecurityMessageSource;
-import org.springframework.security.BadCredentialsException;
-import org.springframework.ldap.UncategorizedLdapException;
-
-import java.util.Hashtable;
-
-import javax.naming.Context;
-import javax.naming.directory.DirContext;
-
-import static org.junit.Assert.*;
-import org.junit.Test;
-
-/**
- * Tests {@link org.springframework.security.ldap.DefaultInitialDirContextFactory}.
- *
- * @author Luke Taylor
- * @version $Id$
- */
-public class DefaultInitialDirContextFactoryTests extends AbstractLdapIntegrationTests {
-    //~ Instance fields ================================================================================================
-
-    DefaultInitialDirContextFactory idf;
-
-    //~ Methods ========================================================================================================
-
-    public void onSetUp() throws Exception {
-        super.onSetUp();
-        idf = getInitialDirContextFactory();
-        idf.setMessageSource(new SpringSecurityMessageSource());
-    }
-
-    @Test
-    public void testAnonymousBindSucceeds() throws Exception {
-        DirContext ctx = idf.newInitialDirContext();
-        // Connection pooling should be set by default for anon users.
-        // Can't rely on this property being there with embedded server
-        // assertEquals("true",ctx.getEnvironment().get("com.sun.jndi.ldap.connect.pool"));
-        ctx.close();
-    }
-
-    @Test
-    public void testBaseDnIsParsedFromCorrectlyFromUrl() {
-        idf = new DefaultInitialDirContextFactory("ldap://springsecurity.org/dc=springframework,dc=org");
-        assertEquals("dc=springframework,dc=org", idf.getRootDn());
-
-        // Check with an empty root
-        idf = new DefaultInitialDirContextFactory("ldap://springsecurity.org/");
-        assertEquals("", idf.getRootDn());
-
-        // Empty root without trailing slash
-        idf = new DefaultInitialDirContextFactory("ldap://springsecurity.org");
-        assertEquals("", idf.getRootDn());
-    }
-
-    @Test
-    public void testBindAsManagerFailsIfNoPasswordSet() throws Exception {
-        idf.setManagerDn("uid=bob,ou=people,dc=springframework,dc=org");
-
-        DirContext ctx = null;
-
-        try {
-            ctx = idf.newInitialDirContext();
-            fail("Binding with no manager password should fail.");
-
-// Can't rely on this property being there with embedded server
-//        assertEquals("true",ctx.getEnvironment().get("com.sun.jndi.ldap.connect.pool"));
-        } catch (BadCredentialsException expected) {}
-
-        LdapUtils.closeContext(ctx);
-    }
-
-    @Test
-    public void testBindAsManagerSucceeds() throws Exception {
-        idf.setManagerPassword("bobspassword");
-        idf.setManagerDn("uid=bob,ou=people,dc=springframework,dc=org");
-
-        DirContext ctx = idf.newInitialDirContext();
-// Can't rely on this property being there with embedded server
-//        assertEquals("true",ctx.getEnvironment().get("com.sun.jndi.ldap.connect.pool"));
-        ctx.close();
-    }
-
-    @Test
-    public void testConnectionAsSpecificUserSucceeds() throws Exception {
-        DirContext ctx = idf.newInitialDirContext("uid=Bob,ou=people,dc=springframework,dc=org", "bobspassword");
-        // We don't want pooling for specific users.
-        // assertNull(ctx.getEnvironment().get("com.sun.jndi.ldap.connect.pool"));
-//        com.sun.jndi.ldap.LdapPoolManager.showStats(System.out);
-        ctx.close();
-    }
-
-    @Test
-    public void testConnectionFailure() throws Exception {
-        // Use the wrong port
-        idf = new DefaultInitialDirContextFactory("ldap://localhost:60389");
-        idf.setInitialContextFactory("com.sun.jndi.ldap.LdapCtxFactory");
-
-        Hashtable env = new Hashtable();
-        env.put("com.sun.jndi.ldap.connect.timeout", "200");
-        idf.setExtraEnvVars(env);
-        idf.setUseConnectionPool(false); // coverage purposes only
-
-        try {
-            idf.newInitialDirContext();
-            fail("Connection succeeded unexpectedly");
-        } catch (UncategorizedLdapException expected) {}
-    }
-
-    @Test
-    public void testEnvironment() {
-        idf = new DefaultInitialDirContextFactory("ldap://springsecurity.org/");
-
-        // check basic env
-        Hashtable env = idf.getEnvironment();
-        //assertEquals("com.sun.jndi.ldap.LdapCtxFactory", env.get(Context.INITIAL_CONTEXT_FACTORY));
-        assertEquals("ldap://springsecurity.org/", env.get(Context.PROVIDER_URL));
-        assertEquals("simple", env.get(Context.SECURITY_AUTHENTICATION));
-        assertNull(env.get(Context.SECURITY_PRINCIPAL));
-        assertNull(env.get(Context.SECURITY_CREDENTIALS));
-
-        // Ctx factory.
-        idf.setInitialContextFactory("org.springframework.security.NonExistentCtxFactory");
-        env = idf.getEnvironment();
-        assertEquals("org.springframework.security.NonExistentCtxFactory", env.get(Context.INITIAL_CONTEXT_FACTORY));
-
-        // Auth type
-        idf.setAuthenticationType("myauthtype");
-        env = idf.getEnvironment();
-        assertEquals("myauthtype", env.get(Context.SECURITY_AUTHENTICATION));
-
-        // Check extra vars
-        Hashtable extraVars = new Hashtable();
-        extraVars.put("extravar", "extravarvalue");
-        idf.setExtraEnvVars(extraVars);
-        env = idf.getEnvironment();
-        assertEquals("extravarvalue", env.get("extravar"));
-    }
-
-    @Test
-    public void testInvalidPasswordCausesBadCredentialsException() throws Exception {
-        idf.setManagerDn("uid=bob,ou=people,dc=springframework,dc=org");
-        idf.setManagerPassword("wrongpassword");
-
-        DirContext ctx = null;
-
-        try {
-            ctx = idf.newInitialDirContext();
-            fail("Binding with wrong credentials should fail.");
-        } catch (BadCredentialsException expected) {}
-
-        LdapUtils.closeContext(ctx);
-    }
-
-    @Test
-    public void testMultipleProviderUrlsAreAccepted() {
-        idf = new DefaultInitialDirContextFactory("ldaps://security.org/dc=springframework,dc=org "
-                + "ldap://monkeymachine.co.uk/dc=springframework,dc=org");
-    }
-
-    @Test
-    public void testMultipleProviderUrlsWithDifferentRootsAreRejected() {
-        try {
-            idf = new DefaultInitialDirContextFactory("ldap://security.org/dc=springframework,dc=org "
-                    + "ldap://monkeymachine.co.uk/dc=someotherplace,dc=org");
-            fail("Different root DNs should cause an exception");
-        } catch (IllegalArgumentException expected) {}
-    }
-
-    @Test
-    public void testSecureLdapUrlIsSupported() {
-        idf = new DefaultInitialDirContextFactory("ldaps://localhost/dc=springframework,dc=org");
-        assertEquals("dc=springframework,dc=org", idf.getRootDn());
-    }
-
-//    public void testNonLdapUrlIsRejected() throws Exception {
-//        DefaultInitialDirContextFactory idf = new DefaultInitialDirContextFactory();
-//
-//        idf.setUrl("http://security.org/dc=springframework,dc=org");
-//        idf.setInitialContextFactory(CoreContextFactory.class.getName());
-//
-//        try {
-//            idf.afterPropertiesSet();
-//            fail("Expected exception for non 'ldap://' URL");
-//        } catch(IllegalArgumentException expected) {
-//        }
-//    }
-    @Test
-    public void testServiceLocationUrlIsSupported() {
-        idf = new DefaultInitialDirContextFactory("ldap:///dc=springframework,dc=org");
-        assertEquals("dc=springframework,dc=org", idf.getRootDn());
-    }
-}

+ 6 - 4
core/src/test/java/org/springframework/security/ldap/MockSpringSecurityContextSource.java

@@ -15,10 +15,12 @@
 
 package org.springframework.security.ldap;
 
+import javax.naming.directory.DirContext;
+
 import org.springframework.dao.DataAccessException;
+import org.springframework.ldap.NamingException;
 import org.springframework.ldap.core.DistinguishedName;
-
-import javax.naming.directory.DirContext;
+import org.springframework.ldap.core.support.BaseLdapPathContextSource;
 
 
 /**
@@ -26,7 +28,7 @@ import javax.naming.directory.DirContext;
  * @author Luke Taylor
  * @version $Id$
  */
-public class MockSpringSecurityContextSource implements SpringSecurityContextSource {
+public class MockSpringSecurityContextSource implements BaseLdapPathContextSource {
     //~ Instance fields ================================================================================================
 
     private DirContext ctx;
@@ -52,7 +54,7 @@ public class MockSpringSecurityContextSource implements SpringSecurityContextSou
         return ctx;
     }
 
-    public DirContext getReadWriteContext(String userDn, Object credentials) {
+    public DirContext getContext(String principal, String credentials) throws NamingException {
         return ctx;
     }
 

+ 2 - 2
core/src/test/java/org/springframework/security/ldap/SpringSecurityAuthenticationSourceTests.java

@@ -64,8 +64,8 @@ public class SpringSecurityAuthenticationSourceTests {
         user.setDn(new DistinguishedName("uid=joe,ou=users"));
         AuthenticationSource source = new SpringSecurityAuthenticationSource();
         SecurityContextHolder.getContext().setAuthentication(
-        		new TestingAuthenticationToken(user.createUserDetails(), null));
+                new TestingAuthenticationToken(user.createUserDetails(), null));
 
-        assertEquals("uid=joe, ou=users", source.getPrincipal());
+        assertEquals("uid=joe,ou=users", source.getPrincipal());
     }
 }

+ 1 - 1
core/src/test/java/org/springframework/security/providers/ldap/authenticator/PasswordComparisonAuthenticatorMockTests.java

@@ -60,7 +60,7 @@ public class PasswordComparisonAuthenticatorMockTests {
         final Attributes searchResults = new BasicAttributes("", null);
 
         context.checking(new Expectations() {{
-            oneOf(dirCtx).search(with(equal("cn=Bob, ou=people")),
+            oneOf(dirCtx).search(with(equal("cn=Bob,ou=people")),
                             with(equal("(userPassword={0})")),
                             with(aNonNull(Object[].class)),
                             with(aNonNull(SearchControls.class)));

+ 1 - 1
core/src/test/java/org/springframework/security/userdetails/ldap/LdapUserDetailsManagerTests.java

@@ -95,7 +95,7 @@ public class LdapUserDetailsManagerTests extends AbstractLdapIntegrationTests {
         mgr.setGroupSearchBase("ou=groups");
         LdapUserDetails bob = (LdapUserDetails) mgr.loadUserByUsername("bob");
         assertEquals("bob", bob.getUsername());
-        assertEquals("uid=bob, ou=people, dc=springframework, dc=org", bob.getDn());
+        assertEquals("uid=bob,ou=people,dc=springframework,dc=org", bob.getDn());
         assertEquals("bobspassword", bob.getPassword());
 
         assertEquals(1, bob.getAuthorities().size());

+ 0 - 18
core/src/test/resources/org/springframework/security/ldap/ldapIntegrationTestContext.xml

@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<beans xmlns="http://www.springframework.org/schema/beans"
-    xmlns:security="http://www.springframework.org/schema/security"
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
-    http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd">
-
-    <security:ldap-server port="53389" ldif="classpath:test-server.ldif"/>
-
-    <!--<import resource="classpath:/org/springframework/security/ldap/apacheDsContext.xml"/>-->
-
-    <bean id="initialDirContextFactory" class="org.springframework.security.ldap.DefaultInitialDirContextFactory" >
-        <constructor-arg value="ldap://127.0.0.1:53389/dc=springframework,dc=org"/>
-        <property name="useLdapContext" value="true"/>
-        <property name="dirObjectFactory" value="org.springframework.ldap.core.support.DefaultDirObjectFactory" />
-	</bean>
-
-</beans>