2
0
Эх сурвалжийг харах

Migrate LDAP integration tests groovy->java

This commit also removes BaseSpringSpec

Issue: gh-4939
Vincent Ricard 5 жил өмнө
parent
commit
f0856c83a9
13 өөрчлөгдсөн 625 нэмэгдсэн , 943 устгасан
  1. 0 220
      config/src/integration-test/groovy/org/springframework/security/config/annotation/authentication/ldap/LdapAuthenticationProviderBuilderSecurityBuilderTests.groovy
  2. 0 90
      config/src/integration-test/groovy/org/springframework/security/config/annotation/authentication/ldap/LdapAuthenticationProviderConfigurerTests.groovy
  3. 0 80
      config/src/integration-test/groovy/org/springframework/security/config/annotation/authentication/ldap/NamespaceLdapAuthenticationProviderTests.groovy
  4. 0 164
      config/src/integration-test/groovy/org/springframework/security/config/ldap/LdapProviderBeanDefinitionParserTests.groovy
  5. 250 0
      config/src/integration-test/java/org/springframework/security/config/annotation/authentication/ldap/LdapAuthenticationProviderBuilderSecurityBuilderTests.java
  6. 101 0
      config/src/integration-test/java/org/springframework/security/config/annotation/authentication/ldap/LdapAuthenticationProviderConfigurerTests.java
  7. 95 0
      config/src/integration-test/java/org/springframework/security/config/annotation/authentication/ldap/NamespaceLdapAuthenticationProviderTests.java
  8. 2 2
      config/src/integration-test/java/org/springframework/security/config/annotation/authentication/ldap/NamespaceLdapAuthenticationProviderTestsConfigs.java
  9. 177 0
      config/src/integration-test/java/org/springframework/security/config/ldap/LdapProviderBeanDefinitionParserTests.java
  10. 0 106
      config/src/test/groovy/org/springframework/security/config/AbstractXmlConfigTests.groovy
  11. 0 25
      config/src/test/groovy/org/springframework/security/config/annotation/AnyObjectPostProcessor.java
  12. 0 174
      config/src/test/groovy/org/springframework/security/config/annotation/BaseSpringSpec.groovy
  13. 0 82
      config/src/test/groovy/org/springframework/security/config/http/AbstractHttpConfigTests.groovy

+ 0 - 220
config/src/integration-test/groovy/org/springframework/security/config/annotation/authentication/ldap/LdapAuthenticationProviderBuilderSecurityBuilderTests.groovy

@@ -1,220 +0,0 @@
-/*
- * Copyright 2002-2013 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
- *
- *      https://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.config.annotation.authentication.ldap
-
-import org.springframework.beans.factory.config.AutowireCapableBeanFactory
-import org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-import org.springframework.context.annotation.Bean
-import org.springframework.context.annotation.Configuration
-import org.springframework.context.annotation.Import
-import org.springframework.ldap.core.ContextSource;
-import org.springframework.ldap.core.support.BaseLdapPathContextSource;
-import org.springframework.security.authentication.AuthenticationManager
-import org.springframework.security.authentication.AuthenticationProvider
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
-import org.springframework.security.config.annotation.BaseSpringSpec
-import org.springframework.security.config.annotation.SecurityBuilder;
-import org.springframework.security.config.annotation.authentication.AuthenticationManagerBuilder
-import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder
-import org.springframework.security.config.annotation.authentication.configuration.EnableGlobalAuthentication
-import org.springframework.security.config.annotation.configuration.AutowireBeanFactoryObjectPostProcessor
-import org.springframework.security.config.annotation.configuration.AutowireBeanFactoryObjectPostProcessorTests
-import org.springframework.security.config.annotation.configuration.ObjectPostProcessorConfiguration
-import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
-import org.springframework.security.crypto.password.PasswordEncoder
-import org.springframework.security.ldap.DefaultSpringSecurityContextSource;
-import org.springframework.security.ldap.authentication.LdapAuthenticationProvider;
-import org.springframework.security.ldap.server.ApacheDSContainer;
-import org.springframework.test.util.ReflectionTestUtils;
-
-/**
- *
- * @author Rob Winch
- *
- */
-class LdapAuthenticationProviderBuilderSecurityBuilderTests extends BaseSpringSpec {
-	def "default configuration"() {
-		when:
-		loadConfig(DefaultLdapConfig)
-		LdapAuthenticationProvider provider = ldapProvider()
-		then:
-		provider.authoritiesPopulator.groupRoleAttribute == "cn"
-		provider.authoritiesPopulator.groupSearchBase == ""
-		provider.authoritiesPopulator.groupSearchFilter == "(uniqueMember={0})"
-		ReflectionTestUtils.getField(provider,"authoritiesMapper").prefix == "ROLE_"
-
-	}
-
-	@Configuration
-	static class DefaultLdapConfig extends BaseLdapProviderConfig {
-		protected void configure(AuthenticationManagerBuilder auth) throws Exception {
-			auth
-				.ldapAuthentication()
-					.contextSource(contextSource())
-					.userDnPatterns("uid={0},ou=people")
-		}
-	}
-
-	def "group roles custom"() {
-		when:
-		loadConfig(GroupRolesConfig)
-		LdapAuthenticationProvider provider = ldapProvider()
-		then:
-		provider.authoritiesPopulator.groupRoleAttribute == "group"
-	}
-
-	@Configuration
-	static class GroupRolesConfig extends BaseLdapProviderConfig {
-		protected void configure(AuthenticationManagerBuilder auth) throws Exception {
-			auth
-				.ldapAuthentication()
-					.contextSource(contextSource())
-					.userDnPatterns("uid={0},ou=people")
-					.groupRoleAttribute("group")
-		}
-	}
-
-	def "group search custom"() {
-		when:
-		loadConfig(GroupSearchConfig)
-		LdapAuthenticationProvider provider = ldapProvider()
-		then:
-		provider.authoritiesPopulator.groupSearchFilter == "ou=groupName"
-	}
-
-	@Configuration
-	static class GroupSearchConfig extends BaseLdapProviderConfig {
-		protected void configure(AuthenticationManagerBuilder auth) throws Exception {
-			auth
-				.ldapAuthentication()
-					.contextSource(contextSource())
-					.userDnPatterns("uid={0},ou=people")
-					.groupSearchFilter("ou=groupName");
-		}
-	}
-
-	def "role prefix custom"() {
-		when:
-		loadConfig(RolePrefixConfig)
-		LdapAuthenticationProvider provider = ldapProvider()
-		then:
-		ReflectionTestUtils.getField(provider,"authoritiesMapper").prefix == "role_"
-	}
-
-	@Configuration
-	static class RolePrefixConfig extends BaseLdapProviderConfig {
-		protected void configure(AuthenticationManagerBuilder auth) throws Exception {
-			auth
-				.ldapAuthentication()
-					.contextSource(contextSource())
-					.userDnPatterns("uid={0},ou=people")
-					.rolePrefix("role_")
-		}
-	}
-
-	def "bind authentication"() {
-		when:
-		loadConfig(BindAuthenticationConfig)
-		AuthenticationManager auth = context.getBean(AuthenticationManager)
-		then:
-		auth
-		auth.authenticate(new UsernamePasswordAuthenticationToken("bob","bobspassword")).authorities.collect { it.authority }.sort() == ["ROLE_DEVELOPERS"]
-	}
-
-	@Configuration
-	static class BindAuthenticationConfig extends BaseLdapServerConfig {
-		protected void configure(AuthenticationManagerBuilder auth) throws Exception {
-			auth
-				.ldapAuthentication()
-					.contextSource(contextSource())
-					.groupSearchBase("ou=groups")
-					.groupSearchFilter("(member={0})")
-					.userDnPatterns("uid={0},ou=people");
-		}
-	}
-
-	def "SEC-2472: Can use crypto PasswordEncoder"() {
-		setup:
-		loadConfig(PasswordEncoderConfig)
-		when:
-		AuthenticationManager auth = context.getBean(AuthenticationManager)
-		then:
-		auth.authenticate(new UsernamePasswordAuthenticationToken("bcrypt","password")).authorities.collect { it.authority }.sort() == ["ROLE_DEVELOPERS"]
-	}
-
-	@Configuration
-	static class PasswordEncoderConfig extends BaseLdapServerConfig {
-		protected void configure(AuthenticationManagerBuilder auth) throws Exception {
-			auth
-				.ldapAuthentication()
-					.contextSource(contextSource())
-					.passwordEncoder(new BCryptPasswordEncoder())
-					.groupSearchBase("ou=groups")
-					.groupSearchFilter("(member={0})")
-					.userDnPatterns("uid={0},ou=people");
-		}
-	}
-
-	def ldapProvider() {
-		context.getBean(AuthenticationManager).providers[0]
-	}
-
-	@Configuration
-	static abstract class BaseLdapServerConfig extends BaseLdapProviderConfig {
-		@Bean
-		public ApacheDSContainer ldapServer() throws Exception {
-			ApacheDSContainer apacheDSContainer = new ApacheDSContainer("dc=springframework,dc=org", "classpath:/test-server.ldif");
-			apacheDSContainer.setPort(getPort());
-			return apacheDSContainer;
-		}
-	}
-
-	@Configuration
-	@EnableGlobalAuthentication
-	@Import(ObjectPostProcessorConfiguration)
-	static abstract class BaseLdapProviderConfig {
-
-		@Bean
-		public BaseLdapPathContextSource contextSource() throws Exception {
-			DefaultSpringSecurityContextSource contextSource = new DefaultSpringSecurityContextSource(
-					"ldap://127.0.0.1:"+ getPort() + "/dc=springframework,dc=org")
-			contextSource.userDn = "uid=admin,ou=system"
-			contextSource.password = "secret"
-			contextSource.afterPropertiesSet()
-			return contextSource;
-		}
-
-		@Bean
-		public AuthenticationManager authenticationManager(AuthenticationManagerBuilder auth) {
-			configure(auth)
-			auth.build()
-		}
-
-		abstract protected void configure(AuthenticationManagerBuilder auth) throws Exception
-	}
-
-	static Integer port;
-
-	static int getPort() {
-		if(port == null) {
-			ServerSocket socket = new ServerSocket(0)
-			port = socket.localPort
-			socket.close()
-		}
-		port
-	}
-}

