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
This commit is contained in:
Dave Syer 2014-06-04 19:08:49 +01:00
parent 0ccbde9c90
commit 0ccfba939e
3 changed files with 35 additions and 58 deletions

View File

@ -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());

View File

@ -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);
}

View File

@ -37,7 +37,7 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter
@ComponentScan
@Controller
public class SampleWebSecureApplication extends WebMvcConfigurerAdapter {
@RequestMapping("/")
public String home(Map<String, Object> model) {
model.put("message", "Hello World");