瀏覽代碼

AuthenticationConfigurationTests -> java

Issue: gh-4939
Rob Winch 7 年之前
父節點
當前提交
e5d40c0599

+ 0 - 518
config/src/test/groovy/org/springframework/security/config/annotation/authentication/configuration/AuthenticationConfigurationTests.groovy

@@ -1,518 +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
- *
- *      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.config.annotation.authentication.configuration;
-
-import org.springframework.aop.framework.ProxyFactoryBean
-import org.springframework.beans.factory.annotation.Autowired
-import org.springframework.context.annotation.Bean
-import org.springframework.context.annotation.Configuration
-import org.springframework.context.annotation.Import
-import org.springframework.core.Ordered
-import org.springframework.core.annotation.Order
-import org.springframework.security.access.annotation.Secured
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.security.authentication.AuthenticationManager
-import org.springframework.security.authentication.AuthenticationProvider
-import org.springframework.security.authentication.TestingAuthenticationToken
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
-import org.springframework.security.authentication.dao.DaoAuthenticationProvider
-import org.springframework.security.config.annotation.BaseSpringSpec
-import org.springframework.security.config.annotation.ObjectPostProcessor
-import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder
-import org.springframework.security.config.annotation.configuration.ObjectPostProcessorConfiguration
-import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity
-import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
-import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
-import org.springframework.security.core.AuthenticationException
-import org.springframework.security.core.authority.AuthorityUtils
-import org.springframework.security.core.context.SecurityContextHolder
-import org.springframework.security.core.userdetails.PasswordEncodedUser
-import org.springframework.security.core.userdetails.User
-import org.springframework.security.core.userdetails.UserDetailsService
-import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
-import org.springframework.security.crypto.password.PasswordEncoder
-import org.springframework.security.provisioning.InMemoryUserDetailsManager
-
-class AuthenticationConfigurationTests extends BaseSpringSpec {
-
-	def "Ordering Autowired on EnableGlobalMethodSecurity"() {
-		setup:
-			SecurityContextHolder.getContext().setAuthentication(new TestingAuthenticationToken("user", "password","ROLE_USER"))
-		when:
-			loadConfig(GlobalMethodSecurityAutowiredConfigAndServicesConfig)
-		then:
-			context.getBean(Service).run()
-	}
-
-	@Configuration
-	@Import([GlobalMethodSecurityAutowiredConfig,ServicesConfig])
-	static class GlobalMethodSecurityAutowiredConfigAndServicesConfig {}
-
-	@EnableGlobalMethodSecurity(securedEnabled = true)
-	static class GlobalMethodSecurityAutowiredConfig {
-		@Autowired
-		public void configureGlobal(AuthenticationManagerBuilder auth) {
-			auth.inMemoryAuthentication().withUser(PasswordEncodedUser.user())
-		}
-	}
-
-	def "Ordering Autowired on EnableWebSecurity"() {
-		setup:
-			SecurityContextHolder.getContext().setAuthentication(new TestingAuthenticationToken("user", "password","ROLE_USER"))
-		when:
-			loadConfig(GlobalMethodSecurityConfigAndServicesConfig)
-		then:
-			context.getBean(Service).run()
-	}
-
-	@Configuration
-	@Import([GlobalMethodSecurityConfig,WebSecurityConfig,ServicesConfig])
-	static class GlobalMethodSecurityConfigAndServicesConfig {}
-
-	@EnableGlobalMethodSecurity(securedEnabled = true)
-	static class GlobalMethodSecurityConfig {}
-
-	@EnableWebSecurity
-	static class WebSecurityConfig extends WebSecurityConfigurerAdapter {
-		@Autowired
-		public void configureGlobal(AuthenticationManagerBuilder auth) {
-			auth.inMemoryAuthentication().withUser(PasswordEncodedUser.user())
-		}
-	}
-
-	//
-
-	def "Ordering Autowired on EnableWebMvcSecurity"() {
-		setup:
-			SecurityContextHolder.getContext().setAuthentication(new TestingAuthenticationToken("user", "password","ROLE_USER"))
-		when:
-			loadConfig(GlobalMethodSecurityMvcSecurityAndServicesConfig)
-		then:
-			context.getBean(Service).run()
-	}
-
-	@Configuration
-	@Import([GlobalMethodSecurityConfig,WebMvcSecurityConfig,ServicesConfig])
-	static class GlobalMethodSecurityMvcSecurityAndServicesConfig {}
-
-	@EnableWebSecurity
-	static class WebMvcSecurityConfig extends WebSecurityConfigurerAdapter {
-		@Autowired
-		public void configureGlobal(AuthenticationManagerBuilder auth) {
-			auth.inMemoryAuthentication().withUser(PasswordEncodedUser.user())
-		}
-	}
-
-	//
-
-	def "no authentication getAuthenticationManager falls back to null"() {
-		when:
-			loadConfig(AuthenticationConfiguration,ObjectPostProcessorConfiguration)
-		then:
-			context.getBean(AuthenticationConfiguration).authenticationManager == null
-	}
-
-	def "QuiesentGlobalAuthenticationConfiguererAdapter falls back to null"() {
-		when:
-			loadConfig(AuthenticationConfiguration,ObjectPostProcessorConfiguration,QuiesentGlobalAuthenticationConfiguererAdapter)
-		then:
-			context.getBean(AuthenticationConfiguration).authenticationManager == null
-	}
-
-	@Configuration
-	static class QuiesentGlobalAuthenticationConfiguererAdapter extends GlobalAuthenticationConfigurerAdapter {}
-
-	//
-
-	def "GlobalAuthenticationConfiguererAdapterImpl configures authentication successfully"() {
-		setup:
-			def token = new UsernamePasswordAuthenticationToken("user", "password")
-		when:
-			loadConfig(AuthenticationConfiguration,ObjectPostProcessorConfiguration,GlobalAuthenticationConfiguererAdapterImpl)
-		then:
-			context.getBean(AuthenticationConfiguration).authenticationManager.authenticate(token)?.name == "user"
-	}
-
-	@Configuration
-	static class GlobalAuthenticationConfiguererAdapterImpl extends GlobalAuthenticationConfigurerAdapter {
-		public void init(AuthenticationManagerBuilder auth) throws Exception {
-			auth.inMemoryAuthentication().withUser(PasswordEncodedUser.user())
-		}
-	}
-
-	//
-
-	def "AuthenticationManagerBean configures authentication successfully"() {
-		setup:
-			def token = new UsernamePasswordAuthenticationToken("user", "password")
-			def auth = new UsernamePasswordAuthenticationToken("user", "password", AuthorityUtils.createAuthorityList("ROLE_USER"))
-			AuthenticationManagerBeanConfig.AM = Mock(AuthenticationManager)
-			1 * AuthenticationManagerBeanConfig.AM.authenticate(token) >> auth
-		when:
-			loadConfig(AuthenticationConfiguration,ObjectPostProcessorConfiguration,AuthenticationManagerBeanConfig)
-		then:
-			context.getBean(AuthenticationConfiguration).authenticationManager.authenticate(token).name == auth.name
-	}
-
-	@Configuration
-	static class AuthenticationManagerBeanConfig {
-		static AuthenticationManager AM
-		@Bean
-		public AuthenticationManager authenticationManager() {
-			AM
-		}
-	}
-
-	//
-
-	@Configuration
-	static class ServicesConfig {
-		@Bean
-		public Service service() {
-			return new ServiceImpl()
-		}
-	}
-
-	static interface Service {
-		public void run();
-	}
-
-	static class ServiceImpl implements Service {
-		@Secured("ROLE_USER")
-		public void run() {}
-	}
-
-	//
-
-	def "GlobalAuthenticationConfigurerAdapter are ordered"() {
-		setup:
-			loadConfig(AuthenticationConfiguration,ObjectPostProcessorConfiguration)
-			AuthenticationConfiguration config = context.getBean(AuthenticationConfiguration)
-			config.setGlobalAuthenticationConfigurers([new LowestOrderGlobalAuthenticationConfigurerAdapter(), new HighestOrderGlobalAuthenticationConfigurerAdapter(), new DefaultOrderGlobalAuthenticationConfigurerAdapter()])
-		when:
-			config.getAuthenticationManager()
-		then:
-			DefaultOrderGlobalAuthenticationConfigurerAdapter.inits == [HighestOrderGlobalAuthenticationConfigurerAdapter,DefaultOrderGlobalAuthenticationConfigurerAdapter,LowestOrderGlobalAuthenticationConfigurerAdapter]
-			DefaultOrderGlobalAuthenticationConfigurerAdapter.configs == [HighestOrderGlobalAuthenticationConfigurerAdapter,DefaultOrderGlobalAuthenticationConfigurerAdapter,LowestOrderGlobalAuthenticationConfigurerAdapter]
-
-	}
-
-	static class DefaultOrderGlobalAuthenticationConfigurerAdapter extends GlobalAuthenticationConfigurerAdapter {
-		static List inits = []
-		static List configs = []
-
-		public void init(AuthenticationManagerBuilder auth) throws Exception {
-			inits.add(getClass())
-		}
-
-		public void configure(AuthenticationManagerBuilder auth) throws Exception {
-			configs.add(getClass())
-		}
-	}
-
-	@Order(Ordered.LOWEST_PRECEDENCE)
-	static class LowestOrderGlobalAuthenticationConfigurerAdapter extends DefaultOrderGlobalAuthenticationConfigurerAdapter {}
-
-	@Order(Ordered.HIGHEST_PRECEDENCE)
-	static class HighestOrderGlobalAuthenticationConfigurerAdapter extends DefaultOrderGlobalAuthenticationConfigurerAdapter {}
-
-	//
-
-	def "Spring Boot not triggered when already configured"() {
-		setup:
-			loadConfig(AuthenticationConfiguration,ObjectPostProcessorConfiguration)
-			AuthenticationConfiguration config = context.getBean(AuthenticationConfiguration)
-			config.setGlobalAuthenticationConfigurers([new ConfiguresInMemoryConfigurerAdapter(), new BootGlobalAuthenticationConfigurerAdapter()])
-			AuthenticationManager authenticationManager = config.authenticationManager
-		when:
-			authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("user","password"))
-		then:
-			noExceptionThrown()
-		when:
-			authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("boot","password"))
-		then:
-			thrown(AuthenticationException)
-	}
-
-
-	def "Spring Boot is triggered when not already configured"() {
-		setup:
-			loadConfig(AuthenticationConfiguration,ObjectPostProcessorConfiguration)
-			AuthenticationConfiguration config = context.getBean(AuthenticationConfiguration)
-			config.setGlobalAuthenticationConfigurers([new BootGlobalAuthenticationConfigurerAdapter()])
-			AuthenticationManager authenticationManager = config.authenticationManager
-		when:
-			authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("boot","password"))
-		then:
-			noExceptionThrown()
-	}
-
-	static class ConfiguresInMemoryConfigurerAdapter extends GlobalAuthenticationConfigurerAdapter {
-
-		public void init(AuthenticationManagerBuilder auth) throws Exception {
-			auth
-				.inMemoryAuthentication()
-					.withUser(PasswordEncodedUser.user())
-		}
-	}
-
-	@Order(Ordered.LOWEST_PRECEDENCE)
-	static class BootGlobalAuthenticationConfigurerAdapter extends DefaultOrderGlobalAuthenticationConfigurerAdapter {
-		public void init(AuthenticationManagerBuilder auth) throws Exception {
-			auth.apply(new DefaultBootGlobalAuthenticationConfigurerAdapter())
-		}
-	}
-
-	static class DefaultBootGlobalAuthenticationConfigurerAdapter extends DefaultOrderGlobalAuthenticationConfigurerAdapter {
-		@Override
-		public void configure(AuthenticationManagerBuilder auth) throws Exception {
-			if(auth.isConfigured()) {
-				return;
-			}
-
-			User user = User.withUserDetails(PasswordEncodedUser.user()).username("boot").build()
-
-			List<User> users = Arrays.asList(user);
-			InMemoryUserDetailsManager inMemory = new InMemoryUserDetailsManager(users);
-
-			DaoAuthenticationProvider provider = new DaoAuthenticationProvider()
-			provider.userDetailsService = inMemory
-
-			auth.authenticationProvider(provider)
-		}
-	}
-
-	def "SEC-2531: AuthenticationConfiguration#lazyBean should use BeanClassLoader on ProxyFactoryBean"() {
-		setup:
-			ObjectPostProcessor opp = Mock()
-			Sec2531Config. opp = opp
-			loadConfig(Sec2531Config)
-		when:
-			AuthenticationConfiguration config = context.getBean(AuthenticationConfiguration)
-			config.getAuthenticationManager()
-		then:
-			1 * opp.postProcess(_ as ProxyFactoryBean) >> { args ->
-				args[0]
-			}
-	}
-
-	@Configuration
-	@Import(AuthenticationConfiguration)
-	static class Sec2531Config {
-		static ObjectPostProcessor opp
-
-		@Bean
-		public ObjectPostProcessor objectPostProcessor() {
-			opp
-		}
-
-		@Bean
-		public AuthenticationManager manager() {
-			null
-		}
-	}
-
-	def "SEC-2822: Cannot Force Authentication already built"() {
-		setup:
-		loadConfig(Sec2822WebSecurity,Sec2822UseAuth,Sec2822Config)
-		when:
-		AuthenticationConfiguration config = context.getBean(AuthenticationConfiguration)
-		config.getAuthenticationManager()
-		then:
-		noExceptionThrown()
-	}
-
-	@Configuration
-	@Import(AuthenticationConfiguration)
-	static class Sec2822Config {}
-
-	@Configuration
-	@EnableWebSecurity
-	static class Sec2822WebSecurity extends WebSecurityConfigurerAdapter {
-		@Autowired
-		public void configureGlobal(AuthenticationManagerBuilder auth) {
-			auth.inMemoryAuthentication()
-		}
-	}
-
-	@Configuration
-	static class Sec2822UseAuth {
-		@Autowired
-		public void useAuthenticationManager(AuthenticationConfiguration auth) {
-			auth.authenticationManager
-		}
-
-		// Ensures that Sec2822UseAuth is initialized before Sec2822WebSecurity
-		// must have additional GlobalAuthenticationConfigurerAdapter to trigger SEC-2822
-		@Bean
-		public static GlobalAuthenticationConfigurerAdapter bootGlobalAuthenticationConfigurerAdapter() {
-			new BootGlobalAuthenticationConfigurerAdapter()
-		}
-
-		static class BootGlobalAuthenticationConfigurerAdapter extends GlobalAuthenticationConfigurerAdapter { }
-	}
-
-	def 'SEC-2868: Allow Configure UserDetailsService'() {
-		setup:
-		UserDetailsService uds = Mock()
-		UserDetailsServiceBeanConfig.UDS = uds
-		loadConfig(UserDetailsServiceBeanConfig)
-		AuthenticationManager am = context.getBean(AuthenticationConfiguration).getAuthenticationManager()
-		when:
-		am.authenticate(new UsernamePasswordAuthenticationToken("user", "password"))
-		then:
-		1 * uds.loadUserByUsername("user") >> PasswordEncodedUser.user()
-		when:
-		am.authenticate(new UsernamePasswordAuthenticationToken("user", "invalid"))
-		then:
-		1 * uds.loadUserByUsername("user") >>  PasswordEncodedUser.user()
-		thrown(AuthenticationException.class)
-	}
-
-	@Configuration
-	@Import([AuthenticationConfiguration, ObjectPostProcessorConfiguration])
-	static class UserDetailsServiceBeanConfig {
-		static UserDetailsService UDS
-
-		@Bean
-		UserDetailsService userDetailsService() {
-			UDS
-		}
-	}
-
-	def 'SEC-2868: Allow Configure UserDetailsService with PasswordEncoder'() {
-		setup:
-		UserDetailsService uds = Mock()
-		UserDetailsServiceBeanWithPasswordEncoderConfig.UDS = uds
-		loadConfig(UserDetailsServiceBeanWithPasswordEncoderConfig)
-		AuthenticationManager am = context.getBean(AuthenticationConfiguration).getAuthenticationManager()
-		when:
-		am.authenticate(new UsernamePasswordAuthenticationToken("user", "password"))
-		then:
-		1 * uds.loadUserByUsername("user") >> new User("user",'$2a$10$FBAKClV1zBIOOC9XMXf3AO8RoGXYVYsfvUdoLxGkd/BnXEn4tqT3u',AuthorityUtils.createAuthorityList("ROLE_USER"))
-		when:
-		am.authenticate(new UsernamePasswordAuthenticationToken("user", "invalid"))
-		then:
-		1 * uds.loadUserByUsername("user") >> new User("user",'$2a$10$FBAKClV1zBIOOC9XMXf3AO8RoGXYVYsfvUdoLxGkd/BnXEn4tqT3u',AuthorityUtils.createAuthorityList("ROLE_USER"))
-		thrown(AuthenticationException.class)
-	}
-
-	@Configuration
-	@Import([AuthenticationConfiguration, ObjectPostProcessorConfiguration])
-	static class UserDetailsServiceBeanWithPasswordEncoderConfig {
-		static UserDetailsService UDS
-
-		@Bean
-		UserDetailsService userDetailsService() {
-			UDS
-		}
-
-		@Bean
-		PasswordEncoder passwordEncoder() {
-			new BCryptPasswordEncoder()
-		}
-	}
-
-	def 'gh-3091: Allow Configure AuthenticationProvider'() {
-		setup:
-		AuthenticationProvider ap = Mock()
-		AuthenticationProviderBeanConfig.AP = ap
-		loadConfig(AuthenticationProviderBeanConfig)
-		AuthenticationManager am = context.getBean(AuthenticationConfiguration).getAuthenticationManager()
-		UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("user", "password");
-		User user = new User("user","password",AuthorityUtils.createAuthorityList("ROLE_USER"))
-		when:
-		am.authenticate(token)
-		then:
-		1 * ap.supports(_) >> true
-		1 * ap.authenticate(token) >> new UsernamePasswordAuthenticationToken(user, user.getPassword(), user.getAuthorities())
-	}
-
-	@Configuration
-	@Import([AuthenticationConfiguration, ObjectPostProcessorConfiguration])
-	static class AuthenticationProviderBeanConfig {
-		static AuthenticationProvider AP
-
-		@Bean
-		AuthenticationProvider authenticationProvider() {
-			AP
-		}
-	}
-
-	def 'AuthenticationProvider Bean Prioritized over UserDetailsService'() {
-		setup:
-		UserDetailsService uds = Mock()
-		AuthenticationProvider ap = Mock()
-		AuthenticationProviderBeanAndUserDetailsServiceConfig.AP = ap
-		AuthenticationProviderBeanAndUserDetailsServiceConfig.UDS = uds
-		loadConfig(AuthenticationProviderBeanAndUserDetailsServiceConfig)
-		AuthenticationManager am = context.getBean(AuthenticationConfiguration).getAuthenticationManager()
-		UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("user", "password");
-		User user = new User("user","password",AuthorityUtils.createAuthorityList("ROLE_USER"))
-		when:
-		am.authenticate(token)
-		then:
-		1 * ap.supports(_) >> true
-		1 * ap.authenticate(token) >> new UsernamePasswordAuthenticationToken(user, user.getPassword(), user.getAuthorities())
-		0 * uds._
-	}
-
-	@Configuration
-	@Import([AuthenticationConfiguration, ObjectPostProcessorConfiguration])
-	static class AuthenticationProviderBeanAndUserDetailsServiceConfig {
-		static AuthenticationProvider AP
-		static UserDetailsService UDS
-
-		@Bean
-		AuthenticationProvider authenticationProvider() {
-			AP
-		}
-
-		@Bean
-		UserDetailsService uds() {
-			UDS
-		}
-	}
-
-	def 'EnableGlobalMethodSecurity configuration uses PreAuthorize does not cause BeanCurrentlyInCreationException'() {
-		when:
-		loadConfig(UsesPreAuthorizeMethodSecurityConfig,AuthenticationManagerBeanConfig)
-		then:
-		noExceptionThrown()
-	}
-
-	@Configuration
-	@EnableGlobalMethodSecurity(prePostEnabled = true)
-	static class UsesPreAuthorizeMethodSecurityConfig {
-		@PreAuthorize("denyAll")
-		void run() {}
-	}
-
-
-	def 'EnableGlobalMethodSecurity uses method security service'() {
-		when:
-		loadConfig(ServicesConfig,UsesPreAuthorizeMethodSecurityConfig,AuthenticationManagerBeanConfig)
-		then:
-		noExceptionThrown()
-	}
-
-	@Configuration
-	@EnableGlobalMethodSecurity(securedEnabled = true)
-	static class UsesServiceMethodSecurityConfig {
-		@Autowired
-		Service service
-	}
-}

