Migrate LDAP integration tests groovy->java

This commit also removes BaseSpringSpec

Issue: gh-4939
This commit is contained in:
Vincent Ricard 2019-11-30 23:12:53 +01:00 committed by Eleftheria Stein-Kousathana
parent 1f6381d970
commit f0856c83a9
13 changed files with 625 additions and 943 deletions

View File

@ -1,220 +0,0 @@
/*
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.config.annotation.authentication.ldap
import org.springframework.beans.factory.config.AutowireCapableBeanFactory
import org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.context.annotation.Import
import org.springframework.ldap.core.ContextSource;
import org.springframework.ldap.core.support.BaseLdapPathContextSource;
import org.springframework.security.authentication.AuthenticationManager
import org.springframework.security.authentication.AuthenticationProvider
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
import org.springframework.security.config.annotation.BaseSpringSpec
import org.springframework.security.config.annotation.SecurityBuilder;
import org.springframework.security.config.annotation.authentication.AuthenticationManagerBuilder
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder
import org.springframework.security.config.annotation.authentication.configuration.EnableGlobalAuthentication
import org.springframework.security.config.annotation.configuration.AutowireBeanFactoryObjectPostProcessor
import org.springframework.security.config.annotation.configuration.AutowireBeanFactoryObjectPostProcessorTests
import org.springframework.security.config.annotation.configuration.ObjectPostProcessorConfiguration
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder
import org.springframework.security.ldap.DefaultSpringSecurityContextSource;
import org.springframework.security.ldap.authentication.LdapAuthenticationProvider;
import org.springframework.security.ldap.server.ApacheDSContainer;
import org.springframework.test.util.ReflectionTestUtils;
/**
*
* @author Rob Winch
*
*/
class LdapAuthenticationProviderBuilderSecurityBuilderTests extends BaseSpringSpec {
def "default configuration"() {
when:
loadConfig(DefaultLdapConfig)
LdapAuthenticationProvider provider = ldapProvider()
then:
provider.authoritiesPopulator.groupRoleAttribute == "cn"
provider.authoritiesPopulator.groupSearchBase == ""
provider.authoritiesPopulator.groupSearchFilter == "(uniqueMember={0})"
ReflectionTestUtils.getField(provider,"authoritiesMapper").prefix == "ROLE_"
}
@Configuration
static class DefaultLdapConfig extends BaseLdapProviderConfig {
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.ldapAuthentication()
.contextSource(contextSource())
.userDnPatterns("uid={0},ou=people")
}
}
def "group roles custom"() {
when:
loadConfig(GroupRolesConfig)
LdapAuthenticationProvider provider = ldapProvider()
then:
provider.authoritiesPopulator.groupRoleAttribute == "group"
}
@Configuration
static class GroupRolesConfig extends BaseLdapProviderConfig {
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.ldapAuthentication()
.contextSource(contextSource())
.userDnPatterns("uid={0},ou=people")
.groupRoleAttribute("group")
}
}
def "group search custom"() {
when:
loadConfig(GroupSearchConfig)
LdapAuthenticationProvider provider = ldapProvider()
then:
provider.authoritiesPopulator.groupSearchFilter == "ou=groupName"
}
@Configuration
static class GroupSearchConfig extends BaseLdapProviderConfig {
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.ldapAuthentication()
.contextSource(contextSource())
.userDnPatterns("uid={0},ou=people")
.groupSearchFilter("ou=groupName");
}
}
def "role prefix custom"() {
when:
loadConfig(RolePrefixConfig)
LdapAuthenticationProvider provider = ldapProvider()
then:
ReflectionTestUtils.getField(provider,"authoritiesMapper").prefix == "role_"
}
@Configuration
static class RolePrefixConfig extends BaseLdapProviderConfig {
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.ldapAuthentication()
.contextSource(contextSource())
.userDnPatterns("uid={0},ou=people")
.rolePrefix("role_")
}
}
def "bind authentication"() {
when:
loadConfig(BindAuthenticationConfig)
AuthenticationManager auth = context.getBean(AuthenticationManager)
then:
auth
auth.authenticate(new UsernamePasswordAuthenticationToken("bob","bobspassword")).authorities.collect { it.authority }.sort() == ["ROLE_DEVELOPERS"]
}
@Configuration
static class BindAuthenticationConfig extends BaseLdapServerConfig {
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.ldapAuthentication()
.contextSource(contextSource())
.groupSearchBase("ou=groups")
.groupSearchFilter("(member={0})")
.userDnPatterns("uid={0},ou=people");
}
}
def "SEC-2472: Can use crypto PasswordEncoder"() {
setup:
loadConfig(PasswordEncoderConfig)
when:
AuthenticationManager auth = context.getBean(AuthenticationManager)
then:
auth.authenticate(new UsernamePasswordAuthenticationToken("bcrypt","password")).authorities.collect { it.authority }.sort() == ["ROLE_DEVELOPERS"]
}
@Configuration
static class PasswordEncoderConfig extends BaseLdapServerConfig {
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.ldapAuthentication()
.contextSource(contextSource())
.passwordEncoder(new BCryptPasswordEncoder())
.groupSearchBase("ou=groups")
.groupSearchFilter("(member={0})")
.userDnPatterns("uid={0},ou=people");
}
}
def ldapProvider() {
context.getBean(AuthenticationManager).providers[0]
}
@Configuration
static abstract class BaseLdapServerConfig extends BaseLdapProviderConfig {
@Bean
public ApacheDSContainer ldapServer() throws Exception {
ApacheDSContainer apacheDSContainer = new ApacheDSContainer("dc=springframework,dc=org", "classpath:/test-server.ldif");
apacheDSContainer.setPort(getPort());
return apacheDSContainer;
}
}
@Configuration
@EnableGlobalAuthentication
@Import(ObjectPostProcessorConfiguration)
static abstract class BaseLdapProviderConfig {
@Bean
public BaseLdapPathContextSource contextSource() throws Exception {
DefaultSpringSecurityContextSource contextSource = new DefaultSpringSecurityContextSource(
"ldap://127.0.0.1:"+ getPort() + "/dc=springframework,dc=org")
contextSource.userDn = "uid=admin,ou=system"
contextSource.password = "secret"
contextSource.afterPropertiesSet()
return contextSource;
}
@Bean
public AuthenticationManager authenticationManager(AuthenticationManagerBuilder auth) {
configure(auth)
auth.build()
}
abstract protected void configure(AuthenticationManagerBuilder auth) throws Exception
}
static Integer port;
static int getPort() {
if(port == null) {
ServerSocket socket = new ServerSocket(0)
port = socket.localPort
socket.close()
}
port
}
}