+ 0 - 90
config/src/integration-test/groovy/org/springframework/security/config/annotation/authentication/ldap/LdapAuthenticationProviderConfigurerTests.groovy

@@ -1,90 +0,0 @@
-/*
- * 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
- *
- *      https://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.config.annotation.authentication.ldap
-
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
-import org.springframework.security.config.annotation.BaseSpringSpec
-import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder
-import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
-import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
-import org.springframework.security.core.authority.SimpleGrantedAuthority
-
-/**
- *
- * @author Rob Winch
- * @author Eddú Meléndez
- *
- */
-class LdapAuthenticationProviderConfigurerTests extends BaseSpringSpec {
-
-	def "authentication-manager support multiple default ldap contexts (ports dynamically allocated)"() {
-		when:
-			loadConfig(MultiLdapAuthenticationProvidersConfig)
-		then:
-			authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("bob","bobspassword"))
-	}
-
-	def "authentication-manager support multiple ldap context with default role prefix" () {
-		when:
-		loadConfig(MultiLdapAuthenticationProvidersConfig)
-		then:
-		def authenticate = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("bob", "bobspassword"))
-		authenticate.authorities.contains(new SimpleGrantedAuthority("ROLE_DEVELOPERS"))
-	}
-
-	def "authentication-manager support multiple ldap context with custom role prefix"() {
-		when:
-		loadConfig(MultiLdapWithCustomRolePrefixAuthenticationProvidersConfig)
-		then:
-		def authenticate = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("bob", "bobspassword"))
-		authenticate.authorities.contains(new SimpleGrantedAuthority("ROL_DEVELOPERS"))
-	}
-
-	@EnableWebSecurity
-	static class MultiLdapAuthenticationProvidersConfig extends WebSecurityConfigurerAdapter {
-		protected void configure(AuthenticationManagerBuilder auth) throws Exception {
-			auth
-				.ldapAuthentication()
-					.groupSearchBase("ou=groups")
-					.groupSearchFilter("(member={0})")
-					.userDnPatterns("uid={0},ou=people")
-					.and()
-				.ldapAuthentication()
-					.groupSearchBase("ou=groups")
-					.groupSearchFilter("(member={0})")
-					.userDnPatterns("uid={0},ou=people")
-		}
-	}
-
-	@EnableWebSecurity
-	static class MultiLdapWithCustomRolePrefixAuthenticationProvidersConfig extends
-			WebSecurityConfigurerAdapter {
-		protected void configure(AuthenticationManagerBuilder auth) throws Exception {
-			auth
-				.ldapAuthentication()
-					.groupSearchBase("ou=groups")
-					.groupSearchFilter("(member={0})")
-					.userDnPatterns("uid={0},ou=people")
-					.rolePrefix("ROL_")
-					.and()
-				.ldapAuthentication()
-					.groupSearchBase("ou=groups")
-					.groupSearchFilter("(member={0})")
-					.userDnPatterns("uid={0},ou=people")
-					.rolePrefix("RUOLO_")
-		}
-	}
-}

+ 0 - 80
config/src/integration-test/groovy/org/springframework/security/config/annotation/authentication/ldap/NamespaceLdapAuthenticationProviderTests.groovy

@@ -1,80 +0,0 @@
-/*
- * Copyright 2002-2013 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
- *
- *      https://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.config.annotation.authentication.ldap
-
-import static org.springframework.security.config.annotation.authentication.ldap.NamespaceLdapAuthenticationProviderTestsConfigs.*
-
-import org.springframework.ldap.core.support.BaseLdapPathContextSource
-import org.springframework.security.authentication.AuthenticationManager
-import org.springframework.security.authentication.AuthenticationProvider
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
-import org.springframework.security.config.annotation.BaseSpringSpec
-import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
-import org.springframework.security.config.annotation.authentication.ldap.NamespaceLdapAuthenticationProviderTestsConfigs.LdapAuthenticationProviderConfig;
-import org.springframework.security.ldap.authentication.LdapAuthenticationProvider;
-import org.springframework.security.ldap.authentication.PasswordComparisonAuthenticator;
-import org.springframework.security.ldap.userdetails.LdapAuthoritiesPopulator;
-import org.springframework.security.ldap.userdetails.PersonContextMapper;
-import org.springframework.test.util.ReflectionTestUtils;
-
-/**
- *
- * @author Rob Winch
- *
- */
-class NamespaceLdapAuthenticationProviderTests extends BaseSpringSpec {
-	def "ldap-authentication-provider"() {
-		when:
-			loadConfig(LdapAuthenticationProviderConfig)
-		then:
-			authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("bob","bobspassword"))
-	}
-
-	def "ldap-authentication-provider custom"() {
-		when:
-			loadConfig(CustomLdapAuthenticationProviderConfig)
-			LdapAuthenticationProvider provider = findAuthenticationProvider(LdapAuthenticationProvider)
-		then:
-			provider.authoritiesPopulator.groupRoleAttribute == "cn"
-			provider.authoritiesPopulator.groupSearchBase == "ou=groups"
-			provider.authoritiesPopulator.groupSearchFilter == "(member={0})"
-			ReflectionTestUtils.getField(provider,"authoritiesMapper").prefix == "PREFIX_"
-			provider.userDetailsContextMapper instanceof PersonContextMapper
-			provider.authenticator.getUserDns("user") == ["uid=user,ou=people"]
-			provider.authenticator.userSearch.searchBase == "ou=users"
-			provider.authenticator.userSearch.searchFilter == "(uid={0})"
-	}
-
-	def "SEC-2490: ldap-authentication-provider custom LdapAuthoritiesPopulator"() {
-		setup:
-			LdapAuthoritiesPopulator LAP = Mock()
-			CustomAuthoritiesPopulatorConfig.LAP = LAP
-		when:
-			loadConfig(CustomAuthoritiesPopulatorConfig)
-			LdapAuthenticationProvider provider = findAuthenticationProvider(LdapAuthenticationProvider)
-		then:
-			provider.authoritiesPopulator == LAP
-	}
-
-	def "ldap-authentication-provider password compare"() {
-		when:
-			loadConfig(PasswordCompareLdapConfig)
-			LdapAuthenticationProvider provider = findAuthenticationProvider(LdapAuthenticationProvider)
-		then:
-			provider.authenticator instanceof PasswordComparisonAuthenticator
-			authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("bob","bobspassword"))
-	}
-}

