mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-06-01 09:42:13 +00:00
SEC-1661: Use a DistinguishedName to wrap the search base to avoid the need for JNDI escaping.
This commit is contained in:
parent
866615ceaa
commit
077af5e187
@ -8,6 +8,21 @@ objectClass: organizationalUnit
|
|||||||
objectClass: top
|
objectClass: top
|
||||||
ou: users
|
ou: users
|
||||||
|
|
||||||
|
dn: ou=\"quoted people\",dc=springsource,dc=com
|
||||||
|
objectclass: top
|
||||||
|
objectclass: organizationalUnit
|
||||||
|
ou: "quoted people"
|
||||||
|
|
||||||
|
dn: cn=quoteguy,ou=\"quoted people\",dc=springsource,dc=com
|
||||||
|
objectclass: top
|
||||||
|
objectclass: person
|
||||||
|
objectclass: organizationalPerson
|
||||||
|
objectclass: inetOrgPerson
|
||||||
|
cn: quoteguy
|
||||||
|
sn: Quote
|
||||||
|
uid: quoteguy
|
||||||
|
userPassword: quoteguyspassword
|
||||||
|
|
||||||
dn: uid=luke,ou=users,dc=springsource,dc=com
|
dn: uid=luke,ou=users,dc=springsource,dc=com
|
||||||
objectClass: person
|
objectClass: person
|
||||||
objectClass: organizationalPerson
|
objectClass: organizationalPerson
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
|
|
||||||
rm -Rf target/openldap
|
rm -Rf build/openldap
|
||||||
mkdir -p target/openldap
|
mkdir -p build/openldap
|
||||||
/opt/local/libexec/slapd -h ldap://localhost:22389 -d -1 -f slapd.conf &
|
/opt/local/libexec/slapd -h ldap://localhost:22389 -d -1 -f slapd.conf &
|
||||||
sleep 2
|
sleep 2
|
||||||
ldapadd -h localhost -p 22389 -D cn=admin,dc=springsource,dc=com -w password -x -f openldaptest.ldif
|
ldapadd -h localhost -p 22389 -D cn=admin,dc=springsource,dc=com -w password -x -f openldaptest.ldif
|
@ -4,8 +4,8 @@ include /opt/local/etc/openldap/schema/inetorgperson.schema
|
|||||||
include /opt/local/etc/openldap/schema/ppolicy.schema
|
include /opt/local/etc/openldap/schema/ppolicy.schema
|
||||||
|
|
||||||
|
|
||||||
pidfile ./target/slapd.pid
|
pidfile ./build/slapd.pid
|
||||||
argsfile ./target/slapd.args
|
argsfile ./build/slapd.args
|
||||||
|
|
||||||
# Load dynamic backend modules:
|
# Load dynamic backend modules:
|
||||||
modulepath /usr/lib/openldap/modules
|
modulepath /usr/lib/openldap/modules
|
||||||
@ -14,7 +14,7 @@ modulepath /usr/lib/openldap/modules
|
|||||||
# moduleload back_monitor.la
|
# moduleload back_monitor.la
|
||||||
# moduleload back_perl.la
|
# moduleload back_perl.la
|
||||||
|
|
||||||
disallow bind_anon
|
#disallow bind_anon
|
||||||
require authc
|
require authc
|
||||||
|
|
||||||
access to dn.base=""
|
access to dn.base=""
|
||||||
@ -28,7 +28,7 @@ rootdn "cn=admin,dc=springsource,dc=com"
|
|||||||
|
|
||||||
rootpw password
|
rootpw password
|
||||||
|
|
||||||
directory ./target/openldap
|
directory ./build/openldap
|
||||||
|
|
||||||
index uid eq
|
index uid eq
|
||||||
index cn eq
|
index cn eq
|
||||||
@ -49,5 +49,3 @@ ppolicy_default "cn=default,ou=policies,dc=springsource,dc=com"
|
|||||||
ppolicy_use_lockout
|
ppolicy_use_lockout
|
||||||
ppolicy_hash_cleartext
|
ppolicy_hash_cleartext
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -194,11 +194,13 @@ public class SpringSecurityLdapTemplate extends LdapTemplate {
|
|||||||
|
|
||||||
return (DirContextOperations) executeReadOnly(new ContextExecutor() {
|
return (DirContextOperations) executeReadOnly(new ContextExecutor() {
|
||||||
public Object executeWithContext(DirContext ctx) throws NamingException {
|
public Object executeWithContext(DirContext ctx) throws NamingException {
|
||||||
DistinguishedName ctxBaseDn = new DistinguishedName(ctx.getNameInNamespace());
|
final DistinguishedName ctxBaseDn = new DistinguishedName(ctx.getNameInNamespace());
|
||||||
NamingEnumeration<SearchResult> resultsEnum = ctx.search(base, filter, params, searchControls);
|
final DistinguishedName searchBaseDn = new DistinguishedName(base);
|
||||||
|
final NamingEnumeration<SearchResult> resultsEnum = ctx.search(searchBaseDn, filter, params, searchControls);
|
||||||
|
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Searching for entry in under DN '" + ctxBaseDn
|
logger.debug("Searching for entry under DN '" + ctxBaseDn
|
||||||
+ "', base = '" + base + "', filter = '" + filter + "'");
|
+ "', base = '" + searchBaseDn + "', filter = '" + filter + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<DirContextOperations> results = new HashSet<DirContextOperations>();
|
Set<DirContextOperations> results = new HashSet<DirContextOperations>();
|
||||||
@ -209,7 +211,7 @@ public class SpringSecurityLdapTemplate extends LdapTemplate {
|
|||||||
DistinguishedName dn = new DistinguishedName(searchResult.getName());
|
DistinguishedName dn = new DistinguishedName(searchResult.getName());
|
||||||
|
|
||||||
if (base.length() > 0) {
|
if (base.length() > 0) {
|
||||||
dn.prepend(new DistinguishedName(base));
|
dn.prepend(searchBaseDn);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
|
@ -40,7 +40,7 @@ import org.springframework.security.ldap.server.ApacheDSContainer;
|
|||||||
public abstract class AbstractLdapIntegrationTests {
|
public abstract class AbstractLdapIntegrationTests {
|
||||||
// private static InMemoryXmlApplicationContext appContext;
|
// private static InMemoryXmlApplicationContext appContext;
|
||||||
private static ApacheDSContainer server;
|
private static ApacheDSContainer server;
|
||||||
private static BaseLdapPathContextSource contextSource;
|
private static DefaultSpringSecurityContextSource contextSource;
|
||||||
|
|
||||||
protected AbstractLdapIntegrationTests() {
|
protected AbstractLdapIntegrationTests() {
|
||||||
}
|
}
|
||||||
@ -48,7 +48,11 @@ public abstract class AbstractLdapIntegrationTests {
|
|||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void startServer() throws Exception {
|
public static void startServer() throws Exception {
|
||||||
contextSource = new DefaultSpringSecurityContextSource("ldap://127.0.0.1:53389/dc=springframework,dc=org");
|
contextSource = new DefaultSpringSecurityContextSource("ldap://127.0.0.1:53389/dc=springframework,dc=org");
|
||||||
((DefaultSpringSecurityContextSource)contextSource).afterPropertiesSet();
|
// OpenLDAP option
|
||||||
|
// contextSource = new DefaultSpringSecurityContextSource("ldap://127.0.0.1:22389/dc=springsource,dc=com");
|
||||||
|
// contextSource.setUserDn("cn=admin,dc=springsource,dc=com");
|
||||||
|
// contextSource.setPassword("password");
|
||||||
|
contextSource.afterPropertiesSet();
|
||||||
server = new ApacheDSContainer("dc=springframework,dc=org", "classpath:test-server.ldif");
|
server = new ApacheDSContainer("dc=springframework,dc=org", "classpath:test-server.ldif");
|
||||||
server.afterPropertiesSet();
|
server.afterPropertiesSet();
|
||||||
}
|
}
|
||||||
@ -98,7 +102,7 @@ public abstract class AbstractLdapIntegrationTests {
|
|||||||
try {
|
try {
|
||||||
enumeration = ctx.listBindings(name);
|
enumeration = ctx.listBindings(name);
|
||||||
while (enumeration.hasMore()) {
|
while (enumeration.hasMore()) {
|
||||||
Binding element = (Binding) enumeration.next();
|
Binding element = enumeration.next();
|
||||||
DistinguishedName childName = new DistinguishedName(element.getName());
|
DistinguishedName childName = new DistinguishedName(element.getName());
|
||||||
childName.prepend((DistinguishedName) name);
|
childName.prepend((DistinguishedName) name);
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ package org.springframework.security.ldap.authentication;
|
|||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.*;
|
||||||
import org.springframework.ldap.core.DirContextOperations;
|
import org.springframework.ldap.core.DirContextOperations;
|
||||||
import org.springframework.security.authentication.BadCredentialsException;
|
import org.springframework.security.authentication.BadCredentialsException;
|
||||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
@ -80,8 +80,34 @@ public class BindAuthenticatorTests extends AbstractLdapIntegrationTests {
|
|||||||
authenticator.setUserSearch(new FilterBasedLdapUserSearch("ou=people", "(cn={0})", getContextSource()));
|
authenticator.setUserSearch(new FilterBasedLdapUserSearch("ou=people", "(cn={0})", getContextSource()));
|
||||||
authenticator.authenticate(new UsernamePasswordAuthenticationToken("mouse, jerry", "jerryspassword"));
|
authenticator.authenticate(new UsernamePasswordAuthenticationToken("mouse, jerry", "jerryspassword"));
|
||||||
authenticator.authenticate(new UsernamePasswordAuthenticationToken("slash/guy", "slashguyspassword"));
|
authenticator.authenticate(new UsernamePasswordAuthenticationToken("slash/guy", "slashguyspassword"));
|
||||||
|
// SEC-1661
|
||||||
|
authenticator.setUserSearch(new FilterBasedLdapUserSearch("ou=\\\"quoted people\\\"", "(cn={0})", getContextSource()));
|
||||||
|
authenticator.authenticate(new UsernamePasswordAuthenticationToken("quoteguy", "quoteguyspassword"));
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
@Test
|
||||||
|
public void messingWithEscapedChars() throws Exception {
|
||||||
|
Hashtable<String,String> env = new Hashtable<String,String>();
|
||||||
|
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
|
||||||
|
env.put(Context.PROVIDER_URL, "ldap://127.0.0.1:22389/dc=springsource,dc=com");
|
||||||
|
env.put(Context.SECURITY_AUTHENTICATION, "simple");
|
||||||
|
env.put(Context.SECURITY_PRINCIPAL, "cn=admin,dc=springsource,dc=com");
|
||||||
|
env.put(Context.SECURITY_CREDENTIALS, "password");
|
||||||
|
|
||||||
|
InitialDirContext idc = new InitialDirContext(env);
|
||||||
|
SearchControls searchControls = new SearchControls();
|
||||||
|
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
|
||||||
|
DistinguishedName baseDn = new DistinguishedName("ou=\\\"quoted people\\\"");
|
||||||
|
NamingEnumeration<SearchResult> matches = idc.search(baseDn, "(cn=*)", new Object[] {"quoteguy"}, searchControls);
|
||||||
|
|
||||||
|
while(matches.hasMore()) {
|
||||||
|
SearchResult match = matches.next();
|
||||||
|
DistinguishedName dn = new DistinguishedName(match.getName());
|
||||||
|
System.out.println("**** Match: " + match.getName() + " ***** " + dn);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testAuthenticationWithWrongPasswordFails() {
|
public void testAuthenticationWithWrongPasswordFails() {
|
||||||
authenticator.setUserDnPatterns(new String[] {"uid={0},ou=people"});
|
authenticator.setUserDnPatterns(new String[] {"uid={0},ou=people"});
|
||||||
|
@ -13,6 +13,11 @@ objectclass: top
|
|||||||
objectclass: organizationalUnit
|
objectclass: organizationalUnit
|
||||||
ou: people
|
ou: people
|
||||||
|
|
||||||
|
dn: ou=\"quoted people\",dc=springframework,dc=org
|
||||||
|
objectclass: top
|
||||||
|
objectclass: organizationalUnit
|
||||||
|
ou: "quoted people"
|
||||||
|
|
||||||
dn: ou=otherpeople,dc=springframework,dc=org
|
dn: ou=otherpeople,dc=springframework,dc=org
|
||||||
objectclass: top
|
objectclass: top
|
||||||
objectclass: organizationalUnit
|
objectclass: organizationalUnit
|
||||||
@ -68,6 +73,17 @@ sn: Slash
|
|||||||
uid: slashguy
|
uid: slashguy
|
||||||
userPassword: slashguyspassword
|
userPassword: slashguyspassword
|
||||||
|
|
||||||
|
dn: cn=quoteguy,ou=\"quoted people\",dc=springframework,dc=org
|
||||||
|
objectclass: top
|
||||||
|
objectclass: person
|
||||||
|
objectclass: organizationalPerson
|
||||||
|
objectclass: inetOrgPerson
|
||||||
|
cn: quoteguy
|
||||||
|
sn: Quote
|
||||||
|
uid: quoteguy
|
||||||
|
userPassword: quoteguyspassword
|
||||||
|
|
||||||
|
|
||||||
dn: cn=developers,ou=groups,dc=springframework,dc=org
|
dn: cn=developers,ou=groups,dc=springframework,dc=org
|
||||||
objectclass: top
|
objectclass: top
|
||||||
objectclass: groupOfNames
|
objectclass: groupOfNames
|
||||||
|
Loading…
x
Reference in New Issue
Block a user