2 changed files with 478 additions and 518 deletions
@ -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…
Reference in new issue