View File

@ -1,90 +0,0 @@
/*
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.config.annotation.authentication.ldap
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
import org.springframework.security.config.annotation.BaseSpringSpec
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
import org.springframework.security.core.authority.SimpleGrantedAuthority
/**
*
* @author Rob Winch
* @author Eddú Meléndez
*
*/
class LdapAuthenticationProviderConfigurerTests extends BaseSpringSpec {
def "authentication-manager support multiple default ldap contexts (ports dynamically allocated)"() {
when:
loadConfig(MultiLdapAuthenticationProvidersConfig)
then:
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("bob","bobspassword"))
}
def "authentication-manager support multiple ldap context with default role prefix" () {
when:
loadConfig(MultiLdapAuthenticationProvidersConfig)
then:
def authenticate = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("bob", "bobspassword"))
authenticate.authorities.contains(new SimpleGrantedAuthority("ROLE_DEVELOPERS"))
}
def "authentication-manager support multiple ldap context with custom role prefix"() {
when:
loadConfig(MultiLdapWithCustomRolePrefixAuthenticationProvidersConfig)
then:
def authenticate = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("bob", "bobspassword"))
authenticate.authorities.contains(new SimpleGrantedAuthority("ROL_DEVELOPERS"))
}
@EnableWebSecurity
static class MultiLdapAuthenticationProvidersConfig extends WebSecurityConfigurerAdapter {
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.ldapAuthentication()
.groupSearchBase("ou=groups")
.groupSearchFilter("(member={0})")
.userDnPatterns("uid={0},ou=people")
.and()
.ldapAuthentication()
.groupSearchBase("ou=groups")
.groupSearchFilter("(member={0})")
.userDnPatterns("uid={0},ou=people")
}
}
@EnableWebSecurity
static class MultiLdapWithCustomRolePrefixAuthenticationProvidersConfig extends
WebSecurityConfigurerAdapter {
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.ldapAuthentication()
.groupSearchBase("ou=groups")
.groupSearchFilter("(member={0})")
.userDnPatterns("uid={0},ou=people")
.rolePrefix("ROL_")
.and()
.ldapAuthentication()
.groupSearchBase("ou=groups")
.groupSearchFilter("(member={0})")
.userDnPatterns("uid={0},ou=people")
.rolePrefix("RUOLO_")
}
}
}

View File

