From ecee19057c8172309302f821d682cffb1967a379 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Wed, 15 Oct 2014 11:31:35 +0100 Subject: [PATCH] Add some precautionary tests for documenting AuthenticationManager config --- .../SecurityAutoConfigurationTests.java | 27 ++-- ...ringBootWebSecurityConfigurationTests.java | 115 +++++++++++++++++- 2 files changed, 131 insertions(+), 11 deletions(-) diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/SecurityAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/SecurityAutoConfigurationTests.java index 85a68b051b4..6429d46485d 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/SecurityAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/SecurityAutoConfigurationTests.java @@ -16,9 +16,15 @@ package org.springframework.boot.autoconfigure.security; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + import java.util.List; import java.util.concurrent.atomic.AtomicReference; +import org.junit.After; import org.junit.Test; import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration; import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage; @@ -45,11 +51,6 @@ import org.springframework.security.web.FilterChainProxy; import org.springframework.security.web.SecurityFilterChain; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - /** * Tests for {@link SecurityAutoConfiguration}. * @@ -59,6 +60,13 @@ public class SecurityAutoConfigurationTests { private AnnotationConfigWebApplicationContext context; + @After + public void close() { + if (context != null) { + context.close(); + } + } + @Test public void testWebConfiguration() throws Exception { this.context = new AnnotationConfigWebApplicationContext(); @@ -137,11 +145,12 @@ public class SecurityAutoConfigurationTests { public void testOverrideAuthenticationManager() throws Exception { this.context = new AnnotationConfigWebApplicationContext(); this.context.setServletContext(new MockServletContext()); - this.context.register(TestConfiguration.class, SecurityAutoConfiguration.class, - ServerPropertiesAutoConfiguration.class, + this.context.register(TestAuthenticationConfiguration.class, + SecurityAutoConfiguration.class, ServerPropertiesAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class); this.context.refresh(); - assertEquals(this.context.getBean(TestConfiguration.class).authenticationManager, + assertEquals( + this.context.getBean(TestAuthenticationConfiguration.class).authenticationManager, this.context.getBean(AuthenticationManager.class)); } @@ -168,7 +177,7 @@ public class SecurityAutoConfigurationTests { } @Configuration - protected static class TestConfiguration { + protected static class TestAuthenticationConfiguration { private AuthenticationManager authenticationManager; diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/SpringBootWebSecurityConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/SpringBootWebSecurityConfigurationTests.java index 4a1dabe3bc3..d9ac6b13a52 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/SpringBootWebSecurityConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/SpringBootWebSecurityConfigurationTests.java @@ -16,10 +16,38 @@ package org.springframework.boot.autoconfigure.security; -import org.junit.Test; - +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.junit.After; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration; +import org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration; +import org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration; +import org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration; +import org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration; +import org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfiguration; +import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration; +import org.springframework.context.ConfigurableApplicationContext; +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.authentication.AuthenticationManager; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +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.WebSecurityConfigurerAdapter; + /** * Tests for {@link SpringBootWebSecurityConfiguration}. * @@ -27,10 +55,93 @@ import static org.junit.Assert.assertTrue; */ public class SpringBootWebSecurityConfigurationTests { + private ConfigurableApplicationContext context; + + @After + public void close() { + if (context != null) { + context.close(); + } + } + @Test public void testDefaultIgnores() { assertTrue(SpringBootWebSecurityConfiguration .getIgnored(new SecurityProperties()).contains("/css/**")); } + @Test + public void testWebConfigurationOverrideGlobalAuthentication() throws Exception { + this.context = SpringApplication.run(TestWebConfiguration.class, + "--server.port=0", "--debug"); + assertNotNull(this.context.getBean(AuthenticationManagerBuilder.class)); + assertNotNull(this.context.getBean(AuthenticationManager.class).authenticate( + new UsernamePasswordAuthenticationToken("dave", "secret"))); + } + + @Test + public void testWebConfigurationInjectGlobalAuthentication() throws Exception { + this.context = SpringApplication.run(TestInjectWebConfiguration.class, + "--server.port=0", "--debug"); + assertNotNull(this.context.getBean(AuthenticationManagerBuilder.class)); + assertNotNull(this.context.getBean(AuthenticationManager.class).authenticate( + new UsernamePasswordAuthenticationToken("dave", "secret"))); + } + + @Configuration + @Import(TestWebConfiguration.class) + @Order(Ordered.LOWEST_PRECEDENCE) + protected static class TestInjectWebConfiguration extends + WebSecurityConfigurerAdapter { + + // It's a bad idea to inject an AuthenticationManager into a + // WebSecurityConfigurerAdapter because it can cascade early instantiation, + // unless you explicitly want the Boot default AuthenticationManager. It's + // better to inject the builder, if you want the global AuthenticationManager. It + // might even be necessary to wrap the builder in a lazy AuthenticationManager + // (that calls getOrBuild() only when the AuthenticationManager is actually + // called). + @Autowired + private AuthenticationManagerBuilder auth; + + @Override + public void init(WebSecurity web) throws Exception { + auth.getOrBuild(); + } + } + + @MinimalWebConfiguration + @Import(SecurityAutoConfiguration.class) + @Order(Ordered.HIGHEST_PRECEDENCE + 10) + protected static class TestWebConfiguration extends WebSecurityConfigurerAdapter { + + @Autowired + public void init(AuthenticationManagerBuilder auth) throws Exception { + // @formatter:off + auth.inMemoryAuthentication() + .withUser("dave") + .password("secret") + .roles("USER"); + // @formatter:on + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.authorizeRequests().anyRequest().denyAll(); + } + + } + + @Configuration + @Target(ElementType.TYPE) + @Retention(RetentionPolicy.RUNTIME) + @Documented + @Import({ EmbeddedServletContainerAutoConfiguration.class, + ServerPropertiesAutoConfiguration.class, + DispatcherServletAutoConfiguration.class, WebMvcAutoConfiguration.class, + HttpMessageConvertersAutoConfiguration.class, + ErrorMvcAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class }) + protected static @interface MinimalWebConfiguration { + } + }