+ 0 - 164
config/src/integration-test/groovy/org/springframework/security/config/ldap/LdapProviderBeanDefinitionParserTests.groovy

@@ -1,164 +0,0 @@
-package org.springframework.security.config.ldap
-
-import org.springframework.security.crypto.password.NoOpPasswordEncoder
-
-import static org.mockito.Mockito.*
-
-import java.text.MessageFormat
-
-import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer
-import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
-import org.springframework.security.crypto.password.PasswordEncoder
-import org.springframework.security.config.AbstractXmlConfigTests
-import org.springframework.security.config.BeanIds
-import org.springframework.security.util.FieldUtils
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
-import org.springframework.context.ApplicationContextException
-import org.springframework.security.core.AuthenticationException
-import org.springframework.security.ldap.userdetails.InetOrgPersonContextMapper
-
-/**
- * @author Luke Taylor
- */
-class LdapProviderBeanDefinitionParserTests extends AbstractXmlConfigTests {
-
-	// SEC-1182
-	def multipleProvidersAreSupported() {
-		xml.'ldap-server'(url: 'ldap://blah:389/dc=blah')
-		xml.'authentication-manager'() {
-			'ldap-authentication-provider'('group-search-filter': 'member={0}')
-			'ldap-authentication-provider'('group-search-filter': 'uniqueMember={0}')
-		}
-
-		createAppContext('')
-
-		def providers = appContext.getBean(BeanIds.AUTHENTICATION_MANAGER).providers
-
-		expect:
-
-		providers.size() == 2
-		providers[0].authoritiesPopulator.groupSearchFilter == "member={0}"
-		providers[1].authoritiesPopulator.groupSearchFilter == "uniqueMember={0}"
-	}
-
-
-	def simpleProviderAuthenticatesCorrectly() {
-		xml.'ldap-server'(ldif:'test-server.ldif')
-		xml.'authentication-manager'{
-			'ldap-authentication-provider'('group-search-filter':'member={0}')
-		}
-
-		createAppContext('')
-
-		def am = appContext.getBean(BeanIds.AUTHENTICATION_MANAGER)
-
-		when:
-		def auth = am.authenticate(new UsernamePasswordAuthenticationToken("ben", "benspassword"))
-		def ben =  auth.principal;
-
-		then:
-		ben.authorities.size() == 3
-	}
-
-	def missingServerEltCausesConfigException() {
-		xml.'authentication-manager'{
-			'ldap-authentication-provider'()
-		}
-
-		when:
-		createAppContext('')
-
-		then:
-		thrown(ApplicationContextException)
-	}
-
-	def supportsPasswordComparisonAuthentication() {
-		xml.'ldap-server'(ldif:'test-server.ldif')
-		xml.'authentication-manager'{
-			'ldap-authentication-provider'('user-dn-pattern': 'uid={0},ou=people')
-			'password-compare'
-		}
-		createAppContext('')
-		def am = appContext.getBean(BeanIds.AUTHENTICATION_MANAGER)
-
-		when:
-		def auth = am.authenticate(new UsernamePasswordAuthenticationToken("ben", "benspassword"))
-
-		then:
-		auth != null
-		notThrown(AuthenticationException)
-	}
-
-	def supportsPasswordComparisonAuthenticationWithPasswordEncoder() {
-		xml.'ldap-server'(ldif:'test-server.ldif')
-		xml.'authentication-manager'{
-			'ldap-authentication-provider'('user-dn-pattern': 'uid={0},ou=people') {
-				'password-compare'('password-attribute': 'uid') {
-					'password-encoder'(ref: 'passwordEncoder')
-				}
-			}
-		}
-		xml.'b:bean'(id: 'passwordEncoder', 'class' : NoOpPasswordEncoder.name, 'factory-method': 'getInstance')
-
-		createAppContext('')
-		def am = appContext.getBean(BeanIds.AUTHENTICATION_MANAGER)
-
-		when:
-		def auth = am.authenticate(new UsernamePasswordAuthenticationToken("ben", "ben"))
-
-		then:
-		auth != null
-		notThrown(AuthenticationException)
-	}
-
-	def 'SEC-2472: Supports Crypto PasswordEncoder'() {
-		setup:
-		xml.'ldap-server'(ldif:'test-server.ldif')
-		xml.'authentication-manager'{
-			'ldap-authentication-provider'('user-dn-pattern': 'uid={0},ou=people') {
-				'password-compare'() {
-					'password-encoder'(ref: 'pe')
-				}
-			}
-		}
-		xml.'b:bean'(id:'pe','class':BCryptPasswordEncoder.class.name)
-
-		createAppContext('')
-		def am = appContext.getBean(BeanIds.AUTHENTICATION_MANAGER)
-
-		when:
-		def auth = am.authenticate(new UsernamePasswordAuthenticationToken("bcrypt", 'password'))
-
-		then:
-		auth != null
-	}
-
-	def inetOrgContextMapperIsSupported()  {
-		xml.'ldap-server'(url: 'ldap://127.0.0.1:343/dc=springframework,dc=org')
-		xml.'authentication-manager'{
-			'ldap-authentication-provider'('user-details-class' :'inetOrgPerson')
-		}
-		createAppContext('')
-
-		expect:
-		appContext.getBean(BeanIds.AUTHENTICATION_MANAGER).providers[0].userDetailsContextMapper instanceof InetOrgPersonContextMapper
-	}
-
-	def ldapAuthenticationProviderWorksWithPlaceholders() {
-		System.setProperty('udp','people')
-		System.setProperty('gsf','member')
-
-		xml.'ldap-server'()
-		xml.'authentication-manager'{
-			'ldap-authentication-provider'('user-dn-pattern':'uid={0},ou=${udp}','group-search-filter':'${gsf}={0}')
-		}
-		bean(PropertyPlaceholderConfigurer.class.name, PropertyPlaceholderConfigurer.class)
-
-		createAppContext('')
-		def provider = this.appContext.getBean(BeanIds.AUTHENTICATION_MANAGER).providers[0]
-
-		expect:
-		[new MessageFormat("uid={0},ou=people")] == FieldUtils.getFieldValue(provider,"authenticator.userDnFormat")
-		"member={0}" == FieldUtils.getFieldValue(provider, "authoritiesPopulator.groupSearchFilter")
-	}
-}