@ -1,80 +0,0 @@
/*
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.config.annotation.authentication.ldap
import static org.springframework.security.config.annotation.authentication.ldap.NamespaceLdapAuthenticationProviderTestsConfigs.*
import org.springframework.ldap.core.support.BaseLdapPathContextSource
import org.springframework.security.authentication.AuthenticationManager
import org.springframework.security.authentication.AuthenticationProvider
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
import org.springframework.security.config.annotation.BaseSpringSpec
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.authentication.ldap.NamespaceLdapAuthenticationProviderTestsConfigs.LdapAuthenticationProviderConfig;
import org.springframework.security.ldap.authentication.LdapAuthenticationProvider;
import org.springframework.security.ldap.authentication.PasswordComparisonAuthenticator;
import org.springframework.security.ldap.userdetails.LdapAuthoritiesPopulator;
import org.springframework.security.ldap.userdetails.PersonContextMapper;
import org.springframework.test.util.ReflectionTestUtils;
/**
*
* @author Rob Winch
*
*/
class NamespaceLdapAuthenticationProviderTests extends BaseSpringSpec {
def "ldap-authentication-provider"() {
when:
loadConfig(LdapAuthenticationProviderConfig)
then:
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("bob","bobspassword"))
}
def "ldap-authentication-provider custom"() {
when:
loadConfig(CustomLdapAuthenticationProviderConfig)
LdapAuthenticationProvider provider = findAuthenticationProvider(LdapAuthenticationProvider)
then:
provider.authoritiesPopulator.groupRoleAttribute == "cn"
provider.authoritiesPopulator.groupSearchBase == "ou=groups"
provider.authoritiesPopulator.groupSearchFilter == "(member={0})"
ReflectionTestUtils.getField(provider,"authoritiesMapper").prefix == "PREFIX_"
provider.userDetailsContextMapper instanceof PersonContextMapper
provider.authenticator.getUserDns("user") == ["uid=user,ou=people"]
provider.authenticator.userSearch.searchBase == "ou=users"
provider.authenticator.userSearch.searchFilter == "(uid={0})"
}
def "SEC-2490: ldap-authentication-provider custom LdapAuthoritiesPopulator"() {
setup:
LdapAuthoritiesPopulator LAP = Mock()
CustomAuthoritiesPopulatorConfig.LAP = LAP
when:
loadConfig(CustomAuthoritiesPopulatorConfig)
LdapAuthenticationProvider provider = findAuthenticationProvider(LdapAuthenticationProvider)
then:
provider.authoritiesPopulator == LAP
}
def "ldap-authentication-provider password compare"() {
when:
loadConfig(PasswordCompareLdapConfig)
LdapAuthenticationProvider provider = findAuthenticationProvider(LdapAuthenticationProvider)
then:
provider.authenticator instanceof PasswordComparisonAuthenticator
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("bob","bobspassword"))
}
}

View File

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

View File

