From 2ba01008bb9aedc25bff8a2f31b798b2de2cb946 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Wed, 4 Sep 2013 18:07:15 +0100 Subject: [PATCH] Add headers external properties for security filters --- .../SecurityAutoConfiguration.java | 37 ++++++++- .../properties/SecurityProperties.java | 75 +++++++++++++++++++ 2 files changed, 110 insertions(+), 2 deletions(-) diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/SecurityAutoConfiguration.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/SecurityAutoConfiguration.java index 9d0712760a9..e8d39331877 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/SecurityAutoConfiguration.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/SecurityAutoConfiguration.java @@ -29,6 +29,7 @@ import org.springframework.boot.actuate.endpoint.Endpoint; import org.springframework.boot.actuate.endpoint.mvc.EndpointHandlerMapping; import org.springframework.boot.actuate.properties.ManagementServerProperties; import org.springframework.boot.actuate.properties.SecurityProperties; +import org.springframework.boot.actuate.properties.SecurityProperties.Headers; import org.springframework.boot.actuate.properties.SecurityProperties.User; import org.springframework.boot.actuate.web.ErrorController; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -52,8 +53,11 @@ import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.builders.WebSecurity.IgnoredRequestConfigurer; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer; 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.AnyRequestMatcher; /** * {@link EnableAutoConfiguration Auto-configuration} for security of a web application or @@ -149,11 +153,15 @@ public class SecurityAutoConfiguration { .and().httpBasic() // .and().anonymous().disable(); } - // Remove this when session creation is disabled by default - http.csrf().disable(); + if (!this.security.isEnableCsrf()) { + http.csrf().disable(); + } // No cookies for application endpoints by default http.sessionManagement().sessionCreationPolicy(this.security.getSessions()); + SecurityAutoConfiguration.configureHeaders(http.headers(), + this.security.getHeaders()); + } private String[] getSecureApplicationPaths() { @@ -234,6 +242,9 @@ public class SecurityAutoConfiguration { http.sessionManagement().sessionCreationPolicy( this.security.getManagement().getSessions()); + SecurityAutoConfiguration.configureHeaders(http.headers(), + this.security.getHeaders()); + } @Override @@ -299,4 +310,26 @@ public class SecurityAutoConfiguration { } + private static void configureHeaders(HeadersConfigurer configurer, + SecurityProperties.Headers headers) throws Exception { + if (headers.getHsts() != Headers.HSTS.none) { + boolean includeSubdomains = headers.getHsts() == Headers.HSTS.all; + HstsHeaderWriter writer = new HstsHeaderWriter(includeSubdomains); + writer.setRequestMatcher(new AnyRequestMatcher()); + configurer.addHeaderWriter(writer); + } + if (headers.isContentType()) { + configurer.contentTypeOptions(); + } + if (headers.isXss()) { + configurer.xssProtection(); + } + if (headers.isCache()) { + configurer.cacheControl(); + } + if (headers.isFrame()) { + configurer.frameOptions(); + } + } + } diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/properties/SecurityProperties.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/properties/SecurityProperties.java index dedf02532ad..4b84a2a92a1 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/properties/SecurityProperties.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/properties/SecurityProperties.java @@ -32,8 +32,13 @@ public class SecurityProperties { private boolean requireSsl; + // Flip this when session creation is disabled by default + private boolean enableCsrf = false; + private Basic basic = new Basic(); + private Headers headers = new Headers(); + private SessionCreationPolicy sessions = SessionCreationPolicy.STATELESS; private String[] ignored = new String[] { "/css/**", "/js/**", "/images/**", @@ -43,6 +48,10 @@ public class SecurityProperties { private User user = new User(); + public Headers getHeaders() { + return this.headers; + } + public User getUser() { return this.user; } @@ -75,6 +84,14 @@ public class SecurityProperties { this.requireSsl = requireSsl; } + public boolean isEnableCsrf() { + return this.enableCsrf; + } + + public void setEnableCsrf(boolean enableCsrf) { + this.enableCsrf = enableCsrf; + } + public void setIgnored(String... ignored) { this.ignored = ignored; } @@ -83,6 +100,64 @@ public class SecurityProperties { return this.ignored; } + public static class Headers { + + public static enum HSTS { + none, domain, all + } + + private boolean xss; + + private boolean cache; + + private boolean frame; + + private boolean contentType; + + private HSTS hsts = HSTS.all; + + public boolean isXss() { + return this.xss; + } + + public void setXss(boolean xss) { + this.xss = xss; + } + + public boolean isCache() { + return this.cache; + } + + public void setCache(boolean cache) { + this.cache = cache; + } + + public boolean isFrame() { + return this.frame; + } + + public void setFrame(boolean frame) { + this.frame = frame; + } + + public boolean isContentType() { + return this.contentType; + } + + public void setContentType(boolean contentType) { + this.contentType = contentType; + } + + public HSTS getHsts() { + return this.hsts; + } + + public void setHsts(HSTS hsts) { + this.hsts = hsts; + } + + } + public static class Basic { private boolean enabled = true;