/*
* Copyright 2002-2016 the original author or authors.
*
* 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 static org.assertj.core.api.Assertions.*;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import javax.naming.directory.DirContext;
import org.junit.Test;
import org.springframework.ldap.AuthenticationException;
import org.springframework.ldap.core.support.AbstractContextSource;
/**
* @author Luke Taylor
*/
public class DefaultSpringSecurityContextSourceTests extends AbstractLdapIntegrationTests {
@Test
public void instantiationSucceedsWithExpectedProperties() {
DefaultSpringSecurityContextSource ctxSrc = new DefaultSpringSecurityContextSource(
"ldap://blah:789/dc=springframework,dc=org");
assertThat(ctxSrc.isAnonymousReadOnly()).isFalse();
assertThat(ctxSrc.isPooled()).isTrue();
}
@Test
public void supportsSpacesInUrl() {
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();
assertThat(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();
assertThat(ctxSrc.getAuthenticatedEnvForTest("user", "password")).doesNotContainKey(
AbstractContextSource.SUN_LDAP_POOLING_FLAG);
}
// SEC-1145. Confirms that there is no issue here with pooling.
@Test(expected = AuthenticationException.class)
public void cantBindWithWrongPasswordImmediatelyAfterSuccessfulBind()
throws Exception {
DirContext ctx = null;
try {
ctx = getContextSource().getContext(
"uid=Bob,ou=people,dc=springframework,dc=org", "bobspassword");
}
catch (Exception e) {
}
assertThat(ctx).isNotNull();
// com.sun.jndi.ldap.LdapPoolManager.showStats(System.out);
ctx.close();
// com.sun.jndi.ldap.LdapPoolManager.showStats(System.out);
// Now get it gain, with wrong password. Should fail.
ctx = getContextSource().getContext(
"uid=Bob,ou=people,dc=springframework,dc=org", "wrongpassword");
ctx.close();
}
@Test
public void serverUrlWithSpacesIsSupported() throws Exception {
DefaultSpringSecurityContextSource contextSource = new DefaultSpringSecurityContextSource(
"ldap://127.0.0.1:" + ApacheDSServerIntegrationTests.getServerPort()
+ "/ou=space%20cadets,dc=springframework,dc=org");
contextSource.afterPropertiesSet();
contextSource.getContext(
"uid=space cadet,ou=space cadets,dc=springframework,dc=org",
"spacecadetspassword");
}
@Test(expected = IllegalArgumentException.class)
public void instantiationFailsWithEmptyServerList() throws Exception {
List<String> serverUrls = new ArrayList<String>();
DefaultSpringSecurityContextSource ctxSrc = new DefaultSpringSecurityContextSource(
serverUrls, "dc=springframework,dc=org");
ctxSrc.afterPropertiesSet();
}
@Test
public void instantiationSuceedsWithProperServerList() throws Exception {
List<String> serverUrls = new ArrayList<String>();
serverUrls.add("ldap://foo:789");
serverUrls.add("ldap://bar:389");
serverUrls.add("ldaps://blah:636");
DefaultSpringSecurityContextSource ctxSrc = new DefaultSpringSecurityContextSource(
serverUrls, "dc=springframework,dc=org");
assertThat(ctxSrc.isAnonymousReadOnly()).isFalse();
assertThat(ctxSrc.isPooled()).isTrue();
}
// SEC-2308
@Test
public void instantiationSuceedsWithEmtpyBaseDn() throws Exception {
String baseDn = "";
List<String> serverUrls = new ArrayList<String>();
serverUrls.add("ldap://foo:789");
serverUrls.add("ldap://bar:389");
serverUrls.add("ldaps://blah:636");
DefaultSpringSecurityContextSource ctxSrc = new DefaultSpringSecurityContextSource(
serverUrls, baseDn);
assertThat(ctxSrc.isAnonymousReadOnly()).isFalse();
assertThat(ctxSrc.isPooled()).isTrue();
}
@Test(expected = IllegalArgumentException.class)
public void instantiationFailsWithIncorrectServerUrl() throws Exception {
List<String> serverUrls = new ArrayList<String>();
// a simple trailing slash should be ok
serverUrls.add("ldaps://blah:636/");
// this url should be rejected because the root DN goes into a separate parameter
serverUrls.add("ldap://bar:389/dc=foobar,dc=org");
DefaultSpringSecurityContextSource ctxSrc = new DefaultSpringSecurityContextSource(
serverUrls, "dc=springframework,dc=org");
}
static class EnvExposingDefaultSpringSecurityContextSource extends
DefaultSpringSecurityContextSource {
public EnvExposingDefaultSpringSecurityContextSource(String providerUrl) {
super(providerUrl);
}
@SuppressWarnings("unchecked")
Hashtable getAuthenticatedEnvForTest(String userDn, String password) {
return getAuthenticatedEnv(userDn, password);
}
}
}