@ -0,0 +1,250 @@
/*
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.config.annotation.authentication.ldap;
import org.junit.Rule;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.ldap.core.support.BaseLdapPathContextSource;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.authentication.configuration.EnableGlobalAuthentication;
import org.springframework.security.config.annotation.configuration.ObjectPostProcessorConfiguration;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.test.SpringTestRule;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.ldap.DefaultSpringSecurityContextSource;
import org.springframework.security.ldap.authentication.LdapAuthenticationProvider;
import org.springframework.security.ldap.server.ApacheDSContainer;
import org.springframework.security.ldap.userdetails.LdapAuthoritiesPopulator;
import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.test.web.servlet.MockMvc;
import java.io.IOException;
import java.net.ServerSocket;
import java.util.List;
import static java.util.Collections.singleton;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.formLogin;
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.authenticated;
public class LdapAuthenticationProviderBuilderSecurityBuilderTests {
@Rule
public final SpringTestRule spring = new SpringTestRule();
@Autowired
private MockMvc mockMvc;
@Autowired
private AuthenticationManager authenticationManager;
@Test
public void defaultConfiguration() {
this.spring.register(DefaultLdapConfig.class).autowire();
LdapAuthenticationProvider provider = ldapProvider();
LdapAuthoritiesPopulator authoritiesPopulator = getAuthoritiesPopulator(provider);
assertThat(authoritiesPopulator).hasFieldOrPropertyWithValue("groupRoleAttribute", "cn");
assertThat(authoritiesPopulator).hasFieldOrPropertyWithValue("groupSearchBase", "");
assertThat(authoritiesPopulator).hasFieldOrPropertyWithValue("groupSearchFilter", "(uniqueMember={0})");
assertThat(ReflectionTestUtils.getField(getAuthoritiesMapper(provider), "prefix")).isEqualTo("ROLE_");
}
@EnableWebSecurity
static class DefaultLdapConfig extends BaseLdapProviderConfig {
// @formatter:off
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.ldapAuthentication()
.contextSource(contextSource())
.userDnPatterns("uid={0},ou=people");
}
// @formatter:on
}
@Test
public void groupRolesCustom() {
this.spring.register(GroupRolesConfig.class).autowire();
LdapAuthenticationProvider provider = ldapProvider();
assertThat(ReflectionTestUtils.getField(getAuthoritiesPopulator(provider), "groupRoleAttribute")).isEqualTo("group");
}
@EnableWebSecurity
static class GroupRolesConfig extends BaseLdapProviderConfig {
// @formatter:off
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.ldapAuthentication()
.contextSource(contextSource())
.userDnPatterns("uid={0},ou=people")
.groupRoleAttribute("group");
}
// @formatter:on
}
@Test
public void groupSearchCustom() {
this.spring.register(GroupSearchConfig.class).autowire();
LdapAuthenticationProvider provider = ldapProvider();
assertThat(ReflectionTestUtils.getField(getAuthoritiesPopulator(provider), "groupSearchFilter")).isEqualTo("ou=groupName");
}
@EnableWebSecurity
static class GroupSearchConfig extends BaseLdapProviderConfig {
// @formatter:off
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.ldapAuthentication()
.contextSource(contextSource())
.userDnPatterns("uid={0},ou=people")
.groupSearchFilter("ou=groupName");
}
// @formatter:on
}
@Test
public void rolePrefixCustom() {
this.spring.register(RolePrefixConfig.class).autowire();
LdapAuthenticationProvider provider = ldapProvider();
assertThat(ReflectionTestUtils.getField(getAuthoritiesMapper(provider), "prefix")).isEqualTo("role_");
}
@EnableWebSecurity
static class RolePrefixConfig extends BaseLdapProviderConfig {
// @formatter:off
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.ldapAuthentication()
.contextSource(contextSource())
.userDnPatterns("uid={0},ou=people")
.rolePrefix("role_");
}
// @formatter:on
}
@Test
public void bindAuthentication() throws Exception {
this.spring.register(BindAuthenticationConfig.class).autowire();
this.mockMvc.perform(formLogin().user("bob").password("bobspassword"))
.andExpect(authenticated().withUsername("bob").withAuthorities(singleton(new SimpleGrantedAuthority("ROLE_DEVELOPERS"))));
}
@EnableWebSecurity
static class BindAuthenticationConfig extends BaseLdapServerConfig {
// @formatter:off
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.ldapAuthentication()
.contextSource(contextSource())
.groupSearchBase("ou=groups")
.groupSearchFilter("(member={0})")
.userDnPatterns("uid={0},ou=people");
}
// @formatter:on
}
// SEC-2472
@Test
public void canUseCryptoPasswordEncoder() throws Exception {
this.spring.register(PasswordEncoderConfig.class).autowire();
this.mockMvc.perform(formLogin().user("bcrypt").password("password"))
.andExpect(authenticated().withUsername("bcrypt").withAuthorities(singleton(new SimpleGrantedAuthority("ROLE_DEVELOPERS"))));
}
@EnableWebSecurity
static class PasswordEncoderConfig extends BaseLdapServerConfig {
// @formatter:off
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.ldapAuthentication()
.contextSource(contextSource())
.passwordEncoder(new BCryptPasswordEncoder())
.groupSearchBase("ou=groups")
.groupSearchFilter("(member={0})")
.userDnPatterns("uid={0},ou=people");
}
// @formatter:on
}
private LdapAuthenticationProvider ldapProvider() {
return ((List<LdapAuthenticationProvider>) ReflectionTestUtils.getField(authenticationManager, "providers")).get(0);
}
private LdapAuthoritiesPopulator getAuthoritiesPopulator(LdapAuthenticationProvider provider) {
return (LdapAuthoritiesPopulator) ReflectionTestUtils.getField(provider, "authoritiesPopulator");
}
private GrantedAuthoritiesMapper getAuthoritiesMapper(LdapAuthenticationProvider provider) {
return (GrantedAuthoritiesMapper) ReflectionTestUtils.getField(provider, "authoritiesMapper");
}
@EnableWebSecurity
static abstract class BaseLdapServerConfig extends BaseLdapProviderConfig {
@Bean
public ApacheDSContainer ldapServer() throws Exception {
ApacheDSContainer apacheDSContainer = new ApacheDSContainer("dc=springframework,dc=org", "classpath:/test-server.ldif");
apacheDSContainer.setPort(getPort());
return apacheDSContainer;
}
}
@EnableWebSecurity
@EnableGlobalAuthentication
@Import(ObjectPostProcessorConfiguration.class)
static abstract class BaseLdapProviderConfig extends WebSecurityConfigurerAdapter {
@Bean
public BaseLdapPathContextSource contextSource() throws Exception {
DefaultSpringSecurityContextSource contextSource = new DefaultSpringSecurityContextSource(
"ldap://127.0.0.1:" + getPort() + "/dc=springframework,dc=org");
contextSource.setUserDn("uid=admin,ou=system");
contextSource.setPassword("secret");
contextSource.afterPropertiesSet();
return contextSource;
}
@Bean
public AuthenticationManager authenticationManager(AuthenticationManagerBuilder auth) throws Exception {
configure(auth);
return auth.build();
}
abstract protected void configure(AuthenticationManagerBuilder auth) throws Exception;
}
static Integer port;
static int getPort() throws IOException {
if (port == null) {
ServerSocket socket = new ServerSocket(0);
port = socket.getLocalPort();
socket.close();
}
return port;
}
}

View File

@ -0,0 +1,101 @@
/*
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.config.annotation.authentication.ldap;
import org.junit.Rule;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.test.SpringTestRule;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.test.web.servlet.MockMvc;
import static java.util.Collections.singleton;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.formLogin;
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.authenticated;
public class LdapAuthenticationProviderConfigurerTests {
@Rule
public final SpringTestRule spring = new SpringTestRule();
@Autowired
private MockMvc mockMvc;
@Test
public void authenticationManagerSupportMultipleDefaultLdapContextsWithPortsDynamicallyAllocated() throws Exception {
this.spring.register(MultiLdapAuthenticationProvidersConfig.class).autowire();
this.mockMvc.perform(formLogin().user("bob").password("bobspassword"))
.andExpect(authenticated().withUsername("bob"));
}
@Test
public void authenticationManagerSupportMultipleLdapContextWithDefaultRolePrefix() throws Exception {
this.spring.register(MultiLdapAuthenticationProvidersConfig.class).autowire();
this.mockMvc.perform(formLogin().user("bob").password("bobspassword"))
.andExpect(authenticated().withUsername("bob").withAuthorities(singleton(new SimpleGrantedAuthority("ROLE_DEVELOPERS"))));
}
@Test
public void authenticationManagerSupportMultipleLdapContextWithCustomRolePrefix() throws Exception {
this.spring.register(MultiLdapWithCustomRolePrefixAuthenticationProvidersConfig.class).autowire();
this.mockMvc.perform(formLogin().user("bob").password("bobspassword"))
.andExpect(authenticated().withUsername("bob").withAuthorities(singleton(new SimpleGrantedAuthority("ROL_DEVELOPERS"))));
}
@EnableWebSecurity
static class MultiLdapAuthenticationProvidersConfig extends WebSecurityConfigurerAdapter {
// @formatter:off
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.ldapAuthentication()
.groupSearchBase("ou=groups")
.groupSearchFilter("(member={0})")
.userDnPatterns("uid={0},ou=people")
.and()
.ldapAuthentication()
.groupSearchBase("ou=groups")
.groupSearchFilter("(member={0})")
.userDnPatterns("uid={0},ou=people");
}
// @formatter:on
}
@EnableWebSecurity
static class MultiLdapWithCustomRolePrefixAuthenticationProvidersConfig extends WebSecurityConfigurerAdapter {
// @formatter:off
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.ldapAuthentication()
.groupSearchBase("ou=groups")
.groupSearchFilter("(member={0})")
.userDnPatterns("uid={0},ou=people")
.rolePrefix("ROL_")
.and()
.ldapAuthentication()
.groupSearchBase("ou=groups")
.groupSearchFilter("(member={0})")
.userDnPatterns("uid={0},ou=people")
.rolePrefix("RUOLO_");
}
// @formatter:on
}
}

View File

@ -0,0 +1,95 @@
/*
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.config.annotation.authentication.ldap;
import org.junit.Rule;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ldap.core.DirContextOperations;
import org.springframework.ldap.core.support.LdapContextSource;
import org.springframework.security.config.annotation.authentication.ldap.NamespaceLdapAuthenticationProviderTestsConfigs.CustomAuthoritiesPopulatorConfig;
import org.springframework.security.config.annotation.authentication.ldap.NamespaceLdapAuthenticationProviderTestsConfigs.CustomLdapAuthenticationProviderConfig;
import org.springframework.security.config.annotation.authentication.ldap.NamespaceLdapAuthenticationProviderTestsConfigs.LdapAuthenticationProviderConfig;
import org.springframework.security.config.annotation.authentication.ldap.NamespaceLdapAuthenticationProviderTestsConfigs.PasswordCompareLdapConfig;
import org.springframework.security.config.test.SpringTestRule;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.ldap.DefaultSpringSecurityContextSource;
import org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator;
import org.springframework.security.web.FilterChainProxy;
import org.springframework.test.web.servlet.MockMvc;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.formLogin;
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.authenticated;
public class NamespaceLdapAuthenticationProviderTests {
@Rule
public final SpringTestRule spring = new SpringTestRule();
@Autowired
private MockMvc mockMvc;
@Autowired
private FilterChainProxy filterChainProxy;
@Test
public void ldapAuthenticationProvider() throws Exception {
this.spring.register(LdapAuthenticationProviderConfig.class).autowire();
this.mockMvc.perform(formLogin().user("bob").password("bobspassword"))
.andExpect(authenticated().withUsername("bob"));
}
@Test
public void ldapAuthenticationProviderCustom() throws Exception {
this.spring.register(CustomLdapAuthenticationProviderConfig.class).autowire();
this.mockMvc.perform(formLogin().user("bob").password("bobspassword"))
.andExpect(authenticated().withAuthorities(Collections.singleton(new SimpleGrantedAuthority("PREFIX_DEVELOPERS"))));
}
// SEC-2490
@Test
public void ldapAuthenticationProviderCustomLdapAuthoritiesPopulator() throws Exception {
LdapContextSource contextSource = new DefaultSpringSecurityContextSource("ldap://blah.example.com:789/dc=springframework,dc=org");
CustomAuthoritiesPopulatorConfig.LAP = new DefaultLdapAuthoritiesPopulator(contextSource, null) {
@Override
protected Set<GrantedAuthority> getAdditionalRoles(DirContextOperations user, String username) {
return new HashSet<>(AuthorityUtils.createAuthorityList("ROLE_EXTRA"));
}
};
this.spring.register(CustomAuthoritiesPopulatorConfig.class).autowire();
this.mockMvc.perform(formLogin().user("bob").password("bobspassword"))
.andExpect(authenticated().withAuthorities(Collections.singleton(new SimpleGrantedAuthority("ROLE_EXTRA"))));
}
@Test
public void ldapAuthenticationProviderPasswordCompare() throws Exception {
this.spring.register(PasswordCompareLdapConfig.class).autowire();
this.mockMvc.perform(formLogin().user("bcrypt").password("password"))
.andExpect(authenticated().withUsername("bcrypt"));
}
}

View File

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

View File

@ -0,0 +1,177 @@
/*
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.config.ldap;
import org.junit.After;
import org.junit.Test;
import org.springframework.context.ApplicationContextException;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.config.BeanIds;
import org.springframework.security.config.util.InMemoryXmlApplicationContext;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.ldap.userdetails.InetOrgPersonContextMapper;
import java.text.MessageFormat;
import static org.assertj.core.api.Assertions.assertThat;
public class LdapProviderBeanDefinitionParserTests {
InMemoryXmlApplicationContext appCtx;
@After
public void closeAppContext() {
if (appCtx != null) {
appCtx.close();
appCtx = null;
}
}
@Test
public void simpleProviderAuthenticatesCorrectly() {
appCtx = new InMemoryXmlApplicationContext("<ldap-server ldif='classpath:test-server.ldif'/>"
+ "<authentication-manager>"
+ " <ldap-authentication-provider group-search-filter='member={0}' />"
+ "</authentication-manager>"
);
AuthenticationManager authenticationManager = appCtx.getBean(BeanIds.AUTHENTICATION_MANAGER, AuthenticationManager.class);
Authentication auth = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("ben", "benspassword"));
UserDetails ben = (UserDetails) auth.getPrincipal();
assertThat(ben.getAuthorities()).hasSize(3);
}
@Test
public void multipleProvidersAreSupported() {
appCtx = new InMemoryXmlApplicationContext("<ldap-server ldif='classpath:test-server.ldif'/>"
+ "<authentication-manager>"
+ " <ldap-authentication-provider group-search-filter='member={0}' />"
+ " <ldap-authentication-provider group-search-filter='uniqueMember={0}' />"
+ "</authentication-manager>"
);
ProviderManager providerManager = appCtx.getBean(BeanIds.AUTHENTICATION_MANAGER, ProviderManager.class);
assertThat(providerManager.getProviders()).hasSize(2);
assertThat(providerManager.getProviders())
.extracting("authoritiesPopulator.groupSearchFilter")
.containsExactly("member={0}", "uniqueMember={0}");
}
@Test(expected = ApplicationContextException.class)
public void missingServerEltCausesConfigException() {
new InMemoryXmlApplicationContext("<authentication-manager>"
+ " <ldap-authentication-provider />"
+ "</authentication-manager>"
);
}
@Test
public void supportsPasswordComparisonAuthentication() {
appCtx = new InMemoryXmlApplicationContext("<ldap-server ldif='classpath:test-server.ldif'/>"
+ "<authentication-manager>"
+ " <ldap-authentication-provider user-dn-pattern='uid={0},ou=people'>"
+ " <password-compare />"
+ " </ldap-authentication-provider>"
+ "</authentication-manager>"
);
AuthenticationManager authenticationManager = appCtx.getBean(BeanIds.AUTHENTICATION_MANAGER, AuthenticationManager.class);
Authentication auth = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("ben", "benspassword"));
assertThat(auth).isNotNull();
}
@Test
public void supportsPasswordComparisonAuthenticationWithPasswordEncoder() {
appCtx = new InMemoryXmlApplicationContext("<ldap-server ldif='classpath:test-server.ldif'/>"
+ "<authentication-manager>"
+ " <ldap-authentication-provider user-dn-pattern='uid={0},ou=people'>"
+ " <password-compare password-attribute='uid'>"
+ " <password-encoder ref='passwordEncoder' />"
+ " </password-compare>"
+ " </ldap-authentication-provider>"
+ "</authentication-manager>"
+ "<b:bean id='passwordEncoder' class='org.springframework.security.crypto.password.NoOpPasswordEncoder' factory-method='getInstance' />"
);
AuthenticationManager authenticationManager = appCtx.getBean(BeanIds.AUTHENTICATION_MANAGER, AuthenticationManager.class);
Authentication auth = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("ben", "ben"));
assertThat(auth).isNotNull();
}
// SEC-2472
@Test
public void supportsCryptoPasswordEncoder() {
appCtx = new InMemoryXmlApplicationContext("<ldap-server ldif='classpath:test-server.ldif'/>"
+ "<authentication-manager>"
+ " <ldap-authentication-provider user-dn-pattern='uid={0},ou=people'>"
+ " <password-compare>"
+ " <password-encoder ref='pe' />"
+ " </password-compare>"
+ " </ldap-authentication-provider>"
+ "</authentication-manager>"
+ "<b:bean id='pe' class='org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder' />"
);
AuthenticationManager authenticationManager = appCtx.getBean(BeanIds.AUTHENTICATION_MANAGER, AuthenticationManager.class);
Authentication auth = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("bcrypt", "password"));
assertThat(auth).isNotNull();
}
@Test
public void inetOrgContextMapperIsSupported() {
appCtx = new InMemoryXmlApplicationContext("<ldap-server url='ldap://127.0.0.1:343/dc=springframework,dc=org'/>"
+ "<authentication-manager>"
+ " <ldap-authentication-provider user-details-class='inetOrgPerson' />"
+ "</authentication-manager>"
);
ProviderManager providerManager = appCtx.getBean(BeanIds.AUTHENTICATION_MANAGER, ProviderManager.class);
assertThat(providerManager.getProviders()).hasSize(1);
assertThat(providerManager.getProviders())
.extracting("userDetailsContextMapper")
.allSatisfy(contextMapper -> assertThat(contextMapper).isInstanceOf(InetOrgPersonContextMapper.class));
}
@Test
public void ldapAuthenticationProviderWorksWithPlaceholders() {
System.setProperty("udp", "people");
System.setProperty("gsf", "member");
appCtx = new InMemoryXmlApplicationContext("<ldap-server />"
+ "<authentication-manager>"
+ " <ldap-authentication-provider user-dn-pattern='uid={0},ou=${udp}' group-search-filter='${gsf}={0}' />"
+ "</authentication-manager>"
+ "<b:bean id='org.springframework.beans.factory.config.PropertyPlaceholderConfigurer' class='org.springframework.beans.factory.config.PropertyPlaceholderConfigurer' />"
);
ProviderManager providerManager = appCtx.getBean(BeanIds.AUTHENTICATION_MANAGER, ProviderManager.class);
assertThat(providerManager.getProviders()).hasSize(1);
AuthenticationProvider authenticationProvider = providerManager.getProviders().get(0);
assertThat(authenticationProvider)
.extracting("authenticator.userDnFormat")
.satisfies(messageFormats -> assertThat(messageFormats).isEqualTo(new MessageFormat[]{new MessageFormat("uid={0},ou=people")}));
assertThat(authenticationProvider)
.extracting("authoritiesPopulator.groupSearchFilter")
.satisfies(searchFilter -> assertThat(searchFilter).isEqualTo("member={0}"));
}
}

View File

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

View File

@ -1,25 +0,0 @@
/*
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.config.annotation;
/**
* Exists for mocking purposes to ensure that the Type information is found.
*
* @author Rob Winch
*/
public interface AnyObjectPostProcessor extends ObjectPostProcessor<Object> {
}

