From 8622e5db20bf7afb839b4b6550750426ed92e7b6 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 19 Feb 2015 10:32:41 +0000 Subject: [PATCH] Apply f9816ea and 64e94f3 to 1.1.x Fixes gh-2473 --- ...BootGlobalAuthenticationConfiguration.java | 77 +++++++++++++++++++ .../security/SecurityAutoConfiguration.java | 5 +- spring-boot-full-build/pom.xml | 1 + spring-boot-security-tests/pom.xml | 22 ++++++ .../pom.xml | 35 +++++++++ .../sample/HelloWebSecurityApplication.java | 39 ++++++++++ .../HelloWebSecurityApplicationTests.java | 77 +++++++++++++++++++ 7 files changed, 254 insertions(+), 2 deletions(-) create mode 100644 spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/BootGlobalAuthenticationConfiguration.java create mode 100644 spring-boot-security-tests/pom.xml create mode 100644 spring-boot-security-tests/spring-boot-security-tests-web-helloworld/pom.xml create mode 100644 spring-boot-security-tests/spring-boot-security-tests-web-helloworld/src/main/java/sample/HelloWebSecurityApplication.java create mode 100644 spring-boot-security-tests/spring-boot-security-tests-web-helloworld/src/test/java/sample/HelloWebSecurityApplicationTests.java diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/BootGlobalAuthenticationConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/BootGlobalAuthenticationConfiguration.java new file mode 100644 index 0000000000..f27245b7f5 --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/BootGlobalAuthenticationConfiguration.java @@ -0,0 +1,77 @@ +/* + * Copyright 2012-2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.boot.autoconfigure.security; + +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; +import org.springframework.security.config.annotation.authentication.configurers.GlobalAuthenticationConfigurerAdapter; + +/** + * This works with the {@link AuthenticationConfiguration} to ensure that users are able + * to use: + * + *
+ * public void configureGlobal(AuthenticationManagerBuilder auth) {
+ *     ...
+ * }
+ * 
+ * + * within their classes annotated with {@link EnableAutoConfiguration}. + * + * @author Rob Winch + * @since 1.1.11 + */ +@Configuration +@ConditionalOnClass(GlobalAuthenticationConfigurerAdapter.class) +public class BootGlobalAuthenticationConfiguration { + + @Bean + public static BootGlobalAuthenticationConfigurationAdapter bootGlobalAuthenticationConfigurationAdapter( + ApplicationContext context) { + return new BootGlobalAuthenticationConfigurationAdapter(context); + } + + private static class BootGlobalAuthenticationConfigurationAdapter extends + GlobalAuthenticationConfigurerAdapter { + + private static Log logger = LogFactory + .getLog(BootGlobalAuthenticationConfiguration.class); + + private final ApplicationContext context; + + public BootGlobalAuthenticationConfigurationAdapter(ApplicationContext context) { + this.context = context; + } + + @Override + public void init(AuthenticationManagerBuilder auth) { + Map beansWithAnnotation = this.context + .getBeansWithAnnotation(EnableAutoConfiguration.class); + if (logger.isDebugEnabled()) { + logger.debug("Eagerly initializing " + beansWithAnnotation); + } + } + } +} diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/SecurityAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/SecurityAutoConfiguration.java index aa462f3bf0..b30ed98fa3 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/SecurityAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/SecurityAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2014 the original author or authors. + * Copyright 2012-2015 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. @@ -49,7 +49,8 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur GlobalAuthenticationConfigurerAdapter.class }) @EnableConfigurationProperties @Import({ SpringBootWebSecurityConfiguration.class, - AuthenticationManagerConfiguration.class }) + AuthenticationManagerConfiguration.class, + BootGlobalAuthenticationConfiguration.class }) public class SecurityAutoConfiguration { @Bean diff --git a/spring-boot-full-build/pom.xml b/spring-boot-full-build/pom.xml index 2ac52747d3..efd5bd098b 100644 --- a/spring-boot-full-build/pom.xml +++ b/spring-boot-full-build/pom.xml @@ -56,6 +56,7 @@ ../spring-boot-cli ../spring-boot-samples ../spring-boot-integration-tests + ../spring-boot-security-tests ../spring-boot-docs diff --git a/spring-boot-security-tests/pom.xml b/spring-boot-security-tests/pom.xml new file mode 100644 index 0000000000..ce335a6228 --- /dev/null +++ b/spring-boot-security-tests/pom.xml @@ -0,0 +1,22 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-parent + 1.1.11.BUILD-SNAPSHOT + ../spring-boot-parent + + spring-boot-security-tests + pom + Spring Boot Security Tests + ${project.name} + http://projects.spring.io/spring-boot/ + + Pivotal Software, Inc. + http://www.spring.io + + + spring-boot-security-tests-web-helloworld + + diff --git a/spring-boot-security-tests/spring-boot-security-tests-web-helloworld/pom.xml b/spring-boot-security-tests/spring-boot-security-tests-web-helloworld/pom.xml new file mode 100644 index 0000000000..81d38d0825 --- /dev/null +++ b/spring-boot-security-tests/spring-boot-security-tests-web-helloworld/pom.xml @@ -0,0 +1,35 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-security-tests + 1.1.11.BUILD-SNAPSHOT + ../ + + spring-boot-security-tests-web-helloworld + Spring Boot Security Tests - Web Hello World + ${project.name} + http://projects.spring.io/spring-boot/ + + Pivotal Software, Inc. + http://www.spring.io + + + ${basedir}/../.. + + + + org.springframework.boot + spring-boot-starter + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-security + + + diff --git a/spring-boot-security-tests/spring-boot-security-tests-web-helloworld/src/main/java/sample/HelloWebSecurityApplication.java b/spring-boot-security-tests/spring-boot-security-tests-web-helloworld/src/main/java/sample/HelloWebSecurityApplication.java new file mode 100644 index 0000000000..d14af0eef1 --- /dev/null +++ b/spring-boot-security-tests/spring-boot-security-tests-web-helloworld/src/main/java/sample/HelloWebSecurityApplication.java @@ -0,0 +1,39 @@ +/* + * Copyright 2012-2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sample; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; + +@EnableAutoConfiguration +@ComponentScan +@Configuration +public class HelloWebSecurityApplication { + + @Autowired + public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { + auth.inMemoryAuthentication().withUser("user").password("password").roles("USER"); + } + + public static void main(String[] args) { + SpringApplication.run(HelloWebSecurityApplication.class, args); + } +} \ No newline at end of file diff --git a/spring-boot-security-tests/spring-boot-security-tests-web-helloworld/src/test/java/sample/HelloWebSecurityApplicationTests.java b/spring-boot-security-tests/spring-boot-security-tests-web-helloworld/src/test/java/sample/HelloWebSecurityApplicationTests.java new file mode 100644 index 0000000000..c7a77f0c08 --- /dev/null +++ b/spring-boot-security-tests/spring-boot-security-tests-web-helloworld/src/test/java/sample/HelloWebSecurityApplicationTests.java @@ -0,0 +1,77 @@ +/* + * Copyright 2012-2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sample; + +import javax.servlet.http.HttpServletResponse; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.IntegrationTest; +import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.mock.web.MockFilterChain; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.security.crypto.codec.Base64; +import org.springframework.security.web.FilterChainProxy; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; + +import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assert.assertThat; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes = HelloWebSecurityApplication.class) +@IntegrationTest("server.port:0") +@WebAppConfiguration +public class HelloWebSecurityApplicationTests { + + @Autowired + private FilterChainProxy springSecurityFilterChain; + + private MockHttpServletRequest request; + + private MockHttpServletResponse response; + + private MockFilterChain chain; + + @Before + public void setup() { + this.request = new MockHttpServletRequest(); + this.response = new MockHttpServletResponse(); + this.chain = new MockFilterChain(); + } + + @Test + public void requiresAuthentication() throws Exception { + this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain); + + assertThat(this.response.getStatus(), + equalTo(HttpServletResponse.SC_UNAUTHORIZED)); + } + + @Test + public void userAuthenticates() throws Exception { + this.request.addHeader("Authorization", + "Basic " + new String(Base64.encode("user:password".getBytes("UTF-8")))); + + this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain); + + assertThat(this.response.getStatus(), equalTo(HttpServletResponse.SC_OK)); + } +}