+ 250 - 0
config/src/integration-test/java/org/springframework/security/config/annotation/authentication/ldap/LdapAuthenticationProviderBuilderSecurityBuilderTests.java

@@ -0,0 +1,250 @@
+/*
+ * Copyright 2002-2019 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
+ *
+ *      https://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.config.annotation.authentication.ldap;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Import;
+import org.springframework.ldap.core.support.BaseLdapPathContextSource;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.authentication.configuration.EnableGlobalAuthentication;
+import org.springframework.security.config.annotation.configuration.ObjectPostProcessorConfiguration;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.config.test.SpringTestRule;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.security.ldap.DefaultSpringSecurityContextSource;
+import org.springframework.security.ldap.authentication.LdapAuthenticationProvider;
+import org.springframework.security.ldap.server.ApacheDSContainer;
+import org.springframework.security.ldap.userdetails.LdapAuthoritiesPopulator;
+import org.springframework.test.util.ReflectionTestUtils;
+import org.springframework.test.web.servlet.MockMvc;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.util.List;
+
+import static java.util.Collections.singleton;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.formLogin;
+import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.authenticated;
+
+public class LdapAuthenticationProviderBuilderSecurityBuilderTests {
+	@Rule
+	public final SpringTestRule spring = new SpringTestRule();
+
+	@Autowired
+	private MockMvc mockMvc;
+
+	@Autowired
+	private AuthenticationManager authenticationManager;
+
+	@Test
+	public void defaultConfiguration() {
+		this.spring.register(DefaultLdapConfig.class).autowire();
+		LdapAuthenticationProvider provider = ldapProvider();
+
+		LdapAuthoritiesPopulator authoritiesPopulator = getAuthoritiesPopulator(provider);
+		assertThat(authoritiesPopulator).hasFieldOrPropertyWithValue("groupRoleAttribute", "cn");
+		assertThat(authoritiesPopulator).hasFieldOrPropertyWithValue("groupSearchBase", "");
+		assertThat(authoritiesPopulator).hasFieldOrPropertyWithValue("groupSearchFilter", "(uniqueMember={0})");
+		assertThat(ReflectionTestUtils.getField(getAuthoritiesMapper(provider), "prefix")).isEqualTo("ROLE_");
+	}
+
+	@EnableWebSecurity
+	static class DefaultLdapConfig extends BaseLdapProviderConfig {
+		// @formatter:off
+		protected void configure(AuthenticationManagerBuilder auth) throws Exception {
+			auth
+				.ldapAuthentication()
+					.contextSource(contextSource())
+					.userDnPatterns("uid={0},ou=people");
+		}
+		// @formatter:on
+	}
+
+	@Test
+	public void groupRolesCustom() {
+		this.spring.register(GroupRolesConfig.class).autowire();
+		LdapAuthenticationProvider provider = ldapProvider();
+
+		assertThat(ReflectionTestUtils.getField(getAuthoritiesPopulator(provider), "groupRoleAttribute")).isEqualTo("group");
+	}
+
+	@EnableWebSecurity
+	static class GroupRolesConfig extends BaseLdapProviderConfig {
+		// @formatter:off
+		protected void configure(AuthenticationManagerBuilder auth) throws Exception {
+			auth
+				.ldapAuthentication()
+					.contextSource(contextSource())
+					.userDnPatterns("uid={0},ou=people")
+					.groupRoleAttribute("group");
+		}
+		// @formatter:on
+	}
+
+	@Test
+	public void groupSearchCustom() {
+		this.spring.register(GroupSearchConfig.class).autowire();
+		LdapAuthenticationProvider provider = ldapProvider();
+
+		assertThat(ReflectionTestUtils.getField(getAuthoritiesPopulator(provider), "groupSearchFilter")).isEqualTo("ou=groupName");
+	}
+
+	@EnableWebSecurity
+	static class GroupSearchConfig extends BaseLdapProviderConfig {
+		// @formatter:off
+		protected void configure(AuthenticationManagerBuilder auth) throws Exception {
+			auth
+				.ldapAuthentication()
+					.contextSource(contextSource())
+					.userDnPatterns("uid={0},ou=people")
+					.groupSearchFilter("ou=groupName");
+		}
+		// @formatter:on
+	}
+
+	@Test
+	public void rolePrefixCustom() {
+		this.spring.register(RolePrefixConfig.class).autowire();
+		LdapAuthenticationProvider provider = ldapProvider();
+
+		assertThat(ReflectionTestUtils.getField(getAuthoritiesMapper(provider), "prefix")).isEqualTo("role_");
+	}
+
+	@EnableWebSecurity
+	static class RolePrefixConfig extends BaseLdapProviderConfig {
+		// @formatter:off
+		protected void configure(AuthenticationManagerBuilder auth) throws Exception {
+			auth
+				.ldapAuthentication()
+					.contextSource(contextSource())
+					.userDnPatterns("uid={0},ou=people")
+					.rolePrefix("role_");
+		}
+		// @formatter:on
+	}
+
+	@Test
+	public void bindAuthentication() throws Exception {
+		this.spring.register(BindAuthenticationConfig.class).autowire();
+
+		this.mockMvc.perform(formLogin().user("bob").password("bobspassword"))
+				.andExpect(authenticated().withUsername("bob").withAuthorities(singleton(new SimpleGrantedAuthority("ROLE_DEVELOPERS"))));
+	}
+
+	@EnableWebSecurity
+	static class BindAuthenticationConfig extends BaseLdapServerConfig {
+		// @formatter:off
+		protected void configure(AuthenticationManagerBuilder auth) throws Exception {
+			auth
+				.ldapAuthentication()
+					.contextSource(contextSource())
+					.groupSearchBase("ou=groups")
+					.groupSearchFilter("(member={0})")
+					.userDnPatterns("uid={0},ou=people");
+		}
+		// @formatter:on
+	}
+
+	// SEC-2472
+	@Test
+	public void canUseCryptoPasswordEncoder() throws Exception {
+		this.spring.register(PasswordEncoderConfig.class).autowire();
+
+		this.mockMvc.perform(formLogin().user("bcrypt").password("password"))
+				.andExpect(authenticated().withUsername("bcrypt").withAuthorities(singleton(new SimpleGrantedAuthority("ROLE_DEVELOPERS"))));
+	}
+
+	@EnableWebSecurity
+	static class PasswordEncoderConfig extends BaseLdapServerConfig {
+		// @formatter:off
+		protected void configure(AuthenticationManagerBuilder auth) throws Exception {
+			auth
+				.ldapAuthentication()
+					.contextSource(contextSource())
+					.passwordEncoder(new BCryptPasswordEncoder())
+					.groupSearchBase("ou=groups")
+					.groupSearchFilter("(member={0})")
+					.userDnPatterns("uid={0},ou=people");
+		}
+		// @formatter:on
+	}
+
+	private LdapAuthenticationProvider ldapProvider() {
+		return ((List<LdapAuthenticationProvider>) ReflectionTestUtils.getField(authenticationManager, "providers")).get(0);
+	}
+
+	private LdapAuthoritiesPopulator getAuthoritiesPopulator(LdapAuthenticationProvider provider) {
+		return (LdapAuthoritiesPopulator) ReflectionTestUtils.getField(provider, "authoritiesPopulator");
+	}
+
+	private GrantedAuthoritiesMapper getAuthoritiesMapper(LdapAuthenticationProvider provider) {
+		return (GrantedAuthoritiesMapper) ReflectionTestUtils.getField(provider, "authoritiesMapper");
+	}
+
+	@EnableWebSecurity
+	static abstract class BaseLdapServerConfig extends BaseLdapProviderConfig {
+		@Bean
+		public ApacheDSContainer ldapServer() throws Exception {
+			ApacheDSContainer apacheDSContainer = new ApacheDSContainer("dc=springframework,dc=org", "classpath:/test-server.ldif");
+			apacheDSContainer.setPort(getPort());
+			return apacheDSContainer;
+		}
+	}
+
+	@EnableWebSecurity
+	@EnableGlobalAuthentication
+	@Import(ObjectPostProcessorConfiguration.class)
+	static abstract class BaseLdapProviderConfig extends WebSecurityConfigurerAdapter {
+
+		@Bean
+		public BaseLdapPathContextSource contextSource() throws Exception {
+			DefaultSpringSecurityContextSource contextSource = new DefaultSpringSecurityContextSource(
+					"ldap://127.0.0.1:" + getPort() + "/dc=springframework,dc=org");
+			contextSource.setUserDn("uid=admin,ou=system");
+			contextSource.setPassword("secret");
+			contextSource.afterPropertiesSet();
+			return contextSource;
+		}
+
+		@Bean
+		public AuthenticationManager authenticationManager(AuthenticationManagerBuilder auth) throws Exception {
+			configure(auth);
+			return auth.build();
+		}
+
+		abstract protected void configure(AuthenticationManagerBuilder auth) throws Exception;
+	}
+
+	static Integer port;
+
+	static int getPort() throws IOException {
+		if (port == null) {
+			ServerSocket socket = new ServerSocket(0);
+			port = socket.getLocalPort();
+			socket.close();
+		}
+		return port;
+	}
+}

+ 101 - 0
config/src/integration-test/java/org/springframework/security/config/annotation/authentication/ldap/LdapAuthenticationProviderConfigurerTests.java

@@ -0,0 +1,101 @@
+/*
+ * Copyright 2002-2019 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
+ *
+ *      https://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.config.annotation.authentication.ldap;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.config.test.SpringTestRule;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.test.web.servlet.MockMvc;
+
+import static java.util.Collections.singleton;
+import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.formLogin;
+import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.authenticated;
+
+public class LdapAuthenticationProviderConfigurerTests {
+	@Rule
+	public final SpringTestRule spring = new SpringTestRule();
+
+	@Autowired
+	private MockMvc mockMvc;
+
+	@Test
+	public void authenticationManagerSupportMultipleDefaultLdapContextsWithPortsDynamicallyAllocated() throws Exception {
+		this.spring.register(MultiLdapAuthenticationProvidersConfig.class).autowire();
+
+		this.mockMvc.perform(formLogin().user("bob").password("bobspassword"))
+				.andExpect(authenticated().withUsername("bob"));
+	}
+
+	@Test
+	public void authenticationManagerSupportMultipleLdapContextWithDefaultRolePrefix() throws Exception {
+		this.spring.register(MultiLdapAuthenticationProvidersConfig.class).autowire();
+
+		this.mockMvc.perform(formLogin().user("bob").password("bobspassword"))
+				.andExpect(authenticated().withUsername("bob").withAuthorities(singleton(new SimpleGrantedAuthority("ROLE_DEVELOPERS"))));
+	}
+
+	@Test
+	public void authenticationManagerSupportMultipleLdapContextWithCustomRolePrefix() throws Exception {
+		this.spring.register(MultiLdapWithCustomRolePrefixAuthenticationProvidersConfig.class).autowire();
+
+		this.mockMvc.perform(formLogin().user("bob").password("bobspassword"))
+				.andExpect(authenticated().withUsername("bob").withAuthorities(singleton(new SimpleGrantedAuthority("ROL_DEVELOPERS"))));
+	}
+
+	@EnableWebSecurity
+	static class MultiLdapAuthenticationProvidersConfig extends WebSecurityConfigurerAdapter {
+		// @formatter:off
+		protected void configure(AuthenticationManagerBuilder auth) throws Exception {
+			auth
+				.ldapAuthentication()
+					.groupSearchBase("ou=groups")
+					.groupSearchFilter("(member={0})")
+					.userDnPatterns("uid={0},ou=people")
+					.and()
+				.ldapAuthentication()
+					.groupSearchBase("ou=groups")
+					.groupSearchFilter("(member={0})")
+					.userDnPatterns("uid={0},ou=people");
+		}
+		// @formatter:on
+	}
+
+	@EnableWebSecurity
+	static class MultiLdapWithCustomRolePrefixAuthenticationProvidersConfig extends WebSecurityConfigurerAdapter {
+		// @formatter:off
+		protected void configure(AuthenticationManagerBuilder auth) throws Exception {
+			auth
+				.ldapAuthentication()
+					.groupSearchBase("ou=groups")
+					.groupSearchFilter("(member={0})")
+					.userDnPatterns("uid={0},ou=people")
+					.rolePrefix("ROL_")
+					.and()
+				.ldapAuthentication()
+					.groupSearchBase("ou=groups")
+					.groupSearchFilter("(member={0})")
+					.userDnPatterns("uid={0},ou=people")
+					.rolePrefix("RUOLO_");
+		}
+		// @formatter:on
+	}
+}

+ 95 - 0
config/src/integration-test/java/org/springframework/security/config/annotation/authentication/ldap/NamespaceLdapAuthenticationProviderTests.java

@@ -0,0 +1,95 @@
+/*
+ * Copyright 2002-2019 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
+ *
+ *      https://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.config.annotation.authentication.ldap;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.ldap.core.DirContextOperations;
+import org.springframework.ldap.core.support.LdapContextSource;
+import org.springframework.security.config.annotation.authentication.ldap.NamespaceLdapAuthenticationProviderTestsConfigs.CustomAuthoritiesPopulatorConfig;
+import org.springframework.security.config.annotation.authentication.ldap.NamespaceLdapAuthenticationProviderTestsConfigs.CustomLdapAuthenticationProviderConfig;
+import org.springframework.security.config.annotation.authentication.ldap.NamespaceLdapAuthenticationProviderTestsConfigs.LdapAuthenticationProviderConfig;
+import org.springframework.security.config.annotation.authentication.ldap.NamespaceLdapAuthenticationProviderTestsConfigs.PasswordCompareLdapConfig;
+import org.springframework.security.config.test.SpringTestRule;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.AuthorityUtils;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.ldap.DefaultSpringSecurityContextSource;
+import org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator;
+import org.springframework.security.web.FilterChainProxy;
+import org.springframework.test.web.servlet.MockMvc;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.formLogin;
+import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.authenticated;
+
+public class NamespaceLdapAuthenticationProviderTests {
+
+	@Rule
+	public final SpringTestRule spring = new SpringTestRule();
+
+	@Autowired
+	private MockMvc mockMvc;
+
+	@Autowired
+	private FilterChainProxy filterChainProxy;
+
+	@Test
+	public void ldapAuthenticationProvider() throws Exception {
+		this.spring.register(LdapAuthenticationProviderConfig.class).autowire();
+
+		this.mockMvc.perform(formLogin().user("bob").password("bobspassword"))
+				.andExpect(authenticated().withUsername("bob"));
+	}
+
+	@Test
+	public void ldapAuthenticationProviderCustom() throws Exception {
+		this.spring.register(CustomLdapAuthenticationProviderConfig.class).autowire();
+
+		this.mockMvc.perform(formLogin().user("bob").password("bobspassword"))
+				.andExpect(authenticated().withAuthorities(Collections.singleton(new SimpleGrantedAuthority("PREFIX_DEVELOPERS"))));
+	}
+
+	// SEC-2490
+	@Test
+	public void ldapAuthenticationProviderCustomLdapAuthoritiesPopulator() throws Exception {
+		LdapContextSource contextSource = new DefaultSpringSecurityContextSource("ldap://blah.example.com:789/dc=springframework,dc=org");
+		CustomAuthoritiesPopulatorConfig.LAP = new DefaultLdapAuthoritiesPopulator(contextSource, null) {
+			@Override
+			protected Set<GrantedAuthority> getAdditionalRoles(DirContextOperations user, String username) {
+				return new HashSet<>(AuthorityUtils.createAuthorityList("ROLE_EXTRA"));
+			}
+		};
+
+		this.spring.register(CustomAuthoritiesPopulatorConfig.class).autowire();
+
+		this.mockMvc.perform(formLogin().user("bob").password("bobspassword"))
+				.andExpect(authenticated().withAuthorities(Collections.singleton(new SimpleGrantedAuthority("ROLE_EXTRA"))));
+	}
+
+	@Test
+	public void ldapAuthenticationProviderPasswordCompare() throws Exception {
+		this.spring.register(PasswordCompareLdapConfig.class).autowire();
+
+		this.mockMvc.perform(formLogin().user("bcrypt").password("password"))
+				.andExpect(authenticated().withUsername("bcrypt"));
+	}
+}

+ 2 - 2
config/src/integration-test/java/org/springframework/security/config/annotation/authentication/ldap/NamespaceLdapAuthenticationProviderTestsConfigs.java

@@ -18,7 +18,7 @@ package org.springframework.security.config.annotation.authentication.ldap;
 import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
-import org.springframework.security.crypto.password.NoOpPasswordEncoder;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
 import org.springframework.security.ldap.userdetails.LdapAuthoritiesPopulator;
 import org.springframework.security.ldap.userdetails.PersonContextMapper;
 
@@ -90,7 +90,7 @@ public class NamespaceLdapAuthenticationProviderTestsConfigs {
 					.groupSearchBase("ou=groups")
 					.userSearchFilter("(uid={0})")
 					.passwordCompare()
-						.passwordEncoder(NoOpPasswordEncoder.getInstance()) // ldap-authentication-provider/password-compare/password-encoder@ref
+						.passwordEncoder(new BCryptPasswordEncoder()) // ldap-authentication-provider/password-compare/password-encoder@ref
 						.passwordAttribute("userPassword"); // ldap-authentication-provider/password-compare@password-attribute
 		}
 		// @formatter:on

+ 177 - 0
config/src/integration-test/java/org/springframework/security/config/ldap/LdapProviderBeanDefinitionParserTests.java

@@ -0,0 +1,177 @@
+/*
+ * Copyright 2002-2019 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
+ *
+ *      https://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.config.ldap;
+
+import org.junit.After;
+import org.junit.Test;
+import org.springframework.context.ApplicationContextException;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.authentication.AuthenticationProvider;
+import org.springframework.security.authentication.ProviderManager;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.config.BeanIds;
+import org.springframework.security.config.util.InMemoryXmlApplicationContext;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.ldap.userdetails.InetOrgPersonContextMapper;
+
+import java.text.MessageFormat;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class LdapProviderBeanDefinitionParserTests {
+	InMemoryXmlApplicationContext appCtx;
+
+	@After
+	public void closeAppContext() {
+		if (appCtx != null) {
+			appCtx.close();
+			appCtx = null;
+		}
+	}
+
+	@Test
+	public void simpleProviderAuthenticatesCorrectly() {
+		appCtx = new InMemoryXmlApplicationContext("<ldap-server ldif='classpath:test-server.ldif'/>"
+				+ "<authentication-manager>"
+				+ "  <ldap-authentication-provider group-search-filter='member={0}' />"
+				+ "</authentication-manager>"
+		);
+
+		AuthenticationManager authenticationManager = appCtx.getBean(BeanIds.AUTHENTICATION_MANAGER, AuthenticationManager.class);
+		Authentication auth = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("ben", "benspassword"));
+		UserDetails ben = (UserDetails) auth.getPrincipal();
+		assertThat(ben.getAuthorities()).hasSize(3);
+	}
+
+	@Test
+	public void multipleProvidersAreSupported() {
+		appCtx = new InMemoryXmlApplicationContext("<ldap-server ldif='classpath:test-server.ldif'/>"
+				+ "<authentication-manager>"
+				+ "  <ldap-authentication-provider group-search-filter='member={0}' />"
+				+ "  <ldap-authentication-provider group-search-filter='uniqueMember={0}' />"
+				+ "</authentication-manager>"
+		);
+
+		ProviderManager providerManager = appCtx.getBean(BeanIds.AUTHENTICATION_MANAGER, ProviderManager.class);
+		assertThat(providerManager.getProviders()).hasSize(2);
+		assertThat(providerManager.getProviders())
+				.extracting("authoritiesPopulator.groupSearchFilter")
+				.containsExactly("member={0}", "uniqueMember={0}");
+	}
+
+	@Test(expected = ApplicationContextException.class)
+	public void missingServerEltCausesConfigException() {
+		new InMemoryXmlApplicationContext("<authentication-manager>"
+				+ "  <ldap-authentication-provider />"
+				+ "</authentication-manager>"
+		);
+	}
+
+	@Test
+	public void supportsPasswordComparisonAuthentication() {
+		appCtx = new InMemoryXmlApplicationContext("<ldap-server ldif='classpath:test-server.ldif'/>"
+				+ "<authentication-manager>"
+				+ "  <ldap-authentication-provider user-dn-pattern='uid={0},ou=people'>"
+				+ "    <password-compare />"
+				+ "  </ldap-authentication-provider>"
+				+ "</authentication-manager>"
+		);
+
+		AuthenticationManager authenticationManager = appCtx.getBean(BeanIds.AUTHENTICATION_MANAGER, AuthenticationManager.class);
+		Authentication auth = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("ben", "benspassword"));
+
+		assertThat(auth).isNotNull();
+	}
+
+	@Test
+	public void supportsPasswordComparisonAuthenticationWithPasswordEncoder() {
+		appCtx = new InMemoryXmlApplicationContext("<ldap-server ldif='classpath:test-server.ldif'/>"
+				+ "<authentication-manager>"
+				+ "  <ldap-authentication-provider user-dn-pattern='uid={0},ou=people'>"
+				+ "    <password-compare password-attribute='uid'>"
+				+ "      <password-encoder ref='passwordEncoder' />"
+				+ "    </password-compare>"
+				+ "  </ldap-authentication-provider>"
+				+ "</authentication-manager>"
+				+ "<b:bean id='passwordEncoder' class='org.springframework.security.crypto.password.NoOpPasswordEncoder' factory-method='getInstance' />"
+		);
+
+		AuthenticationManager authenticationManager = appCtx.getBean(BeanIds.AUTHENTICATION_MANAGER, AuthenticationManager.class);
+		Authentication auth = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("ben", "ben"));
+
+		assertThat(auth).isNotNull();
+	}
+
+	// SEC-2472
+	@Test
+	public void supportsCryptoPasswordEncoder() {
+		appCtx = new InMemoryXmlApplicationContext("<ldap-server ldif='classpath:test-server.ldif'/>"
+				+ "<authentication-manager>"
+				+ "  <ldap-authentication-provider user-dn-pattern='uid={0},ou=people'>"
+				+ "    <password-compare>"
+				+ "      <password-encoder ref='pe' />"
+				+ "    </password-compare>"
+				+ "  </ldap-authentication-provider>"
+				+ "</authentication-manager>"
+				+ "<b:bean id='pe' class='org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder' />"
+		);
+
+		AuthenticationManager authenticationManager = appCtx.getBean(BeanIds.AUTHENTICATION_MANAGER, AuthenticationManager.class);
+		Authentication auth = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("bcrypt", "password"));
+
+		assertThat(auth).isNotNull();
+	}
+
+	@Test
+	public void inetOrgContextMapperIsSupported() {
+		appCtx = new InMemoryXmlApplicationContext("<ldap-server url='ldap://127.0.0.1:343/dc=springframework,dc=org'/>"
+				+ "<authentication-manager>"
+				+ "  <ldap-authentication-provider user-details-class='inetOrgPerson' />"
+				+ "</authentication-manager>"
+		);
+
+		ProviderManager providerManager = appCtx.getBean(BeanIds.AUTHENTICATION_MANAGER, ProviderManager.class);
+		assertThat(providerManager.getProviders()).hasSize(1);
+		assertThat(providerManager.getProviders())
+				.extracting("userDetailsContextMapper")
+				.allSatisfy(contextMapper -> assertThat(contextMapper).isInstanceOf(InetOrgPersonContextMapper.class));
+	}
+
+	@Test
+	public void ldapAuthenticationProviderWorksWithPlaceholders() {
+		System.setProperty("udp", "people");
+		System.setProperty("gsf", "member");
+		appCtx = new InMemoryXmlApplicationContext("<ldap-server />"
+				+ "<authentication-manager>"
+				+ "  <ldap-authentication-provider user-dn-pattern='uid={0},ou=${udp}' group-search-filter='${gsf}={0}' />"
+				+ "</authentication-manager>"
+				+ "<b:bean id='org.springframework.beans.factory.config.PropertyPlaceholderConfigurer' class='org.springframework.beans.factory.config.PropertyPlaceholderConfigurer' />"
+		);
+
+		ProviderManager providerManager = appCtx.getBean(BeanIds.AUTHENTICATION_MANAGER, ProviderManager.class);
+		assertThat(providerManager.getProviders()).hasSize(1);
+
+		AuthenticationProvider authenticationProvider = providerManager.getProviders().get(0);
+		assertThat(authenticationProvider)
+				.extracting("authenticator.userDnFormat")
+				.satisfies(messageFormats -> assertThat(messageFormats).isEqualTo(new MessageFormat[]{new MessageFormat("uid={0},ou=people")}));
+		assertThat(authenticationProvider)
+				.extracting("authoritiesPopulator.groupSearchFilter")
+				.satisfies(searchFilter -> assertThat(searchFilter).isEqualTo("member={0}"));
+	}
+}

+ 0 - 106
config/src/test/groovy/org/springframework/security/config/AbstractXmlConfigTests.groovy

@@ -1,106 +0,0 @@
-package org.springframework.security.config
-
-import groovy.xml.MarkupBuilder
-import org.mockito.Mockito
-import org.springframework.context.ApplicationListener
-import org.springframework.context.support.AbstractRefreshableApplicationContext
-import org.springframework.mock.web.MockServletContext
-import org.springframework.security.CollectingAppListener
-import org.springframework.security.config.util.InMemoryXmlApplicationContext
-import org.springframework.security.config.util.InMemoryXmlWebApplicationContext
-import org.springframework.security.core.context.SecurityContextHolder
-import spock.lang.Specification
-
-import javax.servlet.ServletContext
-
-import static org.springframework.security.config.ConfigTestUtils.AUTH_PROVIDER_XML
-/**
- *
- * @author Luke Taylor
- */
-abstract class AbstractXmlConfigTests extends Specification {
-	AbstractRefreshableApplicationContext appContext;
-	Writer writer;
-	MarkupBuilder xml;
-	ApplicationListener appListener;
-
-	def setup() {
-		writer = new StringWriter()
-		xml = new MarkupBuilder(writer)
-		appListener = new CollectingAppListener()
-	}
-
-	def cleanup() {
-		if (appContext != null) {
-			appContext.close();
-			appContext = null;
-		}
-		SecurityContextHolder.clearContext();
-	}
-
-	def mockBean(Class clazz, String id = clazz.simpleName) {
-		xml.'b:bean'(id: id, 'class': Mockito.class.name, 'factory-method':'mock') {
-			'b:constructor-arg'(value : clazz.name)
-			'b:constructor-arg'(value : id)
-		}
-	}
-
-	def bean(String name, Class clazz) {
-		xml.'b:bean'(id: name, 'class': clazz.name)
-	}
-
-	def bean(String name, String clazz) {
-		xml.'b:bean'(id: name, 'class': clazz)
-	}
-
-	def bean(String name, String clazz, List constructorArgs) {
-		xml.'b:bean'(id: name, 'class': clazz) {
-			constructorArgs.each { val ->
-				'b:constructor-arg'(value: val)
-			}
-		}
-	}
-
-	def bean(String name, String clazz, Map properties, Map refs) {
-		xml.'b:bean'(id: name, 'class': clazz) {
-			properties.each {key, val ->
-				'b:property'(name: key, value: val)
-			}
-			refs.each {key, val ->
-				'b:property'(name: key, ref: val)
-			}
-		}
-	}
-
-	def createAppContext() {
-		createAppContext(AUTH_PROVIDER_XML)
-	}
-
-	def createAppContext(String extraXml) {
-		appContext = new InMemoryXmlApplicationContext(writer.toString() + extraXml);
-		appContext.addApplicationListener(appListener);
-	}
-
-	def createWebAppContext() {
-		createWebAppContext(AUTH_PROVIDER_XML);
-	}
-
-	def createWebAppContext(ServletContext servletContext) {
-		createWebAppContext(AUTH_PROVIDER_XML, servletContext);
-	}
-
-	def createWebAppContext(String extraXml) {
-		createWebAppContext(extraXml, null);
-	}
-
-	def createWebAppContext(String extraXml, ServletContext servletContext) {
-		appContext = new InMemoryXmlWebApplicationContext(writer.toString() + extraXml);
-		appContext.addApplicationListener(appListener);
-		if (servletContext != null) {
-			appContext.setServletContext(servletContext);
-		} else {
-			appContext.setServletContext(new MockServletContext());
-		}
-		appContext.refresh();
-	}
-}