View File

@ -1,174 +0,0 @@
/*
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.config.annotation;
import javax.servlet.Filter
import spock.lang.AutoCleanup
import spock.lang.Specification
import org.springframework.beans.factory.NoSuchBeanDefinitionException
import org.springframework.context.ConfigurableApplicationContext
import org.springframework.context.annotation.AnnotationConfigApplicationContext
import org.springframework.mock.web.MockFilterChain
import org.springframework.mock.web.MockHttpServletRequest
import org.springframework.mock.web.MockHttpServletResponse
import org.springframework.mock.web.MockServletContext
import org.springframework.security.authentication.AuthenticationManager
import org.springframework.security.authentication.AuthenticationProvider
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration
import org.springframework.security.config.annotation.configuration.ObjectPostProcessorConfiguration
import org.springframework.security.core.Authentication
import org.springframework.security.core.authority.AuthorityUtils
import org.springframework.security.core.context.SecurityContextHolder
import org.springframework.security.core.context.SecurityContextImpl
import org.springframework.security.web.FilterChainProxy
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor
import org.springframework.security.web.context.HttpRequestResponseHolder
import org.springframework.security.web.context.HttpSessionSecurityContextRepository
import org.springframework.security.web.csrf.CsrfToken
import org.springframework.security.web.csrf.DefaultCsrfToken
import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext
/**
*
* @author Rob Winch
*/
abstract class BaseSpringSpec extends Specification {
boolean allowCircularReferences = false
@AutoCleanup
ConfigurableApplicationContext context
@AutoCleanup
ConfigurableApplicationContext oppContext
MockHttpServletRequest request
MockHttpServletResponse response
MockFilterChain chain
CsrfToken csrfToken
AuthenticationManagerBuilder authenticationBldr
def setup() {
authenticationBldr = createAuthenticationManagerBuilder()
setupWeb(null)
}
def setupWeb(httpSession = null) {
request = new MockHttpServletRequest(method:"GET")
if(httpSession) {
request.session = httpSession
}
response = new MockHttpServletResponse()
chain = new MockFilterChain()
setupCsrf()
}
def setupCsrf(csrfTokenValue="BaseSpringSpec_CSRFTOKEN",req=request,resp=response) {
csrfToken = new DefaultCsrfToken("X-CSRF-TOKEN","_csrf",csrfTokenValue)
new HttpSessionCsrfTokenRepository().saveToken(csrfToken, req, resp)
req.setParameter(csrfToken.parameterName, csrfToken.token)
}
def cleanup() {
SecurityContextHolder.clearContext()
}
def loadConfig(Class<?>... configs) {
context = new AnnotationConfigWebApplicationContext()
context.setAllowCircularReferences(allowCircularReferences)
context.register(configs)
context.setServletContext(new MockServletContext())
context.refresh()
context
}
def findFilter(Class<?> filter, int index = 0) {
filterChain(index).filters.find { filter.isAssignableFrom(it.class)}
}
def filterChain(int index=0) {
filterChains()[index]
}
def filterChains() {
context.getBean(FilterChainProxy).filterChains
}
Filter getSpringSecurityFilterChain() {
context.getBean("springSecurityFilterChain",Filter.class)
}
def getResponseHeaders() {
def headers = [:]
response.headerNames.each { name ->
headers.put(name, response.getHeaderValues(name).join(','))
}
return headers
}
AuthenticationManager authenticationManager() {
context.getBean(AuthenticationManager)
}
AuthenticationManager getAuthenticationManager() {
try {
authenticationManager().delegateBuilder.getObject()
} catch(NoSuchBeanDefinitionException e) {
} catch(MissingPropertyException e) {}
findFilter(FilterSecurityInterceptor).authenticationManager
}
List<AuthenticationProvider> authenticationProviders() {
List<AuthenticationProvider> providers = new ArrayList<AuthenticationProvider>()
AuthenticationManager authenticationManager = getAuthenticationManager()
while(authenticationManager?.providers) {
providers.addAll(authenticationManager.providers)
authenticationManager = authenticationManager.parent
}
providers
}
AuthenticationProvider findAuthenticationProvider(Class<?> provider) {
authenticationProviders().find { provider.isAssignableFrom(it.class) }
}
def getCurrentAuthentication() {
new HttpSessionSecurityContextRepository().loadContext(new HttpRequestResponseHolder(request, response)).authentication
}
def login(String username="user", String role="ROLE_USER") {
login(new UsernamePasswordAuthenticationToken(username, null, AuthorityUtils.createAuthorityList(role)))
}
def login(Authentication auth) {
HttpSessionSecurityContextRepository repo = new HttpSessionSecurityContextRepository()
HttpRequestResponseHolder requestResponseHolder = new HttpRequestResponseHolder(request, response)
repo.loadContext(requestResponseHolder)
repo.saveContext(new SecurityContextImpl(authentication:auth), requestResponseHolder.request, requestResponseHolder.response)
}
def createAuthenticationManagerBuilder() {
oppContext = new AnnotationConfigApplicationContext(ObjectPostProcessorConfiguration, AuthenticationConfiguration)
AuthenticationManagerBuilder auth = new AuthenticationManagerBuilder(objectPostProcessor)
auth.inMemoryAuthentication().and()
}
def getObjectPostProcessor() {
oppContext.getBean(ObjectPostProcessor)
}
}

