diff --git a/config/src/main/java/org/springframework/security/config/web/server/HeaderBuilder.java b/config/src/main/java/org/springframework/security/config/web/server/HeaderBuilder.java deleted file mode 100644 index 7d61d3d203..0000000000 --- a/config/src/main/java/org/springframework/security/config/web/server/HeaderBuilder.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright 2002-2017 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.security.config.web.server; - -import org.springframework.security.web.server.header.CacheControlHttpHeadersWriter; -import org.springframework.security.web.server.header.CompositeHttpHeadersWriter; -import org.springframework.security.web.server.header.ContentTypeOptionsHttpHeadersWriter; -import org.springframework.security.web.server.header.HttpHeaderWriterWebFilter; -import org.springframework.security.web.server.header.HttpHeadersWriter; -import org.springframework.security.web.server.header.StrictTransportSecurityHttpHeadersWriter; -import org.springframework.security.web.server.header.XFrameOptionsHttpHeadersWriter; -import org.springframework.security.web.server.header.XXssProtectionHttpHeadersWriter; - -import java.time.Duration; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -/** - * @author Rob Winch - * @since 5.0 - */ -public class HeaderBuilder { - private final List writers; - - private CacheControlHttpHeadersWriter cacheControl = new CacheControlHttpHeadersWriter(); - - private ContentTypeOptionsHttpHeadersWriter contentTypeOptions = new ContentTypeOptionsHttpHeadersWriter(); - - private StrictTransportSecurityHttpHeadersWriter hsts = new StrictTransportSecurityHttpHeadersWriter(); - - private XFrameOptionsHttpHeadersWriter frameOptions = new XFrameOptionsHttpHeadersWriter(); - - private XXssProtectionHttpHeadersWriter xss = new XXssProtectionHttpHeadersWriter(); - - public HeaderBuilder() { - this.writers = new ArrayList<>(Arrays.asList(cacheControl, contentTypeOptions, hsts, frameOptions, xss)); - } - - public CacheSpec cache() { - return new CacheSpec(); - } - - public ContentTypeOptionsSpec contentTypeOptions() { - return new ContentTypeOptionsSpec(); - } - - public FrameOptionsSpec frameOptions() { - return new FrameOptionsSpec(); - } - - public HstsSpec hsts() { - return new HstsSpec(); - } - - public HttpHeaderWriterWebFilter build() { - HttpHeadersWriter writer = new CompositeHttpHeadersWriter(writers); - return new HttpHeaderWriterWebFilter(writer); - } - - public XssProtectionSpec xssProtection() { - return new XssProtectionSpec(); - } - - public class CacheSpec { - public void disable() { - writers.remove(cacheControl); - } - - private CacheSpec() {} - } - - public class ContentTypeOptionsSpec { - public void disable() { - writers.remove(contentTypeOptions); - } - - private ContentTypeOptionsSpec() {} - } - - public class FrameOptionsSpec { - public void mode(XFrameOptionsHttpHeadersWriter.Mode mode) { - frameOptions.setMode(mode); - } - public void disable() { - writers.remove(frameOptions); - } - - private FrameOptionsSpec() {} - } - - public class HstsSpec { - public void maxAge(Duration maxAge) { - hsts.setMaxAge(maxAge); - } - - public void includeSubdomains(boolean includeSubDomains) { - hsts.setIncludeSubDomains(includeSubDomains); - } - - public void disable() { - writers.remove(hsts); - } - - private HstsSpec() {} - } - - public class XssProtectionSpec { - public void disable() { - writers.remove(xss); - } - - private XssProtectionSpec() {} - } -} diff --git a/config/src/main/java/org/springframework/security/config/web/server/HttpBasicBuilder.java b/config/src/main/java/org/springframework/security/config/web/server/HttpBasicBuilder.java deleted file mode 100644 index 1439e15b03..0000000000 --- a/config/src/main/java/org/springframework/security/config/web/server/HttpBasicBuilder.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2002-2016 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.security.config.web.server; - -import org.springframework.security.authentication.ReactiveAuthenticationManager; -import org.springframework.security.web.server.AuthenticationEntryPoint; -import org.springframework.security.web.server.authentication.AuthenticationWebFilter; -import org.springframework.security.web.server.HttpBasicAuthenticationConverter; -import org.springframework.security.web.server.authentication.DefaultAuthenticationSuccessHandler; -import org.springframework.security.web.server.authentication.www.HttpBasicAuthenticationEntryPoint; -import org.springframework.security.web.server.context.SecurityContextRepository; - -/** - * @author Rob Winch - * @since 5.0 - */ -public class HttpBasicBuilder { - private ReactiveAuthenticationManager authenticationManager; - - private SecurityContextRepository securityContextRepository; - - private AuthenticationEntryPoint entryPoint = new HttpBasicAuthenticationEntryPoint(); - - public HttpBasicBuilder authenticationManager(ReactiveAuthenticationManager authenticationManager) { - this.authenticationManager = authenticationManager; - return this; - } - - public HttpBasicBuilder securityContextRepository(SecurityContextRepository securityContextRepository) { - this.securityContextRepository = securityContextRepository; - return this; - } - - public AuthenticationWebFilter build() { - AuthenticationWebFilter authenticationFilter = new AuthenticationWebFilter(authenticationManager); - authenticationFilter.setEntryPoint(entryPoint); - authenticationFilter.setAuthenticationConverter(new HttpBasicAuthenticationConverter()); - if(securityContextRepository != null) { - DefaultAuthenticationSuccessHandler handler = new DefaultAuthenticationSuccessHandler(); - handler.setSecurityContextRepository(securityContextRepository); - authenticationFilter.setAuthenticationSuccessHandler(handler); - } - return authenticationFilter; - } -} diff --git a/config/src/main/java/org/springframework/security/config/web/server/HttpSecurity.java b/config/src/main/java/org/springframework/security/config/web/server/HttpSecurity.java index 12d8125c1b..520598a23d 100644 --- a/config/src/main/java/org/springframework/security/config/web/server/HttpSecurity.java +++ b/config/src/main/java/org/springframework/security/config/web/server/HttpSecurity.java @@ -15,7 +15,9 @@ */ package org.springframework.security.config.web.server; +import java.time.Duration; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Optional; @@ -24,8 +26,13 @@ import org.springframework.security.authorization.AuthenticatedAuthorizationMana import org.springframework.security.authorization.AuthorityAuthorizationManager; import org.springframework.security.authorization.AuthorizationDecision; import org.springframework.security.authorization.ReactiveAuthorizationManager; +import org.springframework.security.web.server.AuthenticationEntryPoint; +import org.springframework.security.web.server.HttpBasicAuthenticationConverter; import org.springframework.security.web.server.MatcherSecurityWebFilterChain; import org.springframework.security.web.server.SecurityWebFilterChain; +import org.springframework.security.web.server.authentication.AuthenticationWebFilter; +import org.springframework.security.web.server.authentication.DefaultAuthenticationSuccessHandler; +import org.springframework.security.web.server.authentication.www.HttpBasicAuthenticationEntryPoint; import org.springframework.security.web.server.authorization.AuthorizationContext; import org.springframework.security.web.server.authorization.AuthorizationWebFilter; import org.springframework.security.web.server.authorization.DelegatingReactiveAuthorizationManager; @@ -33,6 +40,14 @@ import org.springframework.security.web.server.context.AuthenticationReactorCont import org.springframework.security.web.server.context.SecurityContextRepositoryWebFilter; import org.springframework.security.web.server.authorization.ExceptionTranslationWebFilter; import org.springframework.security.web.server.context.SecurityContextRepository; +import org.springframework.security.web.server.header.CacheControlHttpHeadersWriter; +import org.springframework.security.web.server.header.CompositeHttpHeadersWriter; +import org.springframework.security.web.server.header.ContentTypeOptionsHttpHeadersWriter; +import org.springframework.security.web.server.header.HttpHeaderWriterWebFilter; +import org.springframework.security.web.server.header.HttpHeadersWriter; +import org.springframework.security.web.server.header.StrictTransportSecurityHttpHeadersWriter; +import org.springframework.security.web.server.header.XFrameOptionsHttpHeadersWriter; +import org.springframework.security.web.server.header.XXssProtectionHttpHeadersWriter; import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher; import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcherEntry; import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatchers; @@ -209,4 +224,147 @@ public class HttpSecurity { } } } + + /** + * @author Rob Winch + * @since 5.0 + */ + public class HttpBasicBuilder { + private ReactiveAuthenticationManager authenticationManager; + + private SecurityContextRepository securityContextRepository; + + private AuthenticationEntryPoint entryPoint = new HttpBasicAuthenticationEntryPoint(); + + public HttpBasicBuilder authenticationManager(ReactiveAuthenticationManager authenticationManager) { + this.authenticationManager = authenticationManager; + return this; + } + + public HttpBasicBuilder securityContextRepository(SecurityContextRepository securityContextRepository) { + this.securityContextRepository = securityContextRepository; + return this; + } + + public HttpSecurity and() { + return HttpSecurity.this; + } + + protected AuthenticationWebFilter build() { + AuthenticationWebFilter authenticationFilter = new AuthenticationWebFilter(authenticationManager); + authenticationFilter.setEntryPoint(entryPoint); + authenticationFilter.setAuthenticationConverter(new HttpBasicAuthenticationConverter()); + if(securityContextRepository != null) { + DefaultAuthenticationSuccessHandler handler = new DefaultAuthenticationSuccessHandler(); + handler.setSecurityContextRepository(securityContextRepository); + authenticationFilter.setAuthenticationSuccessHandler(handler); + } + return authenticationFilter; + } + + private HttpBasicBuilder() {} + } + + /** + * @author Rob Winch + * @since 5.0 + */ + public class HeaderBuilder { + private final List writers; + + private CacheControlHttpHeadersWriter cacheControl = new CacheControlHttpHeadersWriter(); + + private ContentTypeOptionsHttpHeadersWriter contentTypeOptions = new ContentTypeOptionsHttpHeadersWriter(); + + private StrictTransportSecurityHttpHeadersWriter hsts = new StrictTransportSecurityHttpHeadersWriter(); + + private XFrameOptionsHttpHeadersWriter frameOptions = new XFrameOptionsHttpHeadersWriter(); + + private XXssProtectionHttpHeadersWriter xss = new XXssProtectionHttpHeadersWriter(); + + public HttpSecurity and() { + return HttpSecurity.this; + } + + public CacheSpec cache() { + return new CacheSpec(); + } + + public ContentTypeOptionsSpec contentTypeOptions() { + return new ContentTypeOptionsSpec(); + } + + public FrameOptionsSpec frameOptions() { + return new FrameOptionsSpec(); + } + + public HstsSpec hsts() { + return new HstsSpec(); + } + + public HttpHeaderWriterWebFilter build() { + HttpHeadersWriter writer = new CompositeHttpHeadersWriter(writers); + return new HttpHeaderWriterWebFilter(writer); + } + + public XssProtectionSpec xssProtection() { + return new XssProtectionSpec(); + } + + public class CacheSpec { + public void disable() { + writers.remove(cacheControl); + } + + private CacheSpec() {} + } + + public class ContentTypeOptionsSpec { + public void disable() { + writers.remove(contentTypeOptions); + } + + private ContentTypeOptionsSpec() {} + } + + public class FrameOptionsSpec { + public void mode(XFrameOptionsHttpHeadersWriter.Mode mode) { + frameOptions.setMode(mode); + } + public void disable() { + writers.remove(frameOptions); + } + + private FrameOptionsSpec() {} + } + + public class HstsSpec { + public void maxAge(Duration maxAge) { + hsts.setMaxAge(maxAge); + } + + public void includeSubdomains(boolean includeSubDomains) { + hsts.setIncludeSubDomains(includeSubDomains); + } + + public void disable() { + writers.remove(hsts); + } + + private HstsSpec() {} + } + + public class XssProtectionSpec { + public void disable() { + writers.remove(xss); + } + + private XssProtectionSpec() {} + } + + private HeaderBuilder() { + this.writers = new ArrayList<>( + Arrays.asList(cacheControl, contentTypeOptions, hsts, frameOptions, xss)); + } + } } diff --git a/config/src/test/java/org/springframework/security/config/web/server/HeaderBuilderTests.java b/config/src/test/java/org/springframework/security/config/web/server/HeaderBuilderTests.java index 082e064e29..606b96ff71 100644 --- a/config/src/test/java/org/springframework/security/config/web/server/HeaderBuilderTests.java +++ b/config/src/test/java/org/springframework/security/config/web/server/HeaderBuilderTests.java @@ -42,7 +42,8 @@ import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; * @since 5.0 */ public class HeaderBuilderTests { - HeaderBuilder headers = new HeaderBuilder(); + + HttpSecurity.HeaderBuilder headers = HttpSecurity.http().headers(); HttpHeaders expectedHeaders = new HttpHeaders();