+ 0 - 25
config/src/test/groovy/org/springframework/security/config/annotation/AnyObjectPostProcessor.java

@@ -1,25 +0,0 @@
-/*
- * Copyright 2002-2013 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
- *
- *      https://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.config.annotation;
-
-/**
- * Exists for mocking purposes to ensure that the Type information is found.
- *
- * @author Rob Winch
- */
-public interface AnyObjectPostProcessor extends ObjectPostProcessor<Object> {
-
-}

+ 0 - 174
config/src/test/groovy/org/springframework/security/config/annotation/BaseSpringSpec.groovy

@@ -1,174 +0,0 @@
-/*
- * Copyright 2002-2013 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
- *
- *		https://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.config.annotation;
-
-import javax.servlet.Filter
-
-import spock.lang.AutoCleanup
-import spock.lang.Specification
-
-import org.springframework.beans.factory.NoSuchBeanDefinitionException
-import org.springframework.context.ConfigurableApplicationContext
-import org.springframework.context.annotation.AnnotationConfigApplicationContext
-import org.springframework.mock.web.MockFilterChain
-import org.springframework.mock.web.MockHttpServletRequest
-import org.springframework.mock.web.MockHttpServletResponse
-import org.springframework.mock.web.MockServletContext
-import org.springframework.security.authentication.AuthenticationManager
-import org.springframework.security.authentication.AuthenticationProvider
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
-import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder
-import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration
-import org.springframework.security.config.annotation.configuration.ObjectPostProcessorConfiguration
-import org.springframework.security.core.Authentication
-import org.springframework.security.core.authority.AuthorityUtils
-import org.springframework.security.core.context.SecurityContextHolder
-import org.springframework.security.core.context.SecurityContextImpl
-import org.springframework.security.web.FilterChainProxy
-import org.springframework.security.web.access.intercept.FilterSecurityInterceptor
-import org.springframework.security.web.context.HttpRequestResponseHolder
-import org.springframework.security.web.context.HttpSessionSecurityContextRepository
-import org.springframework.security.web.csrf.CsrfToken
-import org.springframework.security.web.csrf.DefaultCsrfToken
-import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository
-import org.springframework.web.context.support.AnnotationConfigWebApplicationContext
-
-/**
- *
- * @author Rob Winch
- */
-abstract class BaseSpringSpec extends Specification {
-	boolean allowCircularReferences = false
-	@AutoCleanup
-	ConfigurableApplicationContext context
-	@AutoCleanup
-	ConfigurableApplicationContext oppContext
-
-	MockHttpServletRequest request
-	MockHttpServletResponse response
-	MockFilterChain chain
-	CsrfToken csrfToken
-	AuthenticationManagerBuilder authenticationBldr
-
-	def setup() {
-		authenticationBldr = createAuthenticationManagerBuilder()
-		setupWeb(null)
-	}
-
-	def setupWeb(httpSession = null) {
-		request = new MockHttpServletRequest(method:"GET")
-		if(httpSession) {
-			request.session = httpSession
-		}
-		response = new MockHttpServletResponse()
-		chain = new MockFilterChain()
-		setupCsrf()
-	}
-
-	def setupCsrf(csrfTokenValue="BaseSpringSpec_CSRFTOKEN",req=request,resp=response) {
-		csrfToken = new DefaultCsrfToken("X-CSRF-TOKEN","_csrf",csrfTokenValue)
-		new HttpSessionCsrfTokenRepository().saveToken(csrfToken, req, resp)
-		req.setParameter(csrfToken.parameterName, csrfToken.token)
-	}
-
-	def cleanup() {
-		SecurityContextHolder.clearContext()
-	}
-
-	def loadConfig(Class<?>... configs) {
-		context = new AnnotationConfigWebApplicationContext()
-		context.setAllowCircularReferences(allowCircularReferences)
-		context.register(configs)
-		context.setServletContext(new MockServletContext())
-		context.refresh()
-		context
-	}
-
-	def findFilter(Class<?> filter, int index = 0) {
-		filterChain(index).filters.find { filter.isAssignableFrom(it.class)}
-	}
-
-	def filterChain(int index=0) {
-		filterChains()[index]
-	}
-
-	def filterChains() {
-		context.getBean(FilterChainProxy).filterChains
-	}
-
-	Filter getSpringSecurityFilterChain() {
-		context.getBean("springSecurityFilterChain",Filter.class)
-	}
-
-	def getResponseHeaders() {
-		def headers = [:]
-		response.headerNames.each { name ->
-			headers.put(name, response.getHeaderValues(name).join(','))
-		}
-		return headers
-	}
-
-	AuthenticationManager authenticationManager() {
-		context.getBean(AuthenticationManager)
-	}
-
-	AuthenticationManager getAuthenticationManager() {
-		try {
-			authenticationManager().delegateBuilder.getObject()
-		} catch(NoSuchBeanDefinitionException e) {
-		} catch(MissingPropertyException e) {}
-		findFilter(FilterSecurityInterceptor).authenticationManager
-	}
-
-	List<AuthenticationProvider> authenticationProviders() {
-		List<AuthenticationProvider> providers = new ArrayList<AuthenticationProvider>()
-		AuthenticationManager authenticationManager = getAuthenticationManager()
-		while(authenticationManager?.providers) {
-			providers.addAll(authenticationManager.providers)
-			authenticationManager = authenticationManager.parent
-		}
-		providers
-	}
-
-	AuthenticationProvider findAuthenticationProvider(Class<?> provider) {
-		authenticationProviders().find { provider.isAssignableFrom(it.class) }
-	}
-
-	def getCurrentAuthentication() {
-		new HttpSessionSecurityContextRepository().loadContext(new HttpRequestResponseHolder(request, response)).authentication
-	}
-
-	def login(String username="user", String role="ROLE_USER") {
-		login(new UsernamePasswordAuthenticationToken(username, null, AuthorityUtils.createAuthorityList(role)))
-	}
-
-	def login(Authentication auth) {
-		HttpSessionSecurityContextRepository repo = new HttpSessionSecurityContextRepository()
-		HttpRequestResponseHolder requestResponseHolder = new HttpRequestResponseHolder(request, response)
-		repo.loadContext(requestResponseHolder)
-		repo.saveContext(new SecurityContextImpl(authentication:auth), requestResponseHolder.request, requestResponseHolder.response)
-	}
-
-	def createAuthenticationManagerBuilder() {
-		oppContext = new AnnotationConfigApplicationContext(ObjectPostProcessorConfiguration, AuthenticationConfiguration)
-		AuthenticationManagerBuilder auth = new AuthenticationManagerBuilder(objectPostProcessor)
-		auth.inMemoryAuthentication().and()
-	}
-
-	def getObjectPostProcessor() {
-		oppContext.getBean(ObjectPostProcessor)
-	}
-}