View File

@ -1,82 +0,0 @@
/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package org.springframework.security.config.http
import javax.servlet.Filter
import org.springframework.mock.web.MockFilterChain
import org.springframework.mock.web.MockHttpServletRequest
import org.springframework.mock.web.MockHttpServletResponse
import org.springframework.security.config.AbstractXmlConfigTests
import org.springframework.security.config.BeanIds
import org.springframework.security.web.FilterInvocation
import javax.servlet.http.HttpServletRequest
/**
*
* @author Rob Winch
*
*/
abstract class AbstractHttpConfigTests extends AbstractXmlConfigTests {
final int AUTO_CONFIG_FILTERS = 15;
def httpAutoConfig(Closure c) {
xml.http(['auto-config': 'true', 'use-expressions':false], c)
}
def httpAutoConfig(String matcher, Closure c) {
xml.http(['auto-config': 'true', 'use-expressions':false, 'request-matcher': matcher], c)
}
def interceptUrl(String path, String authz) {
xml.'intercept-url'(pattern: path, access: authz)
}
def interceptUrl(String path, String httpMethod, String authz) {
xml.'intercept-url'(pattern: path, method: httpMethod, access: authz)
}
Filter getFilter(Class type) {
List filters = getFilters("/any");
for (f in filters) {
if (f.class.isAssignableFrom(type)) {
return f;
}
}
return null;
}
List getFilters(String url) {
springSecurityFilterChain.getFilters(url)
}
Filter getSpringSecurityFilterChain() {
appContext.getBean(BeanIds.FILTER_CHAIN_PROXY)
}
FilterInvocation createFilterinvocation(String path, String method) {
MockHttpServletRequest request = new MockHttpServletRequest("GET", "");
request.setMethod(method);
request.setRequestURI(null);
request.setServletPath(path);
return new FilterInvocation(request, new MockHttpServletResponse(), new MockFilterChain());
}
def basicLogin(HttpServletRequest request, String username="user",String password="password") {
def credentials = username + ":" + password
request.addHeader("Authorization", "Basic " + credentials.bytes.encodeBase64())
}
}