mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-05-30 08:42:13 +00:00
AuthenticationConfigurationTests -> java
Issue: gh-4939
This commit is contained in:
parent
f7e49ace9f
commit
e5d40c0599
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user