From 0ccfba939eeaa543670a3151f4b15a7057c5fc02 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Wed, 4 Jun 2014 19:08:49 +0100 Subject: [PATCH] Switch to a matches-none filter for security.basic.enabled=false There were some residual issues to do with the changes to the implementation of security.basic.enabled=false. It was a good idea to have a filetr chain triggered by the flag being off because it smooths the way for user-defined filter chains to use the Boot AuthenticationManager (as a first step at least), but it wasn't a goog idea to add any actual secuity features to that filter. E.g. if it has HSTS then even an app like Sagan that has some secure endpoints that it manages itself and the rest is unsecured has issues because it can't accept connections over HTTP even on unsecure endpoints. TODO: find a way for security.ssl_enabled=true to apply to only the user- defined security filter (maybe not possible or worth the effort, since they can inject a SecurityProperties if they need it?). See gh-928 --- .../SpringBootWebSecurityConfiguration.java | 89 +++++++------------ .../SecurityAutoConfigurationTests.java | 2 +- .../ui/secure/SampleWebSecureApplication.java | 2 +- 3 files changed, 35 insertions(+), 58 deletions(-) diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/SpringBootWebSecurityConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/SpringBootWebSecurityConfiguration.java index 1dee19c157..b97c8b83a7 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/SpringBootWebSecurityConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/SpringBootWebSecurityConfiguration.java @@ -20,6 +20,8 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import javax.servlet.http.HttpServletRequest; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; @@ -47,6 +49,7 @@ import org.springframework.security.web.AuthenticationEntryPoint; import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint; import org.springframework.security.web.header.writers.HstsHeaderWriter; import org.springframework.security.web.util.matcher.AnyRequestMatcher; +import org.springframework.security.web.util.matcher.RequestMatcher; import org.springframework.web.servlet.support.RequestDataValueProcessor; /** @@ -173,11 +176,26 @@ public class SpringBootWebSecurityConfiguration { } - /** - * Basic functionality for all web apps (whether or not we are providing basic auth). - * @author Dave Syer - */ - private static class BaseApplicationWebSecurityConfigurerAdapter extends + @ConditionalOnExpression("!${security.basic.enabled:true}") + @Configuration + @Order(SecurityProperties.BASIC_AUTH_ORDER) + protected static class ApplicationNoWebSecurityConfigurerAdapter extends + WebSecurityConfigurerAdapter { + @Override + protected void configure(HttpSecurity http) throws Exception { + http.requestMatcher(new RequestMatcher() { + @Override + public boolean matches(HttpServletRequest request) { + return false; + } + }); + } + } + + @ConditionalOnExpression("${security.basic.enabled:true}") + @Configuration + @Order(SecurityProperties.BASIC_AUTH_ORDER) + protected static class ApplicationWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter { @Autowired @@ -200,7 +218,16 @@ public class SpringBootWebSecurityConfiguration { this.security.getHeaders()); String[] paths = getSecureApplicationPaths(); - configureAdditionalRules(http, paths); + + if (paths.length > 0) { + http.exceptionHandling().authenticationEntryPoint(entryPoint()); + http.httpBasic(); + http.requestMatchers().antMatchers(paths); + http.authorizeRequests() + .anyRequest() + .hasAnyRole( + this.security.getUser().getRole().toArray(new String[0])); + } } @@ -218,56 +245,6 @@ public class SpringBootWebSecurityConfiguration { return list.toArray(new String[list.size()]); } - protected void configureAdditionalRules(HttpSecurity http, String... paths) - throws Exception { - } - - } - - @ConditionalOnExpression("!${security.basic.enabled:true}") - @Configuration - @Order(SecurityProperties.BASIC_AUTH_ORDER) - protected static class ApplicationNoWebSecurityConfigurerAdapter extends - BaseApplicationWebSecurityConfigurerAdapter { - @Override - protected void configureAdditionalRules(HttpSecurity http, String... paths) - throws Exception { - - if (paths.length > 0) { - http.requestMatchers().antMatchers(paths); - // The basic security was disabled - http.authorizeRequests().anyRequest().permitAll(); - } - - } - - } - - @ConditionalOnExpression("${security.basic.enabled:true}") - @Configuration - @Order(SecurityProperties.BASIC_AUTH_ORDER) - protected static class ApplicationWebSecurityConfigurerAdapter extends - BaseApplicationWebSecurityConfigurerAdapter { - - @Autowired - private SecurityProperties security; - - @Override - protected void configureAdditionalRules(HttpSecurity http, String... paths) - throws Exception { - - if (paths.length > 0) { - http.exceptionHandling().authenticationEntryPoint(entryPoint()); - http.httpBasic(); - http.requestMatchers().antMatchers(paths); - http.authorizeRequests() - .anyRequest() - .hasAnyRole( - this.security.getUser().getRole().toArray(new String[0])); - } - - } - private AuthenticationEntryPoint entryPoint() { BasicAuthenticationEntryPoint entryPoint = new BasicAuthenticationEntryPoint(); entryPoint.setRealmName(this.security.getBasic().getRealm()); 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 1daca280d2..10c31b4e8b 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 @@ -89,7 +89,7 @@ public class SecurityAutoConfigurationTests { PropertyPlaceholderAutoConfiguration.class); EnvironmentTestUtils.addEnvironment(this.context, "security.basic.enabled:false"); this.context.refresh(); - // Ignores and permitAll() security on application endpoints + // Ignores and the "matches-none" filter only assertEquals(1, this.context.getBeanNamesForType(FilterChainProxy.class).length); } diff --git a/spring-boot-samples/spring-boot-sample-web-secure/src/main/java/sample/ui/secure/SampleWebSecureApplication.java b/spring-boot-samples/spring-boot-sample-web-secure/src/main/java/sample/ui/secure/SampleWebSecureApplication.java index b8580aed93..410e68ce48 100644 --- a/spring-boot-samples/spring-boot-sample-web-secure/src/main/java/sample/ui/secure/SampleWebSecureApplication.java +++ b/spring-boot-samples/spring-boot-sample-web-secure/src/main/java/sample/ui/secure/SampleWebSecureApplication.java @@ -37,7 +37,7 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter @ComponentScan @Controller public class SampleWebSecureApplication extends WebMvcConfigurerAdapter { - + @RequestMapping("/") public String home(Map model) { model.put("message", "Hello World");