HttpSession 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);
}
diff --git a/core/src/main/java/org/springframework/security/ldap/DefaultInitialDirContextFactory.java b/core/src/main/java/org/springframework/security/ldap/DefaultInitialDirContextFactory.java
deleted file mode 100644
index c6f673de29..0000000000
--- a/core/src/main/java/org/springframework/security/ldap/DefaultInitialDirContextFactory.java
+++ /dev/null
@@ -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
- * DirContext references.
- * - * The directory location is configured using by setting the constructor argument - * providerUrl. This should be in the form ldap://monkeymachine.co.uk:389/dc=springframework,dc=org. - * The Sun JNDI provider also supports lists of space-separated URLs, each of which will be tried in turn until a - * connection is obtained. - *
- *To obtain an initial context, the client calls the newInitialDirContext method. There are two - * signatures - one with no arguments and one which allows binding with a specific username and password. - *
- *The no-args version will bind anonymously unless a manager login has been configured using the properties - * managerDn and managerPassword, in which case it will bind as the manager user.
- *Connection pooling is enabled by default for anonymous or manager connections, but not when binding as a - * specific user.
- * - * @author Robert Sanders - * @author Luke Taylor - * @version $Id$ - * - * - * @deprecated use {@link DefaultSpringSecurityContextSource} instead. - * - * @see The Java tutorial's guide to LDAP - * connection pooling - */ -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 should not 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 formldap://localhost:389/base_dn
- */
- public DefaultInitialDirContextFactory(String providerUrl) {
- this.setProviderUrl(providerUrl);
- }
-
- //~ Methods ========================================================================================================
-
- /**
- * Set the LDAP url
- *
- * @param providerUrl a String of the form ldap://localhost:389/base_dn
- */
- 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
- * ldap://monkeymachine.co.uk:389/dc=springframework,dc=org the value will be
- * dc=springframework,dc=org.
- *
- * @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 ContextSource method */
- public DirContext getReadOnlyContext() throws DataAccessException {
- return newInitialDirContext();
- }
-
- /** Spring LDAP ContextSource 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 getEnvironment 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
- * newInitialDirContext() 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();
- }
-}
diff --git a/core/src/main/java/org/springframework/security/ldap/InitialDirContextFactory.java b/core/src/main/java/org/springframework/security/ldap/InitialDirContextFactory.java
deleted file mode 100644
index 87111dd15a..0000000000
--- a/core/src/main/java/org/springframework/security/ldap/InitialDirContextFactory.java
+++ /dev/null
@@ -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);
-}
diff --git a/core/src/main/java/org/springframework/security/ldap/SpringSecurityContextSource.java b/core/src/main/java/org/springframework/security/ldap/SpringSecurityContextSource.java
index 89663d6c4b..3919d3cdec 100644
--- a/core/src/main/java/org/springframework/security/ldap/SpringSecurityContextSource.java
+++ b/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 {
diff --git a/core/src/main/java/org/springframework/security/ldap/SpringSecurityLdapTemplate.java b/core/src/main/java/org/springframework/security/ldap/SpringSecurityLdapTemplate.java
index a3edf94c44..50f10bd53d 100644
--- a/core/src/main/java/org/springframework/security/ldap/SpringSecurityLdapTemplate.java
+++ b/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 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 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 set = new HashSet();
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 resultsEnum = ctx.search(base, filter, params, searchControls);
+ Set results = new HashSet();
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());
diff --git a/core/src/main/java/org/springframework/security/providers/ldap/authenticator/BindAuthenticator.java b/core/src/main/java/org/springframework/security/providers/ldap/authenticator/BindAuthenticator.java
index 82b4af5cb8..088580e2d6 100644
--- a/core/src/main/java/org/springframework/security/providers/ldap/authenticator/BindAuthenticator.java
+++ b/core/src/main/java/org/springframework/security/providers/ldap/authenticator/BindAuthenticator.java
@@ -15,22 +15,21 @@
package org.springframework.security.providers.ldap.authenticator;
-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 javax.naming.directory.Attributes;
+import javax.naming.directory.DirContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-
-import javax.naming.directory.DirContext;
-import java.util.Iterator;
+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.providers.UsernamePasswordAuthenticationToken;
+import org.springframework.util.Assert;
/**
@@ -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();
- }
- }
-
}
diff --git a/core/src/test/java/org/springframework/security/ldap/AbstractLdapIntegrationTests.java b/core/src/test/java/org/springframework/security/ldap/AbstractLdapIntegrationTests.java
index 131ac9d8d0..9fdc8e8d9b 100644
--- a/core/src/test/java/org/springframework/security/ldap/AbstractLdapIntegrationTests.java
+++ b/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(" ");
}
@@ -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 enumeration = null;
try {
enumeration = ctx.listBindings(name);
while (enumeration.hasMore()) {
diff --git a/core/src/test/java/org/springframework/security/ldap/DefaultInitialDirContextFactoryTests.java b/core/src/test/java/org/springframework/security/ldap/DefaultInitialDirContextFactoryTests.java
deleted file mode 100644
index fc7d343c85..0000000000
--- a/core/src/test/java/org/springframework/security/ldap/DefaultInitialDirContextFactoryTests.java
+++ /dev/null
@@ -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());
- }
-}
diff --git a/core/src/test/java/org/springframework/security/ldap/MockSpringSecurityContextSource.java b/core/src/test/java/org/springframework/security/ldap/MockSpringSecurityContextSource.java
index 8a0276857c..ad34b3dd6a 100644
--- a/core/src/test/java/org/springframework/security/ldap/MockSpringSecurityContextSource.java
+++ b/core/src/test/java/org/springframework/security/ldap/MockSpringSecurityContextSource.java
@@ -15,18 +15,20 @@
package org.springframework.security.ldap;
-import org.springframework.dao.DataAccessException;
-import org.springframework.ldap.core.DistinguishedName;
-
import javax.naming.directory.DirContext;
+import org.springframework.dao.DataAccessException;
+import org.springframework.ldap.NamingException;
+import org.springframework.ldap.core.DistinguishedName;
+import org.springframework.ldap.core.support.BaseLdapPathContextSource;
+
/**
*
* @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;
}
diff --git a/core/src/test/java/org/springframework/security/ldap/SpringSecurityAuthenticationSourceTests.java b/core/src/test/java/org/springframework/security/ldap/SpringSecurityAuthenticationSourceTests.java
index b465498d77..23e5a9d7d3 100644
--- a/core/src/test/java/org/springframework/security/ldap/SpringSecurityAuthenticationSourceTests.java
+++ b/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());
}
}
diff --git a/core/src/test/java/org/springframework/security/providers/ldap/authenticator/PasswordComparisonAuthenticatorMockTests.java b/core/src/test/java/org/springframework/security/providers/ldap/authenticator/PasswordComparisonAuthenticatorMockTests.java
index 0a239c20e1..f7beeee001 100644
--- a/core/src/test/java/org/springframework/security/providers/ldap/authenticator/PasswordComparisonAuthenticatorMockTests.java
+++ b/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)));
diff --git a/core/src/test/java/org/springframework/security/userdetails/ldap/LdapUserDetailsManagerTests.java b/core/src/test/java/org/springframework/security/userdetails/ldap/LdapUserDetailsManagerTests.java
index 2a52bd76db..f3c0ebdb3b 100644
--- a/core/src/test/java/org/springframework/security/userdetails/ldap/LdapUserDetailsManagerTests.java
+++ b/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());
diff --git a/core/src/test/resources/org/springframework/security/ldap/ldapIntegrationTestContext.xml b/core/src/test/resources/org/springframework/security/ldap/ldapIntegrationTestContext.xml
deleted file mode 100644
index cc9f92086a..0000000000
--- a/core/src/test/resources/org/springframework/security/ldap/ldapIntegrationTestContext.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file