+ 478 - 0
config/src/test/java/org/springframework/security/config/annotation/authentication/configuration/AuthenticationConfigurationTests.java

@@ -0,0 +1,478 @@
+/*
+ * Copyright 2002-2018 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.config.annotation.authentication.configuration;
+
+import org.apache.http.auth.AUTH;
+import org.junit.After;
+import org.junit.Rule;
+import org.junit.Test;
+import org.springframework.aop.framework.ProxyFactoryBean;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+import org.springframework.core.Ordered;
+import org.springframework.core.annotation.Order;
+import org.springframework.security.access.annotation.Secured;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.authentication.AuthenticationProvider;
+import org.springframework.security.authentication.TestAuthentication;
+import org.springframework.security.authentication.TestingAuthenticationToken;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
+import org.springframework.security.config.annotation.ObjectPostProcessor;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.configuration.ObjectPostProcessorConfiguration;
+import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;
+import org.springframework.security.config.test.SpringTestRule;
+import org.springframework.security.config.users.AuthenticationTestConfiguration;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.core.authority.AuthorityUtils;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.PasswordEncodedUser;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.security.provisioning.InMemoryUserDetailsManager;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class AuthenticationConfigurationTests {
+
+	@Rule
+	public final SpringTestRule spring = new SpringTestRule();
+
+	@Autowired(required = false)
+	private Service service;
+
+	@After
+	public void cleanup() {
+		SecurityContextHolder.clearContext();
+	}
+
+	@Test
+	public void orderingAutowiredOnEnableGlobalMethodSecurity() {
+		this.spring.register(AuthenticationTestConfiguration.class, GlobalMethodSecurityAutowiredConfig.class, ServicesConfig.class).autowire();
+
+		SecurityContextHolder.getContext().setAuthentication(new TestingAuthenticationToken("user", "password", "ROLE_USER"));
+		this.service.run();
+	}
+
+	@EnableGlobalMethodSecurity(securedEnabled = true)
+	static class GlobalMethodSecurityAutowiredConfig {
+	}
+
+	@Test
+	public void orderingAutowiredOnEnableWebSecurity() {
+		this.spring.register(AuthenticationTestConfiguration.class, WebSecurityConfig.class, GlobalMethodSecurityAutowiredConfig.class, ServicesConfig.class).autowire();
+
+		SecurityContextHolder.getContext().setAuthentication(new TestingAuthenticationToken("user", "password", "ROLE_USER"));
+		this.service.run();
+	}
+
+	@EnableWebSecurity
+	static class WebSecurityConfig {}
+
+
+	@Test
+	public void orderingAutowiredOnEnableWebMvcSecurity() {
+		this.spring.register(AuthenticationTestConfiguration.class, WebMvcSecurityConfig.class, GlobalMethodSecurityAutowiredConfig.class, ServicesConfig.class).autowire();
+
+		SecurityContextHolder.getContext().setAuthentication(new TestingAuthenticationToken("user", "password", "ROLE_USER"));
+		this.service.run();
+	}
+
+	@EnableWebMvcSecurity
+	static class WebMvcSecurityConfig {}
+
+	@Test
+	public void getAuthenticationManagerWhenNoAuthenticationThenNull() throws Exception {
+		this.spring.register(AuthenticationConfiguration.class, ObjectPostProcessorConfiguration.class).autowire();
+
+		assertThat(this.spring.getContext().getBean(AuthenticationConfiguration.class).getAuthenticationManager()).isNull();
+	}
+
+
+	@Test
+	public void getAuthenticationManagerWhenNoOpGlobalAuthenticationConfigurerAdapterThenNull() throws Exception {
+		this.spring.register(AuthenticationConfiguration.class, ObjectPostProcessorConfiguration.class, NoOpGlobalAuthenticationConfigurerAdapter.class).autowire();
+
+		assertThat(this.spring.getContext().getBean(AuthenticationConfiguration.class).getAuthenticationManager()).isNull();
+	}
+
+	@Configuration
+	static class NoOpGlobalAuthenticationConfigurerAdapter extends GlobalAuthenticationConfigurerAdapter {}
+
+	@Test
+	public void getAuthenticationWhenGlobalAuthenticationConfigurerAdapterThenAuthenticates() throws Exception {
+		UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("user", "password");
+		this.spring.register(AuthenticationConfiguration.class, ObjectPostProcessorConfiguration.class, UserGlobalAuthenticationConfigurerAdapter.class).autowire();
+
+		AuthenticationManager authentication = this.spring.getContext().getBean(AuthenticationConfiguration.class).getAuthenticationManager();
+
+		assertThat(authentication.authenticate(token).getName()).isEqualTo(token.getName());
+	}
+
+	@Configuration
+	static class UserGlobalAuthenticationConfigurerAdapter extends GlobalAuthenticationConfigurerAdapter {
+		public void init(AuthenticationManagerBuilder auth) throws Exception {
+			auth.inMemoryAuthentication()
+				.withUser(PasswordEncodedUser.user());
+		}
+	}
+
+	@Test
+	public void getAuthenticationWhenAuthenticationManagerBeanThenAuthenticates() throws Exception {
+		UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("user", "password");
+		this.spring.register(AuthenticationConfiguration.class, ObjectPostProcessorConfiguration.class, AuthenticationManagerBeanConfig.class).autowire();
+
+		AuthenticationManager authentication = this.spring.getContext().getBean(AuthenticationConfiguration.class).getAuthenticationManager();
+		when(authentication.authenticate(token)).thenReturn(TestAuthentication.authenticatedUser());
+
+		assertThat(authentication.authenticate(token).getName()).isEqualTo(token.getName());
+	}
+
+	@Configuration
+	static class AuthenticationManagerBeanConfig {
+		AuthenticationManager authenticationManager = mock(AuthenticationManager.class);
+
+		@Bean
+		public AuthenticationManager authenticationManager() {
+			return authenticationManager;
+		}
+	}
+		//
+		//	//
+		//
+		@Configuration
+		static class ServicesConfig {
+			@Bean
+			public Service service() {
+				return new ServiceImpl();
+			}
+		}
+
+		interface Service {
+			void run();
+		}
+
+		static class ServiceImpl implements Service {
+			@Secured("ROLE_USER")
+			public void run() {}
+		}
+
+		@Test
+		public void getAuthenticationWhenMultipleThenOrdered() throws Exception {
+			this.spring.register(AuthenticationConfiguration.class, ObjectPostProcessorConfiguration.class, AuthenticationManagerBeanConfig.class).autowire();
+			AuthenticationConfiguration config = this.spring.getContext().getBean(AuthenticationConfiguration.class);
+			config.setGlobalAuthenticationConfigurers(Arrays.asList(new LowestOrderGlobalAuthenticationConfigurerAdapter(), new HighestOrderGlobalAuthenticationConfigurerAdapter(), new DefaultOrderGlobalAuthenticationConfigurerAdapter()));
+		}
+
+		static class DefaultOrderGlobalAuthenticationConfigurerAdapter extends GlobalAuthenticationConfigurerAdapter {
+			static List<Class<?>> inits = new ArrayList<>();
+			static List<Class<?>> configs = new ArrayList<>();
+
+			public void init(AuthenticationManagerBuilder auth) throws Exception {
+				inits.add(getClass());
+			}
+
+			public void configure(AuthenticationManagerBuilder auth) throws Exception {
+				configs.add(getClass());
+			}
+		}
+
+		@Order(Ordered.LOWEST_PRECEDENCE)
+		static class LowestOrderGlobalAuthenticationConfigurerAdapter extends DefaultOrderGlobalAuthenticationConfigurerAdapter {}
+
+		@Order(Ordered.HIGHEST_PRECEDENCE)
+		static class HighestOrderGlobalAuthenticationConfigurerAdapter extends DefaultOrderGlobalAuthenticationConfigurerAdapter {}
+
+	@Test
+	public void getAuthenticationWhenConfiguredThenBootNotTrigger() throws Exception {
+		this.spring.register(AuthenticationConfiguration.class, ObjectPostProcessorConfiguration.class).autowire();
+		AuthenticationConfiguration config = this.spring.getContext().getBean(AuthenticationConfiguration.class);
+		config.setGlobalAuthenticationConfigurers(Arrays.asList(new ConfiguresInMemoryConfigurerAdapter(), new BootGlobalAuthenticationConfigurerAdapter()));
+		AuthenticationManager authenticationManager = config.getAuthenticationManager();
+
+		authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("user", "password"));
+
+		assertThatThrownBy(() -> authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("boot", "password")))
+			.isInstanceOf(AuthenticationException.class);
+
+	}
+
+	@Test
+	public void getAuthenticationWhenNotConfiguredThenBootTrigger() throws Exception {
+		this.spring.register(AuthenticationConfiguration.class, ObjectPostProcessorConfiguration.class).autowire();
+		AuthenticationConfiguration config = this.spring.getContext().getBean(AuthenticationConfiguration.class);
+		config.setGlobalAuthenticationConfigurers(Arrays.asList(new BootGlobalAuthenticationConfigurerAdapter()));
+		AuthenticationManager authenticationManager = config.getAuthenticationManager();
+
+		authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("boot", "password"));
+	}
+
+	static class ConfiguresInMemoryConfigurerAdapter extends GlobalAuthenticationConfigurerAdapter {
+
+		public void init(AuthenticationManagerBuilder auth) throws Exception {
+			auth
+				.inMemoryAuthentication()
+					.withUser(PasswordEncodedUser.user());
+		}
+	}
+
+	@Order(Ordered.LOWEST_PRECEDENCE)
+	static class BootGlobalAuthenticationConfigurerAdapter extends DefaultOrderGlobalAuthenticationConfigurerAdapter {
+		public void init(AuthenticationManagerBuilder auth) throws Exception {
+			auth.apply(new DefaultBootGlobalAuthenticationConfigurerAdapter());
+		}
+	}
+
+	static class DefaultBootGlobalAuthenticationConfigurerAdapter extends DefaultOrderGlobalAuthenticationConfigurerAdapter {
+		@Override
+		public void configure(AuthenticationManagerBuilder auth) throws Exception {
+			if (auth.isConfigured()) {
+				return;
+			}
+
+			UserDetails user = User.withUserDetails(PasswordEncodedUser.user()).username("boot").build();
+
+			List<UserDetails> users = Arrays.asList(user);
+			InMemoryUserDetailsManager inMemory = new InMemoryUserDetailsManager(users);
+
+			DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
+			provider.setUserDetailsService(inMemory);
+
+			auth.authenticationProvider(provider);
+		}
+	}
+
+	// gh-2531
+	@Test
+	public void getAuthenticationManagerWhenPostProcessThenUsesBeanClassLoaderOnProxyFactoryBean() throws Exception {
+		this.spring.register(Sec2531Config.class).autowire();
+		ObjectPostProcessor<Object> opp = this.spring.getContext().getBean(ObjectPostProcessor.class);
+		when(opp.postProcess(any())).thenAnswer(a -> a.getArgument(0));
+
+		AuthenticationConfiguration config = this.spring.getContext().getBean(AuthenticationConfiguration.class);
+		config.getAuthenticationManager();
+
+		verify(opp).postProcess(any(ProxyFactoryBean.class));
+	}
+
+	@Configuration
+	@Import(AuthenticationConfiguration.class)
+	static class Sec2531Config {
+
+		@Bean
+		public ObjectPostProcessor objectPostProcessor() {
+			return mock(ObjectPostProcessor.class);
+		}
+
+		@Bean
+		public AuthenticationManager manager() {
+			return null;
+		}
+	}
+
+	@Test
+	public void getAuthenticationManagerWhenSec2822ThenCannotForceAuthenticationAlreadyBuilt() throws Exception {
+		this.spring.register(Sec2822WebSecurity.class, Sec2822UseAuth.class, Sec2822Config.class).autowire();
+
+		this.spring.getContext().getBean(AuthenticationConfiguration.class).getAuthenticationManager();
+		// no exception
+	}
+
+	@Configuration
+	@Import(AuthenticationConfiguration.class)
+	static class Sec2822Config {}
+
+	@Configuration
+	@EnableWebSecurity
+	static class Sec2822WebSecurity extends WebSecurityConfigurerAdapter {
+		@Autowired
+		public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
+			auth.inMemoryAuthentication();
+		}
+	}
+
+	@Configuration
+	static class Sec2822UseAuth {
+		@Autowired
+		public void useAuthenticationManager(AuthenticationConfiguration auth) throws Exception {
+			auth.getAuthenticationManager();
+		}
+
+		// Ensures that Sec2822UseAuth is initialized before Sec2822WebSecurity
+		// must have additional GlobalAuthenticationConfigurerAdapter to trigger SEC-2822
+		@Bean
+		public static GlobalAuthenticationConfigurerAdapter bootGlobalAuthenticationConfigurerAdapter() {
+			return new BootGlobalAuthenticationConfigurerAdapter();
+		}
+
+		static class BootGlobalAuthenticationConfigurerAdapter extends GlobalAuthenticationConfigurerAdapter { }
+	}
+
+	// sec-2868
+	@Test
+	public void getAuthenticationWhenUserDetailsServiceBeanThenAuthenticationManagerUsesUserDetailsServiceBean() throws Exception {
+		this.spring.register(UserDetailsServiceBeanConfig.class).autowire();
+		UserDetailsService uds = this.spring.getContext().getBean(UserDetailsService.class);
+		AuthenticationManager am = this.spring.getContext().getBean(AuthenticationConfiguration.class).getAuthenticationManager();
+		when(uds.loadUserByUsername("user")).thenReturn(PasswordEncodedUser.user(), PasswordEncodedUser.user());
+
+		am.authenticate(new UsernamePasswordAuthenticationToken("user", "password"));
+
+		assertThatThrownBy(() -> am.authenticate(new UsernamePasswordAuthenticationToken("user", "invalid")))
+			.isInstanceOf(AuthenticationException.class);
+	}
+
+	@Configuration
+	@Import({AuthenticationConfiguration.class, ObjectPostProcessorConfiguration.class})
+	static class UserDetailsServiceBeanConfig {
+		UserDetailsService uds = mock(UserDetailsService.class);
+
+		@Bean
+		UserDetailsService userDetailsService() {
+			return this.uds;
+		}
+	}
+
+	@Test
+	public void getAuthenticationWhenUserDetailsServiceAndPasswordEncoderBeanThenEncoderUsed() throws Exception {
+		UserDetails user = new User("user", "$2a$10$FBAKClV1zBIOOC9XMXf3AO8RoGXYVYsfvUdoLxGkd/BnXEn4tqT3u",
+			AuthorityUtils.createAuthorityList("ROLE_USER"));
+		this.spring.register(UserDetailsServiceBeanWithPasswordEncoderConfig.class).autowire();
+		UserDetailsService uds = this.spring.getContext().getBean(UserDetailsService.class);
+		AuthenticationManager am = this.spring.getContext().getBean(AuthenticationConfiguration.class).getAuthenticationManager();
+		when(uds.loadUserByUsername("user")).thenReturn(User.withUserDetails(user).build(), User.withUserDetails(user).build());
+
+		am.authenticate(new UsernamePasswordAuthenticationToken("user", "password"));
+
+		assertThatThrownBy(() -> am.authenticate(new UsernamePasswordAuthenticationToken("user", "invalid")))
+			.isInstanceOf(AuthenticationException.class);
+	}
+
+	@Configuration
+	@Import({AuthenticationConfiguration.class, ObjectPostProcessorConfiguration.class})
+	static class UserDetailsServiceBeanWithPasswordEncoderConfig {
+		UserDetailsService uds = mock(UserDetailsService.class);
+
+		@Bean
+		UserDetailsService userDetailsService() {
+			return this.uds;
+		}
+
+		@Bean
+		PasswordEncoder passwordEncoder() {
+			return new BCryptPasswordEncoder();
+		}
+	}
+
+	//gh-3091
+	@Test
+	public void getAuthenticationWhenAuthenticationProviderBeanThenUsed() throws Exception {
+		this.spring.register(AuthenticationProviderBeanConfig.class).autowire();
+		AuthenticationProvider ap = this.spring.getContext().getBean(AuthenticationProvider.class);
+		AuthenticationManager am = this.spring.getContext().getBean(AuthenticationConfiguration.class).getAuthenticationManager();
+		when(ap.supports(any())).thenReturn(true);
+		when(ap.authenticate(any())).thenReturn(TestAuthentication.authenticatedUser());
+
+		am.authenticate(new UsernamePasswordAuthenticationToken("user", "password"));
+	}
+
+	@Configuration
+	@Import({AuthenticationConfiguration.class, ObjectPostProcessorConfiguration.class})
+	static class AuthenticationProviderBeanConfig {
+		AuthenticationProvider provider = mock(AuthenticationProvider.class);
+
+		@Bean
+		AuthenticationProvider authenticationProvider() {
+			return this.provider;
+		}
+	}
+
+	@Test
+	public void getAuthenticationWhenAuthenticationProviderAndUserDetailsBeanThenAuthenticationProviderUsed() throws Exception {
+		this.spring.register(AuthenticationProviderBeanAndUserDetailsServiceConfig.class).autowire();
+		AuthenticationProvider ap = this.spring.getContext().getBean(AuthenticationProvider.class);
+		AuthenticationManager am = this.spring.getContext().getBean(AuthenticationConfiguration.class).getAuthenticationManager();
+		when(ap.supports(any())).thenReturn(true);
+		when(ap.authenticate(any())).thenReturn(TestAuthentication.authenticatedUser());
+
+		am.authenticate(new UsernamePasswordAuthenticationToken("user", "password"));
+	}
+
+	@Configuration
+	@Import({AuthenticationConfiguration.class, ObjectPostProcessorConfiguration.class})
+	static class AuthenticationProviderBeanAndUserDetailsServiceConfig {
+		AuthenticationProvider provider = mock(AuthenticationProvider.class);
+
+		UserDetailsService uds = mock(UserDetailsService.class);
+
+		@Bean
+		UserDetailsService userDetailsService() {
+			return this.uds;
+		}
+
+		@Bean
+		AuthenticationProvider authenticationProvider() {
+			return this.provider;
+		}
+	}
+
+	@Test
+	public void enableGlobalMethodSecurityWhenPreAuthorizeThenNoException() throws Exception {
+		this.spring.register(UsesPreAuthorizeMethodSecurityConfig.class, AuthenticationManagerBeanConfig.class).autowire();
+
+		// no exception
+	}
+
+	@Configuration
+	@EnableGlobalMethodSecurity(prePostEnabled = true)
+	static class UsesPreAuthorizeMethodSecurityConfig {
+		@PreAuthorize("denyAll")
+		void run() {}
+	}
+
+	@Test
+	public void enableGlobalMethodSecurityWhenPreAuthorizeThenUsesMethodSecurityService() throws Exception {
+		this.spring.register(ServicesConfig.class, UsesPreAuthorizeMethodSecurityConfig.class, AuthenticationManagerBeanConfig.class).autowire();
+
+		// no exception
+	}
+
+	@Configuration
+	@EnableGlobalMethodSecurity(securedEnabled = true)
+	static class UsesServiceMethodSecurityConfig {
+		@Autowired
+		Service service;
+	}
+}