SEC-1036: Updated DefaultSpringSecurityContextSource to enable pooling for "manager" users by default but not when binding directly as a user.
This commit is contained in:
parent
bc6878c1c5
commit
6293541b73
|
@ -1,11 +1,14 @@
|
||||||
package org.springframework.security.ldap;
|
package org.springframework.security.ldap;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Hashtable;
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.springframework.ldap.core.support.DirContextAuthenticationStrategy;
|
||||||
import org.springframework.ldap.core.support.LdapContextSource;
|
import org.springframework.ldap.core.support.LdapContextSource;
|
||||||
|
import org.springframework.ldap.core.support.SimpleDirContextAuthenticationStrategy;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -15,6 +18,11 @@ import org.springframework.util.Assert;
|
||||||
* From Spring Security 2.5, Spring LDAP 1.3 is used and the <tt>ContextSource</tt> interface
|
* From Spring Security 2.5, Spring LDAP 1.3 is used and the <tt>ContextSource</tt> interface
|
||||||
* provides support for binding with a username and password. As a result, Spring LDAP <tt>ContextSource</tt>
|
* provides support for binding with a username and password. As a result, Spring LDAP <tt>ContextSource</tt>
|
||||||
* implementations such as <tt>LdapContextSource</tt> may be used directly with Spring Security.
|
* implementations such as <tt>LdapContextSource</tt> may be used directly with Spring Security.
|
||||||
|
* <p>
|
||||||
|
* Spring LDAP 1.3 doesn't have JVM-level LDAP connection pooling enabled by default. This class sets the
|
||||||
|
* <tt>pooled</tt> property to true, but customizes the {@link DirContextAuthenticationStrategy} used to disable
|
||||||
|
* pooling when the <tt>DN</tt> doesn't match the <tt>userDn</tt> property. This prevents pooling for calls
|
||||||
|
* to {@link #getContext(String, String)} to authenticate as specific users.
|
||||||
*
|
*
|
||||||
* @author Luke Taylor
|
* @author Luke Taylor
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
|
@ -53,7 +61,20 @@ public class DefaultSpringSecurityContextSource extends LdapContextSource {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
super.setUrls(urls.toArray(new String[urls.size()]));
|
setUrls(urls.toArray(new String[urls.size()]));
|
||||||
super.setBase(rootDn);
|
setBase(rootDn);
|
||||||
|
setPooled(true);
|
||||||
|
setAuthenticationStrategy(new SimpleDirContextAuthenticationStrategy() {
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void setupEnvironment(Hashtable env, String dn, String password) {
|
||||||
|
super.setupEnvironment(env, dn, password);
|
||||||
|
// Remove the pooling flag unless we are authenticating as the 'manager' user.
|
||||||
|
if (!userDn.equals(dn) && env.containsKey(SUN_LDAP_POOLING_FLAG)) {
|
||||||
|
logger.debug("Removing pooling flag for user " + dn);
|
||||||
|
env.remove(SUN_LDAP_POOLING_FLAG);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
package org.springframework.security.ldap;
|
package org.springframework.security.ldap;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.util.Hashtable;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.springframework.ldap.core.support.AbstractContextSource;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Luke Taylor
|
* @author Luke Taylor
|
||||||
|
@ -9,8 +15,11 @@ import org.junit.Test;
|
||||||
public class DefaultSpringSecurityContextSourceTests {
|
public class DefaultSpringSecurityContextSourceTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void instantiationSucceeds() {
|
public void instantiationSucceedsWithExpectedProperties() {
|
||||||
|
DefaultSpringSecurityContextSource ctxSrc =
|
||||||
new DefaultSpringSecurityContextSource("ldap://blah:789/dc=springframework,dc=org");
|
new DefaultSpringSecurityContextSource("ldap://blah:789/dc=springframework,dc=org");
|
||||||
|
assertFalse(ctxSrc.isAnonymousReadOnly());
|
||||||
|
assertTrue(ctxSrc.isPooled());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -18,4 +27,34 @@ public class DefaultSpringSecurityContextSourceTests {
|
||||||
new DefaultSpringSecurityContextSource("ldap://myhost:10389/dc=spring%20framework,dc=org");
|
new DefaultSpringSecurityContextSource("ldap://myhost:10389/dc=spring%20framework,dc=org");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void poolingFlagIsSetWhenAuthenticationDnMatchesManagerUserDn() throws Exception {
|
||||||
|
EnvExposingDefaultSpringSecurityContextSource ctxSrc =
|
||||||
|
new EnvExposingDefaultSpringSecurityContextSource("ldap://blah:789/dc=springframework,dc=org");
|
||||||
|
ctxSrc.setUserDn("manager");
|
||||||
|
ctxSrc.setPassword("password");
|
||||||
|
ctxSrc.afterPropertiesSet();
|
||||||
|
assertTrue(ctxSrc.getAuthenticatedEnvForTest("manager", "password").containsKey(AbstractContextSource.SUN_LDAP_POOLING_FLAG));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void poolingFlagIsNotSetWhenAuthenticationDnIsNotManagerUserDn() throws Exception {
|
||||||
|
EnvExposingDefaultSpringSecurityContextSource ctxSrc =
|
||||||
|
new EnvExposingDefaultSpringSecurityContextSource("ldap://blah:789/dc=springframework,dc=org");
|
||||||
|
ctxSrc.setUserDn("manager");
|
||||||
|
ctxSrc.setPassword("password");
|
||||||
|
ctxSrc.afterPropertiesSet();
|
||||||
|
assertFalse(ctxSrc.getAuthenticatedEnvForTest("user", "password").containsKey(AbstractContextSource.SUN_LDAP_POOLING_FLAG));
|
||||||
|
}
|
||||||
|
|
||||||
|
static class EnvExposingDefaultSpringSecurityContextSource extends DefaultSpringSecurityContextSource {
|
||||||
|
public EnvExposingDefaultSpringSecurityContextSource(String providerUrl) {
|
||||||
|
super(providerUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
Hashtable getAuthenticatedEnvForTest(String userDn, String password) {
|
||||||
|
return getAuthenticatedEnv(userDn, password);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue