diff --git a/config/src/main/java/org/springframework/security/config/web/server/ServerHttpSecurity.java b/config/src/main/java/org/springframework/security/config/web/server/ServerHttpSecurity.java index 00daeb7761..4fe1a02f4a 100644 --- a/config/src/main/java/org/springframework/security/config/web/server/ServerHttpSecurity.java +++ b/config/src/main/java/org/springframework/security/config/web/server/ServerHttpSecurity.java @@ -644,6 +644,11 @@ public class ServerHttpSecurity { return ServerHttpSecurity.this; } + public ServerHttpSecurity disable() { + ServerHttpSecurity.this.headers = null; + return ServerHttpSecurity.this; + } + public CacheSpec cache() { return new CacheSpec(); } @@ -671,27 +676,36 @@ public class ServerHttpSecurity { } public class CacheSpec { - public void disable() { + public HeaderSpec disable() { HeaderSpec.this.writers.remove(HeaderSpec.this.cacheControl); + return HeaderSpec.this; } private CacheSpec() {} } public class ContentTypeOptionsSpec { - public void disable() { + public HeaderSpec disable() { HeaderSpec.this.writers.remove(HeaderSpec.this.contentTypeOptions); + return HeaderSpec.this; } private ContentTypeOptionsSpec() {} } public class FrameOptionsSpec { - public void mode(XFrameOptionsServerHttpHeadersWriter.Mode mode) { + public FrameOptionsSpec mode(XFrameOptionsServerHttpHeadersWriter.Mode mode) { HeaderSpec.this.frameOptions.setMode(mode); + return this; } - public void disable() { + + public HeaderSpec and() { + return HeaderSpec.this; + } + + public HeaderSpec disable() { HeaderSpec.this.writers.remove(HeaderSpec.this.frameOptions); + return HeaderSpec.this; } private FrameOptionsSpec() {} @@ -706,16 +720,22 @@ public class ServerHttpSecurity { HeaderSpec.this.hsts.setIncludeSubDomains(includeSubDomains); } - public void disable() { + public HeaderSpec and() { + return HeaderSpec.this; + } + + public HeaderSpec disable() { HeaderSpec.this.writers.remove(HeaderSpec.this.hsts); + return HeaderSpec.this; } private HstsSpec() {} } public class XssProtectionSpec { - public void disable() { + public HeaderSpec disable() { HeaderSpec.this.writers.remove(HeaderSpec.this.xss); + return HeaderSpec.this; } private XssProtectionSpec() {} diff --git a/config/src/test/java/org/springframework/security/config/web/server/HeaderSpecTests.java b/config/src/test/java/org/springframework/security/config/web/server/HeaderSpecTests.java index faafc01871..562542477b 100644 --- a/config/src/test/java/org/springframework/security/config/web/server/HeaderSpecTests.java +++ b/config/src/test/java/org/springframework/security/config/web/server/HeaderSpecTests.java @@ -60,6 +60,23 @@ public class HeaderSpecTests { .add(XXssProtectionServerHttpHeadersWriter.X_XSS_PROTECTION, "1 ; mode=block"); } + @Test + public void headersWhenDisableThenNoSecurityHeaders() { + new HashSet<>(this.expectedHeaders.keySet()).forEach(this::expectHeaderNamesNotPresent); + + this.headers.disable(); + + assertHeaders(); + } + + @Test + public void headersWhenDisableAndInvokedExplicitlyThenDefautsUsed() { + this.headers.disable() + .headers(); + + assertHeaders(); + } + @Test public void headersWhenDefaultsThenAllDefaultsWritten() { assertHeaders(); @@ -110,7 +127,9 @@ public class HeaderSpecTests { @Test public void headersWhenFrameOptionsModeThenFrameOptionsCustomMode() { this.expectedHeaders.set(XFrameOptionsServerHttpHeadersWriter.X_FRAME_OPTIONS, "SAMEORIGIN"); - this.headers.frameOptions().mode(XFrameOptionsServerHttpHeadersWriter.Mode.SAMEORIGIN); + this.headers + .frameOptions() + .mode(XFrameOptionsServerHttpHeadersWriter.Mode.SAMEORIGIN); assertHeaders(); } @@ -139,8 +158,10 @@ public class HeaderSpecTests { Map> responseHeaders = response.getResponseHeaders(); - assertThat(responseHeaders).describedAs(response.toString()).containsAllEntriesOf( - this.expectedHeaders); + if (!this.expectedHeaders.isEmpty()) { + assertThat(responseHeaders).describedAs(response.toString()) + .containsAllEntriesOf(this.expectedHeaders); + } if (!this.headerNamesNotPresent.isEmpty()) { assertThat(responseHeaders.keySet()).doesNotContainAnyElementsOf(this.headerNamesNotPresent); }