diff --git a/config/src/test/groovy/org/springframework/security/config/annotation/web/configuration/BaseWebConfig.groovy b/config/src/test/groovy/org/springframework/security/config/annotation/web/configuration/BaseWebConfig.groovy deleted file mode 100644 index d212ab2219..0000000000 --- a/config/src/test/groovy/org/springframework/security/config/annotation/web/configuration/BaseWebConfig.groovy +++ /dev/null @@ -1,41 +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.web.configuration; - -import org.springframework.context.annotation.Configuration -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder -import org.springframework.security.core.userdetails.PasswordEncodedUser - -/** - * - * @author Rob Winch - */ -@EnableWebSecurity -public abstract class BaseWebConfig extends WebSecurityConfigurerAdapter { - BaseWebConfig(boolean disableDefaults) { - super(disableDefaults) - } - - BaseWebConfig() { - } - - protected void configure(AuthenticationManagerBuilder auth) throws Exception { - auth - .inMemoryAuthentication() - .withUser(PasswordEncodedUser.user()) - .withUser(PasswordEncodedUser.admin()); - } -} diff --git a/config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/DefaultFiltersTests.groovy b/config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/DefaultFiltersTests.groovy deleted file mode 100644 index 8abfeb0158..0000000000 --- a/config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/DefaultFiltersTests.groovy +++ /dev/null @@ -1,156 +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.web.configurers - -import org.springframework.beans.factory.BeanCreationException -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.context.annotation.AnnotationConfigApplicationContext -import org.springframework.context.annotation.Bean -import org.springframework.context.annotation.Configuration -import org.springframework.mock.web.MockFilterChain -import org.springframework.mock.web.MockHttpServletRequest -import org.springframework.mock.web.MockHttpServletResponse -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.web.WebSecurityConfigurer -import org.springframework.security.config.annotation.web.builders.HttpSecurity -import org.springframework.security.config.annotation.web.builders.WebSecurity -import org.springframework.security.config.annotation.web.configuration.BaseWebConfig -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter -import org.springframework.security.web.DefaultSecurityFilterChain -import org.springframework.security.web.FilterChainProxy -import org.springframework.security.web.access.ExceptionTranslationFilter -import org.springframework.security.web.access.intercept.FilterSecurityInterceptor -import org.springframework.security.web.authentication.AnonymousAuthenticationFilter -import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter -import org.springframework.security.web.authentication.logout.LogoutFilter -import org.springframework.security.web.context.SecurityContextPersistenceFilter -import org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter -import org.springframework.security.web.csrf.CsrfFilter -import org.springframework.security.web.header.HeaderWriterFilter -import org.springframework.security.web.savedrequest.RequestCacheAwareFilter -import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter -import org.springframework.security.web.session.SessionManagementFilter -import org.springframework.security.web.util.matcher.AnyRequestMatcher - -/** - * - * @author Rob Winch - */ -class DefaultFiltersTests extends BaseSpringSpec { - - def "Default the WebSecurityConfigurerAdapter"() { - when: - context = new AnnotationConfigApplicationContext(FilterChainProxyBuilderMissingConfig) - then: - context.getBean(FilterChainProxy) != null - } - - @EnableWebSecurity - static class FilterChainProxyBuilderMissingConfig { - @Autowired - public void configureGlobal(AuthenticationManagerBuilder auth) { - auth - .inMemoryAuthentication() - .withUser("user").password("password").roles("USER") - } - } - - @EnableWebSecurity - static class FilterChainProxyBuilderNoSecurityFilterBuildersConfig { - @Bean - public WebSecurity filterChainProxyBuilder(ObjectPostProcessor opp) { - new WebSecurity(opp) - .ignoring() - .antMatchers("/resources/**") - } - } - - def "null WebInvocationPrivilegeEvaluator"() { - when: - context = new AnnotationConfigApplicationContext(NullWebInvocationPrivilegeEvaluatorConfig) - then: - List filterChains = context.getBean(FilterChainProxy).filterChains - filterChains.size() == 1 - filterChains[0].requestMatcher instanceof AnyRequestMatcher - filterChains[0].filters.size() == 1 - filterChains[0].filters.find { it instanceof UsernamePasswordAuthenticationFilter } - } - - @EnableWebSecurity - static class NullWebInvocationPrivilegeEvaluatorConfig extends BaseWebConfig { - NullWebInvocationPrivilegeEvaluatorConfig() { - super(true) - } - - protected void configure(HttpSecurity http) { - http.formLogin() - } - } - - def "FilterChainProxyBuilder ignoring resources"() { - when: - loadConfig(FilterChainProxyBuilderIgnoringConfig) - then: - List filterChains = context.getBean(FilterChainProxy).filterChains - filterChains.size() == 2 - filterChains[0].requestMatcher.pattern == '/resources/**' - filterChains[0].filters.empty - filterChains[1].requestMatcher instanceof AnyRequestMatcher - filterChains[1].filters.collect { it.class } == - [WebAsyncManagerIntegrationFilter, SecurityContextPersistenceFilter, HeaderWriterFilter, CsrfFilter, LogoutFilter, RequestCacheAwareFilter, - SecurityContextHolderAwareRequestFilter, AnonymousAuthenticationFilter, SessionManagementFilter, - ExceptionTranslationFilter, FilterSecurityInterceptor ] - } - - @EnableWebSecurity - static class FilterChainProxyBuilderIgnoringConfig extends BaseWebConfig { - @Override - public void configure(WebSecurity builder) throws Exception { - builder - .ignoring() - .antMatchers("/resources/**"); - } - @Override - protected void configure(HttpSecurity http) { - http - .authorizeRequests() - .anyRequest().hasRole("USER"); - } - } - - def "DefaultFilters.permitAll()"() { - when: - loadConfig(DefaultFiltersConfigPermitAll) - MockHttpServletResponse response = new MockHttpServletResponse() - request = new MockHttpServletRequest(servletPath : uri, queryString: query, method:"POST") - setupCsrf() - springSecurityFilterChain.doFilter(request, response, new MockFilterChain()) - then: - response.redirectedUrl == "/login?logout" - where: - uri | query - "/logout" | null - } - - @EnableWebSecurity - static class DefaultFiltersConfigPermitAll extends BaseWebConfig { - protected void configure(HttpSecurity http) { - } - } -} diff --git a/config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/Issue55Tests.groovy b/config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/Issue55Tests.groovy deleted file mode 100644 index 2a01e1ca26..0000000000 --- a/config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/Issue55Tests.groovy +++ /dev/null @@ -1,118 +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.web.configurers - -import org.springframework.context.annotation.Bean -import org.springframework.context.annotation.Configuration -import org.springframework.core.annotation.Order; -import org.springframework.security.authentication.AuthenticationManager -import org.springframework.security.authentication.TestingAuthenticationToken; -import org.springframework.security.config.annotation.BaseSpringSpec -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; -import org.springframework.security.core.Authentication -import org.springframework.security.core.AuthenticationException -import org.springframework.security.web.FilterChainProxy -import org.springframework.security.web.access.intercept.FilterSecurityInterceptor -import org.springframework.stereotype.Component - -/** - * - * @author Rob Winch - */ -class Issue55Tests extends BaseSpringSpec { - - def "WebSecurityConfigurerAdapter defaults to @Autowired"() { - setup: - TestingAuthenticationToken token = new TestingAuthenticationToken("test", "this") - when: - loadConfig(WebSecurityConfigurerAdapterDefaultsAuthManagerConfig) - then: - context.getBean(FilterChainProxy) - findFilter(FilterSecurityInterceptor).authenticationManager.authenticate(token) == CustomAuthenticationManager.RESULT - } - - @EnableWebSecurity - static class WebSecurityConfigurerAdapterDefaultsAuthManagerConfig { - @Component - public static class WebSecurityAdapter extends WebSecurityConfigurerAdapter { - - @Override - protected void configure(HttpSecurity http) throws Exception { - http - .authorizeRequests() - .anyRequest().hasRole("USER"); - } - } - @Configuration - public static class AuthenticationManagerConfiguration { - @Bean - public AuthenticationManager authenticationManager() throws Exception { - return new CustomAuthenticationManager(); - } - } - } - - def "multi http WebSecurityConfigurerAdapter defaults to @Autowired"() { - setup: - TestingAuthenticationToken token = new TestingAuthenticationToken("test", "this") - when: - loadConfig(MultiWebSecurityConfigurerAdapterDefaultsAuthManagerConfig) - then: - context.getBean(FilterChainProxy) - findFilter(FilterSecurityInterceptor).authenticationManager.authenticate(token) == CustomAuthenticationManager.RESULT - findFilter(FilterSecurityInterceptor,1).authenticationManager.authenticate(token) == CustomAuthenticationManager.RESULT - } - - @EnableWebSecurity - static class MultiWebSecurityConfigurerAdapterDefaultsAuthManagerConfig { - @Component - @Order(1) - public static class ApiWebSecurityAdapter extends WebSecurityConfigurerAdapter { - @Override - protected void configure(HttpSecurity http) throws Exception { - http - .antMatcher("/api/**") - .authorizeRequests() - .anyRequest().hasRole("USER"); - } - } - @Component - public static class WebSecurityAdapter extends WebSecurityConfigurerAdapter { - @Override - protected void configure(HttpSecurity http) throws Exception { - http - .authorizeRequests() - .anyRequest().hasRole("USER"); - } - } - @Configuration - public static class AuthenticationManagerConfiguration { - @Bean - public AuthenticationManager authenticationManager() throws Exception { - return new CustomAuthenticationManager(); - } - } - } - - static class CustomAuthenticationManager implements AuthenticationManager { - static Authentication RESULT = new TestingAuthenticationToken("test", "this","ROLE_USER") - public Authentication authenticate(Authentication authentication) throws AuthenticationException { - return RESULT; - } - } -} diff --git a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/DefaultFiltersTests.java b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/DefaultFiltersTests.java new file mode 100644 index 0000000000..f74ace6b52 --- /dev/null +++ b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/DefaultFiltersTests.java @@ -0,0 +1,184 @@ +/* + * 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.web.configurers; + +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.Configuration; +import org.springframework.mock.web.MockFilterChain; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.builders.WebSecurity; +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.userdetails.PasswordEncodedUser; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.provisioning.InMemoryUserDetailsManager; +import org.springframework.security.web.DefaultSecurityFilterChain; +import org.springframework.security.web.FilterChainProxy; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.access.ExceptionTranslationFilter; +import org.springframework.security.web.access.intercept.FilterSecurityInterceptor; +import org.springframework.security.web.authentication.AnonymousAuthenticationFilter; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.security.web.authentication.logout.LogoutFilter; +import org.springframework.security.web.context.SecurityContextPersistenceFilter; +import org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter; +import org.springframework.security.web.csrf.CsrfFilter; +import org.springframework.security.web.csrf.CsrfToken; +import org.springframework.security.web.csrf.DefaultCsrfToken; +import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository; +import org.springframework.security.web.header.HeaderWriterFilter; +import org.springframework.security.web.savedrequest.RequestCacheAwareFilter; +import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter; +import org.springframework.security.web.session.SessionManagementFilter; +import org.springframework.security.web.util.matcher.AnyRequestMatcher; + +import javax.servlet.Filter; +import javax.servlet.ServletException; +import java.io.IOException; +import java.util.List; +import java.util.stream.Collectors; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Rob Winch + * @author Konstantin Volivach + */ +public class DefaultFiltersTests { + + @Rule + public final SpringTestRule spring = new SpringTestRule(); + + @Test + public void defaultTheWebSecurityConfigurerAdapter() { + this.spring.register(FilterChainProxyBuilderMissingConfig.class); + assertThat(this.spring.getContext().getBean(FilterChainProxy.class)).isNotNull(); + } + + @EnableWebSecurity + static class FilterChainProxyBuilderMissingConfig { + @Autowired + public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { + auth + .inMemoryAuthentication() + .withUser("user").password("password").roles("USER"); + } + } + + @Test + public void nullWebInvocationPrivilegeEvaluator() { + this.spring.register(NullWebInvocationPrivilegeEvaluatorConfig.class, UserDetailsServiceConfig.class); + List filterChains = this.spring.getContext().getBean(FilterChainProxy.class).getFilterChains(); + assertThat(filterChains.size()).isEqualTo(1); + DefaultSecurityFilterChain filterChain = (DefaultSecurityFilterChain) filterChains.get(0); + assertThat(filterChain.getRequestMatcher()).isInstanceOf(AnyRequestMatcher.class); + assertThat(filterChain.getFilters().size()).isEqualTo(1); + long filter = filterChain.getFilters().stream() + .filter(it -> it instanceof UsernamePasswordAuthenticationFilter).count(); + assertThat(filter).isEqualTo(1); + } + + @Configuration + static class UserDetailsServiceConfig { + @Bean + public UserDetailsService userDetailsService() { + return new InMemoryUserDetailsManager(PasswordEncodedUser.user(), PasswordEncodedUser.admin()); + } + } + + @EnableWebSecurity + static class NullWebInvocationPrivilegeEvaluatorConfig extends WebSecurityConfigurerAdapter { + NullWebInvocationPrivilegeEvaluatorConfig() { + super(true); + } + + protected void configure(HttpSecurity http) throws Exception { + http.formLogin(); + } + } + + @Test + public void filterChainProxyBuilderIgnoringResources() { + this.spring.register(FilterChainProxyBuilderIgnoringConfig.class, UserDetailsServiceConfig.class); + List filterChains = this.spring.getContext().getBean(FilterChainProxy.class).getFilterChains(); + assertThat(filterChains.size()).isEqualTo(2); + DefaultSecurityFilterChain firstFilter = (DefaultSecurityFilterChain) filterChains.get(0); + DefaultSecurityFilterChain secondFilter = (DefaultSecurityFilterChain) filterChains.get(1); + + assertThat(firstFilter.getFilters().isEmpty()).isEqualTo(true); + assertThat(secondFilter.getRequestMatcher()).isInstanceOf(AnyRequestMatcher.class); + + List> classes = secondFilter.getFilters().stream().map(Filter::getClass) + .collect(Collectors.toList()); + assertThat(classes.contains(WebAsyncManagerIntegrationFilter.class)).isTrue(); + assertThat(classes.contains(SecurityContextPersistenceFilter.class)).isTrue(); + assertThat(classes.contains(HeaderWriterFilter.class)).isTrue(); + assertThat(classes.contains(LogoutFilter.class)).isTrue(); + assertThat(classes.contains(CsrfFilter.class)).isTrue(); + assertThat(classes.contains(RequestCacheAwareFilter.class)).isTrue(); + assertThat(classes.contains(SecurityContextHolderAwareRequestFilter.class)).isTrue(); + assertThat(classes.contains(AnonymousAuthenticationFilter.class)).isTrue(); + assertThat(classes.contains(SessionManagementFilter.class)).isTrue(); + assertThat(classes.contains(ExceptionTranslationFilter.class)).isTrue(); + assertThat(classes.contains(FilterSecurityInterceptor.class)).isTrue(); + } + + @EnableWebSecurity + static class FilterChainProxyBuilderIgnoringConfig extends WebSecurityConfigurerAdapter { + @Override + public void configure(WebSecurity builder) throws Exception { + builder + .ignoring() + .antMatchers("/resources/**"); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .authorizeRequests() + .anyRequest().hasRole("USER"); + } + } + + @Test + public void defaultFiltersPermitAll() throws IOException, ServletException { + this.spring.register(DefaultFiltersConfigPermitAll.class, UserDetailsServiceConfig.class); + MockHttpServletResponse response = new MockHttpServletResponse(); + MockHttpServletRequest request = new MockHttpServletRequest("POST", ""); + request.setServletPath("/logout"); + + CsrfToken csrfToken = new DefaultCsrfToken("X-CSRF-TOKEN", "_csrf", "BaseSpringSpec_CSRFTOKEN"); + new HttpSessionCsrfTokenRepository().saveToken(csrfToken, request, response); + request.setParameter(csrfToken.getParameterName(), csrfToken.getToken()); + + this.spring.getContext().getBean("springSecurityFilterChain", Filter.class).doFilter(request, response, + new MockFilterChain()); + assertThat(response.getRedirectedUrl()).isEqualTo("/login?logout"); + } + + @EnableWebSecurity + static class DefaultFiltersConfigPermitAll extends WebSecurityConfigurerAdapter { + protected void configure(HttpSecurity http) { + } + } +} diff --git a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/Issue55Tests.java b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/Issue55Tests.java new file mode 100644 index 0000000000..26acf4ea25 --- /dev/null +++ b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/Issue55Tests.java @@ -0,0 +1,159 @@ +/* + * 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.web.configurers; + +import org.junit.Rule; +import org.junit.Test; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.TestingAuthenticationToken; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +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.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.FilterChainProxy; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.access.intercept.FilterSecurityInterceptor; +import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; +import org.springframework.stereotype.Component; + +import javax.servlet.Filter; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.List; + +import static org.assertj.core.api.Java6Assertions.assertThat; + +/** + * @author Rob Winch + * @author Konstantin Volivach + */ +public class Issue55Tests { + + @Rule + public final SpringTestRule spring = new SpringTestRule(); + + @Test + public void webSecurityConfigurerAdapterDefaultToAutowired() { + TestingAuthenticationToken token = new TestingAuthenticationToken("test", "this"); + this.spring.register(WebSecurityConfigurerAdapterDefaultsAuthManagerConfig.class); + this.spring.getContext().getBean(FilterChainProxy.class); + + FilterSecurityInterceptor filter = (FilterSecurityInterceptor) findFilter(FilterSecurityInterceptor.class, 0); + assertThat(filter.getAuthenticationManager().authenticate(token)).isEqualTo(CustomAuthenticationManager.RESULT); + } + + + @EnableWebSecurity + static class WebSecurityConfigurerAdapterDefaultsAuthManagerConfig { + @Component + public static class WebSecurityAdapter extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .authorizeRequests() + .anyRequest().hasRole("USER"); + } + } + + @Configuration + public static class AuthenticationManagerConfiguration { + @Bean + public AuthenticationManager authenticationManager() throws Exception { + return new CustomAuthenticationManager(); + } + } + } + + @Test + public void multiHttpWebSecurityConfigurerAdapterDefaultsToAutowired() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { + TestingAuthenticationToken token = new TestingAuthenticationToken("test", "this"); + this.spring.register(MultiWebSecurityConfigurerAdapterDefaultsAuthManagerConfig.class); + this.spring.getContext().getBean(FilterChainProxy.class); + + FilterSecurityInterceptor filter = (FilterSecurityInterceptor) findFilter(FilterSecurityInterceptor.class, 0); + assertThat(filter.getAuthenticationManager().authenticate(token)).isEqualTo(CustomAuthenticationManager.RESULT); + + FilterSecurityInterceptor secondFilter = (FilterSecurityInterceptor) findFilter(FilterSecurityInterceptor.class, 1); + assertThat(secondFilter.getAuthenticationManager().authenticate(token)).isEqualTo(CustomAuthenticationManager.RESULT); + } + + private AuthenticationManager getAuthManager(AbstractAuthenticationProcessingFilter filter) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { + final Method getAuthenticationManager = filter.getClass().getDeclaredMethod("getAuthenticationManager"); + getAuthenticationManager.setAccessible(true); + return (AuthenticationManager) getAuthenticationManager.invoke(filter); + } + + @EnableWebSecurity + static class MultiWebSecurityConfigurerAdapterDefaultsAuthManagerConfig { + @Component + @Order(1) + public static class ApiWebSecurityAdapter extends WebSecurityConfigurerAdapter { + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .antMatcher("/api/**") + .authorizeRequests() + .anyRequest().hasRole("USER"); + } + } + + @Component + public static class WebSecurityAdapter extends WebSecurityConfigurerAdapter { + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .authorizeRequests() + .anyRequest().hasRole("USER"); + } + } + + @Configuration + public static class AuthenticationManagerConfiguration { + @Bean + public AuthenticationManager authenticationManager() throws Exception { + return new CustomAuthenticationManager(); + } + } + } + + static class CustomAuthenticationManager implements AuthenticationManager { + static Authentication RESULT = new TestingAuthenticationToken("test", "this", "ROLE_USER"); + + public Authentication authenticate(Authentication authentication) throws AuthenticationException { + return RESULT; + } + } + + protected Filter findFilter(Class filter, int index) { + List filters = filterChain(index).getFilters(); + for (Filter it : filters) { + if (filter.isAssignableFrom(it.getClass())) { + return it; + } + } + return null; + } + + SecurityFilterChain filterChain(int index) { + return this.spring.getContext().getBean(FilterChainProxy.class).getFilterChains().get(index); + } +}