+ 0 - 82
config/src/test/groovy/org/springframework/security/config/http/AbstractHttpConfigTests.groovy

@@ -1,82 +0,0 @@
-/*
- * Copyright 2002-2012 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
- *
- * https://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.config.http
-
-import javax.servlet.Filter
-import org.springframework.mock.web.MockFilterChain
-import org.springframework.mock.web.MockHttpServletRequest
-import org.springframework.mock.web.MockHttpServletResponse
-import org.springframework.security.config.AbstractXmlConfigTests
-import org.springframework.security.config.BeanIds
-import org.springframework.security.web.FilterInvocation
-
-import javax.servlet.http.HttpServletRequest
-
-/**
- *
- * @author Rob Winch
- *
- */
-abstract class AbstractHttpConfigTests extends AbstractXmlConfigTests {
-	final int AUTO_CONFIG_FILTERS = 15;
-
-	def httpAutoConfig(Closure c) {
-		xml.http(['auto-config': 'true', 'use-expressions':false], c)
-	}
-
-	def httpAutoConfig(String matcher, Closure c) {
-		xml.http(['auto-config': 'true', 'use-expressions':false, 'request-matcher': matcher], c)
-	}
-
-	def interceptUrl(String path, String authz) {
-		xml.'intercept-url'(pattern: path, access: authz)
-	}
-
-	def interceptUrl(String path, String httpMethod, String authz) {
-		xml.'intercept-url'(pattern: path, method: httpMethod, access: authz)
-	}
-
-	Filter getFilter(Class type) {
-		List filters = getFilters("/any");
-
-		for (f in filters) {
-			if (f.class.isAssignableFrom(type)) {
-				return f;
-			}
-		}
-
-		return null;
-	}
-
-	List getFilters(String url) {
-		springSecurityFilterChain.getFilters(url)
-	}
-
-	Filter getSpringSecurityFilterChain() {
-		appContext.getBean(BeanIds.FILTER_CHAIN_PROXY)
-	}
-
-	FilterInvocation createFilterinvocation(String path, String method) {
-		MockHttpServletRequest request = new MockHttpServletRequest("GET", "");
-		request.setMethod(method);
-		request.setRequestURI(null);
-		request.setServletPath(path);
-
-		return new FilterInvocation(request, new MockHttpServletResponse(), new MockFilterChain());
-	}
-
-	def basicLogin(HttpServletRequest request, String username="user",String password="password") {
-		def credentials = username + ":" + password
-		request.addHeader("Authorization", "Basic " + credentials.bytes.encodeBase64())
-	}
-}