diff --git a/config/src/main/java/org/springframework/security/config/SecurityNamespaceHandler.java b/config/src/main/java/org/springframework/security/config/SecurityNamespaceHandler.java index 03676e718b..1cf1070056 100644 --- a/config/src/main/java/org/springframework/security/config/SecurityNamespaceHandler.java +++ b/config/src/main/java/org/springframework/security/config/SecurityNamespaceHandler.java @@ -221,7 +221,7 @@ public final class SecurityNamespaceHandler implements NamespaceHandler { private boolean matchesVersionInternal(Element element) { String schemaLocation = element.getAttributeNS( "http://www.w3.org/2001/XMLSchema-instance", "schemaLocation"); - return schemaLocation.matches("(?m).*spring-security-4\\.1.*.xsd.*") + return schemaLocation.matches("(?m).*spring-security-4\\.2.*.xsd.*") || schemaLocation.matches("(?m).*spring-security.xsd.*") || !schemaLocation.matches("(?m).*spring-security.*"); } diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/HeadersConfigurer.java b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/HeadersConfigurer.java index dd6726bdad..7eb78f4d91 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/HeadersConfigurer.java +++ b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/HeadersConfigurer.java @@ -28,6 +28,7 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur import org.springframework.security.web.header.HeaderWriter; import org.springframework.security.web.header.HeaderWriterFilter; import org.springframework.security.web.header.writers.*; +import org.springframework.security.web.header.writers.ReferrerPolicyHeaderWriter.ReferrerPolicy; import org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter; import org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter.XFrameOptionsMode; import org.springframework.security.web.util.matcher.RequestMatcher; @@ -56,6 +57,7 @@ import org.springframework.util.Assert; * @author Rob Winch * @author Tim Ysewyn * @author Joe Grandja + * @author Eddú Meléndez * @since 3.2 */ public class HeadersConfigurer> extends @@ -78,6 +80,8 @@ public class HeadersConfigurer> extends private final ContentSecurityPolicyConfig contentSecurityPolicy = new ContentSecurityPolicyConfig(); + private final ReferrerPolicyConfig referrerPolicy = new ReferrerPolicyConfig(); + /** * Creates a new instance * @@ -770,6 +774,7 @@ public class HeadersConfigurer> extends addIfNotNull(writers, frameOptions.writer); addIfNotNull(writers, hpkp.writer); addIfNotNull(writers, contentSecurityPolicy.writer); + addIfNotNull(writers, referrerPolicy.writer); writers.addAll(headerWriters); return writers; } @@ -779,4 +784,68 @@ public class HeadersConfigurer> extends values.add(value); } } + + /** + *

+ * Allows configuration for Referrer Policy. + *

+ * + *

+ * Configuration is provided to the {@link ReferrerPolicyHeaderWriter} which support the writing + * of the header as detailed in the W3C Technical Report: + *

+ *
    + *
  • Referrer-Policy
  • + *
+ * + *

Default value is:

+ * + *
+	 * Referrer-Policy: no-referrer
+	 * 
+ * + * @see ReferrerPolicyHeaderWriter + * @since 4.2 + * @return the ReferrerPolicyConfig for additional configuration + */ + public ReferrerPolicyConfig referrerPolicy() { + this.referrerPolicy.writer = new ReferrerPolicyHeaderWriter(); + return this.referrerPolicy; + } + + /** + *

+ * Allows configuration for Referrer Policy. + *

+ * + *

+ * Configuration is provided to the {@link ReferrerPolicyHeaderWriter} which support the writing + * of the header as detailed in the W3C Technical Report: + *

+ *
    + *
  • Referrer-Policy
  • + *
+ * + * @see ReferrerPolicyHeaderWriter + * @since 4.2 + * @return the ReferrerPolicyConfig for additional configuration + * @throws IllegalArgumentException if policy is null or empty + */ + public ReferrerPolicyConfig referrerPolicy(ReferrerPolicy policy) { + this.referrerPolicy.writer = new ReferrerPolicyHeaderWriter(policy); + return this.referrerPolicy; + } + + public final class ReferrerPolicyConfig { + + private ReferrerPolicyHeaderWriter writer; + + private ReferrerPolicyConfig() { + } + + public HeadersConfigurer and() { + return HeadersConfigurer.this; + } + + } } \ No newline at end of file diff --git a/config/src/main/java/org/springframework/security/config/http/HeadersBeanDefinitionParser.java b/config/src/main/java/org/springframework/security/config/http/HeadersBeanDefinitionParser.java index 89d265d3cd..6e35ddf34a 100644 --- a/config/src/main/java/org/springframework/security/config/http/HeadersBeanDefinitionParser.java +++ b/config/src/main/java/org/springframework/security/config/http/HeadersBeanDefinitionParser.java @@ -31,6 +31,7 @@ import org.springframework.beans.factory.xml.BeanDefinitionParser; import org.springframework.beans.factory.xml.ParserContext; import org.springframework.security.web.header.HeaderWriterFilter; import org.springframework.security.web.header.writers.*; +import org.springframework.security.web.header.writers.ReferrerPolicyHeaderWriter.ReferrerPolicy; import org.springframework.security.web.header.writers.frameoptions.RegExpAllowFromStrategy; import org.springframework.security.web.header.writers.frameoptions.StaticAllowFromStrategy; import org.springframework.security.web.header.writers.frameoptions.WhiteListedAllowFromStrategy; @@ -45,6 +46,7 @@ import org.w3c.dom.Node; * * @author Marten Deinum * @author Tim Ysewyn + * @author Eddú Meléndez * @since 3.2 */ public class HeadersBeanDefinitionParser implements BeanDefinitionParser { @@ -82,6 +84,7 @@ public class HeadersBeanDefinitionParser implements BeanDefinitionParser { private static final String GENERIC_HEADER_ELEMENT = "header"; private static final String CONTENT_SECURITY_POLICY_ELEMENT = "content-security-policy"; + private static final String REFERRER_POLICY_ELEMENT = "referrer-policy"; private static final String ALLOW_FROM = "ALLOW-FROM"; @@ -109,6 +112,8 @@ public class HeadersBeanDefinitionParser implements BeanDefinitionParser { parseContentSecurityPolicyElement(disabled, element, parserContext); + parseReferrerPolicyElement(element, parserContext); + parseHeaderElements(element); boolean noWriters = headerWriters.isEmpty(); @@ -291,6 +296,23 @@ public class HeadersBeanDefinitionParser implements BeanDefinitionParser { headerWriters.add(headersWriter.getBeanDefinition()); } + private void parseReferrerPolicyElement(Element element, ParserContext context) { + Element referrerPolicyElement = (element == null) ? null : DomUtils.getChildElementByTagName(element, REFERRER_POLICY_ELEMENT); + if (referrerPolicyElement != null) { + addReferrerPolicy(referrerPolicyElement, context); + } + } + + private void addReferrerPolicy(Element referrerPolicyElement, ParserContext context) { + BeanDefinitionBuilder headersWriter = BeanDefinitionBuilder.genericBeanDefinition(ReferrerPolicyHeaderWriter.class); + + String policy = referrerPolicyElement.getAttribute(ATT_POLICY); + if (StringUtils.hasLength(policy)) { + headersWriter.addConstructorArgValue(ReferrerPolicy.get(policy)); + } + headerWriters.add(headersWriter.getBeanDefinition()); + } + private void attrNotAllowed(ParserContext context, String attrName, String otherAttrName, Element element) { context.getReaderContext().error( diff --git a/config/src/main/resources/org/springframework/security/config/spring-security-4.2.rnc b/config/src/main/resources/org/springframework/security/config/spring-security-4.2.rnc index 3e1ec9ce67..ee0542d112 100644 --- a/config/src/main/resources/org/springframework/security/config/spring-security-4.2.rnc +++ b/config/src/main/resources/org/springframework/security/config/spring-security-4.2.rnc @@ -753,7 +753,7 @@ csrf-options.attlist &= headers = ## Element for configuration of the HeaderWritersFilter. Enables easy setting for the X-Frame-Options, X-XSS-Protection and X-Content-Type-Options headers. -element headers { headers-options.attlist, (cache-control? & xss-protection? & hsts? & frame-options? & content-type-options? & hpkp? & content-security-policy? & header*)} +element headers { headers-options.attlist, (cache-control? & xss-protection? & hsts? & frame-options? & content-type-options? & hpkp? & content-security-policy? & referrer-policy? & header*)} headers-options.attlist &= ## Specifies if the default headers should be disabled. Default false. attribute defaults-disabled {xsd:boolean}? @@ -824,6 +824,13 @@ csp-options.attlist &= ## Set to true, to enable the Content-Security-Policy-Report-Only header for reporting policy violations only. Defaults to false. attribute report-only {xsd:boolean}? +referrer-policy = + ## Adds support for Referrer Policy + element referrer-policy {referrer-options.attlist} +referrer-options.attlist &= + ## The policies for the Referrer-Policy header. + attribute policy {"no-referrer","no-referrer-when-downgrade","same-origin","origin","strict-origin","origin-when-cross-origin","strict-origin-when-cross-origin","unsafe-url"}? + cache-control = ## Adds Cache-Control no-cache, no-store, must-revalidate, Pragma no-cache, and Expires 0 for every request element cache-control {cache-control.attlist} diff --git a/config/src/main/resources/org/springframework/security/config/spring-security-4.2.xsd b/config/src/main/resources/org/springframework/security/config/spring-security-4.2.xsd index 0a6a27f22a..960158e19e 100644 --- a/config/src/main/resources/org/springframework/security/config/spring-security-4.2.xsd +++ b/config/src/main/resources/org/springframework/security/config/spring-security-4.2.xsd @@ -2357,6 +2357,7 @@ + @@ -2539,6 +2540,35 @@ + + + Adds support for Referrer Policy + + + + + + + + + + The policies for the Referrer-Policy header. + + + + + + + + + + + + + + + + Adds Cache-Control no-cache, no-store, must-revalidate, Pragma no-cache, and Expires 0 for diff --git a/config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/HeadersConfigurerTests.groovy b/config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/HeadersConfigurerTests.groovy index e39efaacb6..07fa282114 100644 --- a/config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/HeadersConfigurerTests.groovy +++ b/config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/HeadersConfigurerTests.groovy @@ -20,12 +20,14 @@ import org.springframework.security.config.annotation.BaseSpringSpec import org.springframework.security.config.annotation.web.builders.HttpSecurity import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter +import static org.springframework.security.web.header.writers.ReferrerPolicyHeaderWriter.ReferrerPolicy /** * * @author Rob Winch * @author Tim Ysewyn * @author Joe Grandja + * @author Eddú Meléndez */ class HeadersConfigurerTests extends BaseSpringSpec { @@ -453,4 +455,46 @@ class HeadersConfigurerTests extends BaseSpringSpec { } } + def "headers.referrerPolicy default"() { + setup: + loadConfig(ReferrerPolicyDefaultConfig) + when: + springSecurityFilterChain.doFilter(request,response,chain) + then: + responseHeaders == ['Referrer-Policy': 'no-referrer'] + } + + @EnableWebSecurity + static class ReferrerPolicyDefaultConfig extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .headers() + .defaultsDisabled() + .referrerPolicy(); + } + } + + def "headers.referrerPolicy custom"() { + setup: + loadConfig(ReferrerPolicyCustomConfig) + when: + springSecurityFilterChain.doFilter(request,response,chain) + then: + responseHeaders == ['Referrer-Policy': 'same-origin'] + } + + @EnableWebSecurity + static class ReferrerPolicyCustomConfig extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .headers() + .defaultsDisabled() + .referrerPolicy(ReferrerPolicy.SAME_ORIGIN); + } + } + } diff --git a/config/src/test/groovy/org/springframework/security/config/http/HttpHeadersConfigTests.groovy b/config/src/test/groovy/org/springframework/security/config/http/HttpHeadersConfigTests.groovy index e944e085b1..de2a887c86 100644 --- a/config/src/test/groovy/org/springframework/security/config/http/HttpHeadersConfigTests.groovy +++ b/config/src/test/groovy/org/springframework/security/config/http/HttpHeadersConfigTests.groovy @@ -920,6 +920,38 @@ class HttpHeadersConfigTests extends AbstractHttpConfigTests { assertHeaders(response, expectedHeaders) } + def 'http headers defaults : referrer-policy'() { + setup: + httpAutoConfig { + 'headers'('defaults-disabled':true) { + 'referrer-policy'() + } + } + createAppContext() + when: + def hf = getFilter(HeaderWriterFilter) + MockHttpServletResponse response = new MockHttpServletResponse() + hf.doFilter(new MockHttpServletRequest(), response, new MockFilterChain()) + then: + assertHeaders(response, ['Referrer-Policy': 'no-referrer']) + } + + def 'http headers defaults : referrer-policy same-origin'() { + setup: + httpAutoConfig { + 'headers'('defaults-disabled':true) { + 'referrer-policy'('policy': 'same-origin') + } + } + createAppContext() + when: + def hf = getFilter(HeaderWriterFilter) + MockHttpServletResponse response = new MockHttpServletResponse() + hf.doFilter(new MockHttpServletRequest(), response, new MockFilterChain()) + then: + assertHeaders(response, ['Referrer-Policy': 'same-origin']) + } + def assertHeaders(MockHttpServletResponse response, Map expected) { assert response.headerNames == expected.keySet() expected.each { headerName, value -> diff --git a/config/src/test/java/org/springframework/security/config/util/InMemoryXmlApplicationContext.java b/config/src/test/java/org/springframework/security/config/util/InMemoryXmlApplicationContext.java index dc1b716ec3..f2c200bb31 100644 --- a/config/src/test/java/org/springframework/security/config/util/InMemoryXmlApplicationContext.java +++ b/config/src/test/java/org/springframework/security/config/util/InMemoryXmlApplicationContext.java @@ -40,7 +40,7 @@ public class InMemoryXmlApplicationContext extends AbstractXmlApplicationContext + "http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-"; static final String BEANS_CLOSE = "\n"; - static final String SPRING_SECURITY_VERSION = "4.1"; + static final String SPRING_SECURITY_VERSION = "4.2"; Resource inMemoryXml; diff --git a/docs/manual/src/docs/asciidoc/index.adoc b/docs/manual/src/docs/asciidoc/index.adoc index 20c6c6320e..24e2c52089 100644 --- a/docs/manual/src/docs/asciidoc/index.adoc +++ b/docs/manual/src/docs/asciidoc/index.adoc @@ -4353,6 +4353,57 @@ protected void configure(HttpSecurity http) throws Exception { } ---- +[[headers-referrer]] +==== Referrer Policy + +https://www.w3.org/TR/referrer-policy[Referrer Policy] is a mechanism that web applications can leverage to manage the referrer field, which contains the last +page the user was on. + +Spring Security's approach is to use https://www.w3.org/TR/referrer-policy/[Referrer Policy] header, which provides different https://www.w3.org/TR/referrer-policy/#referrer-policies[policies]: + +[source] +---- +Referrer-Policy: same-origin +---- + +The Referrer-Policy response header instructs the browser to let the destination knows the source where the user was previously. + +[[headers-referrer-configure]] +===== Configuring Referrer Policy + +Spring Security *_doesn't add_* Referrer Policy header by default. + +You can enable the Referrer-Policy header using XML configuration with the <>> element as shown below: + +[source,xml] +---- + + + + + + + +---- + +Similarly, you can enable the Referrer Policy header using Java configuration as shown below: + +[source,java] +---- +@EnableWebSecurity +public class WebSecurityConfig extends +WebSecurityConfigurerAdapter { + +@Override +protected void configure(HttpSecurity http) throws Exception { + http + // ... + .headers() + .referrerPolicy(ReferrerPolicy.SAME_ORIGIN); +} +} +---- + [[headers-csp-links]] ===== Additional Resources @@ -7685,6 +7736,7 @@ This element allows for configuring additional (security) headers to be send wit ** `X-Content-Type-Options` - Can be set using the <> element. The http://blogs.msdn.com/b/ie/archive/2008/09/02/ie8-security-part-vi-beta-2-update.aspx[X-Content-Type-Options] header prevents Internet Explorer from MIME-sniffing a response away from the declared content-type. This also applies to Google Chrome, when downloading extensions. ** `Public-Key-Pinning` or `Public-Key-Pinning-Report-Only` - Can be set using the <> element. This allows HTTPS websites to resist impersonation by attackers using mis-issued or otherwise fraudulent certificates. ** `Content-Security-Policy` or `Content-Security-Policy-Report-Only` - Can be set using the <> element. https://www.w3.org/TR/CSP2/[Content Security Policy (CSP)] is a mechanism that web applications can leverage to mitigate content injection vulnerabilities, such as cross-site scripting (XSS). +** `Referrer-Policy` - Can be set using the <> element, https://www.w3.org/TR/referrer-policy/[Referrer-Policy] is a mechanism that web applications can leverage to manage the referrer field, which contains the last page the user was on. [[nsa-headers-attributes]] ===== Attributes @@ -7718,6 +7770,7 @@ Optional attribute that specifies to disable Spring Security's HTTP response hea * <> * <> * <> +* <> * <> @@ -7867,6 +7920,24 @@ Set to true, to enable the Content-Security-Policy-Report-Only header for report +[[nsa-referrer-policy]] +==== +When enabled adds the https://www.w3.org/TR/referrer-policy/[Referrer Policy] header to the response. + +[[nsa-referrer-policy-attributes]] +===== Attributes + +[[nsa-referrer-policy-policy]] +* **policy** +The policy for the Referrer-Policy header. Default "no-referrer". + +[[nsa-referrer-policy-parents]] +===== Parent Elements of + +* <> + + + [[nsa-frame-options]] ==== When enabled adds the http://tools.ietf.org/html/draft-ietf-websec-x-frame-options[X-Frame-Options header] to the response, this allows newer browsers to do some security checks and prevent http://en.wikipedia.org/wiki/Clickjacking[clickjacking] attacks. diff --git a/web/src/main/java/org/springframework/security/web/header/writers/ReferrerPolicyHeaderWriter.java b/web/src/main/java/org/springframework/security/web/header/writers/ReferrerPolicyHeaderWriter.java new file mode 100644 index 0000000000..7ac1b0c2fb --- /dev/null +++ b/web/src/main/java/org/springframework/security/web/header/writers/ReferrerPolicyHeaderWriter.java @@ -0,0 +1,129 @@ +/* + * 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.web.header.writers; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.security.web.header.HeaderWriter; +import org.springframework.util.Assert; + +/** + *

+ * Provides support for Referrer Policy. + *

+ * + *

+ * The list of policies defined can be found at + * Referrer Policies. + *

+ * + *

+ * This implementation of {@link HeaderWriter} writes the following header: + *

+ *
    + *
  • Referrer-Policy
  • + *
+ * + *

+ * By default, the Referrer-Policy header is not included in the response. + * Policy no-referrer is used by default if no {@link ReferrerPolicy} is set. + *

+ * + * @author Eddú Meléndez + * @since 4.2 + */ +public class ReferrerPolicyHeaderWriter implements HeaderWriter { + + private final String REFERER_POLICY_HEADER = "Referrer-Policy"; + + private ReferrerPolicy policy; + + /** + * Creates a new instance. Default value: no-referrer. + */ + public ReferrerPolicyHeaderWriter() { + this(ReferrerPolicy.NO_REFERRER); + } + + /** + * Creates a new instance. + * + * @param policy + * @throws IllegalArgumentException if policyDirectives is null or empty + */ + public ReferrerPolicyHeaderWriter(ReferrerPolicy policy) { + setPolicy(policy); + } + + /** + * Sets the policy to be used in the response header. + * @param policy + */ + public void setPolicy(ReferrerPolicy policy) { + Assert.notNull(policy, "policy can not be null"); + this.policy = policy; + } + + /** + * @see org.springframework.security.web.header.HeaderWriter#writeHeaders(HttpServletRequest, HttpServletResponse) + */ + @Override + public void writeHeaders(HttpServletRequest request, HttpServletResponse response) { + response.setHeader(REFERER_POLICY_HEADER, this.policy.getPolicy()); + } + + public enum ReferrerPolicy { + + NO_REFERRER("no-referrer"), + NO_REFERRER_WHEN_DOWNGRADE("no-referrer-when-downgrade"), + SAME_ORIGIN("same-origin"), + ORIGIN("origin"), + STRICT_ORIGIN("strict-origin"), + ORIGIN_WHEN_CROSS_ORIGIN("origin-when-cross-origin"), + STRICT_ORIGIN_WHEN_CROSS_ORIGIN("strict-origin-when-cross-origin"), + UNSAFE_URL("unsafe-url"); + + private static Map REFERRER_POLICIES; + + static { + Map referrerPolicies = new HashMap(); + for (ReferrerPolicy referrerPolicy : values()) { + referrerPolicies.put(referrerPolicy.getPolicy(), referrerPolicy); + } + REFERRER_POLICIES = Collections.unmodifiableMap(referrerPolicies); + } + + private String policy; + + private ReferrerPolicy(String policy) { + this.policy = policy; + } + + public String getPolicy() { + return this.policy; + } + + public static ReferrerPolicy get(String referrerPolicy) { + return REFERRER_POLICIES.get(referrerPolicy); + } + } + +} diff --git a/web/src/test/java/org/springframework/security/web/header/writers/ReferrerPolicyHeaderWriterTests.java b/web/src/test/java/org/springframework/security/web/header/writers/ReferrerPolicyHeaderWriterTests.java new file mode 100644 index 0000000000..b3332d23d2 --- /dev/null +++ b/web/src/test/java/org/springframework/security/web/header/writers/ReferrerPolicyHeaderWriterTests.java @@ -0,0 +1,68 @@ +/* + * 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.web.header.writers; + +import org.junit.Before; +import org.junit.Test; + +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.security.web.header.writers.ReferrerPolicyHeaderWriter.*; + +/** + * @author Eddú Meléndez + */ +public class ReferrerPolicyHeaderWriterTests { + + private final String DEFAULT_REFERRER_POLICY = "no-referrer"; + private MockHttpServletRequest request; + private MockHttpServletResponse response; + private ReferrerPolicyHeaderWriter writer; + + @Before + public void setup() { + this.request = new MockHttpServletRequest(); + this.request.setSecure(true); + this.response = new MockHttpServletResponse(); + this.writer = new ReferrerPolicyHeaderWriter(); + } + + @Test + public void writeHeadersReferrerPolicyDefault() { + this.writer.writeHeaders(this.request, this.response); + + assertThat(this.response.getHeaderNames().size()).isEqualTo(1); + assertThat(this.response.getHeader("Referrer-Policy")).isEqualTo(DEFAULT_REFERRER_POLICY); + } + + @Test + public void writeHeadersReferrerPolicyCustom() { + this.writer = new ReferrerPolicyHeaderWriter(ReferrerPolicy.SAME_ORIGIN); + + this.writer.writeHeaders(this.request, this.response); + + assertThat(this.response.getHeaderNames().size()).isEqualTo(1); + assertThat(this.response.getHeader("Referrer-Policy")).isEqualTo("same-origin"); + } + + @Test(expected = IllegalArgumentException.class) + public void writeHeaderReferrerPolicyInvalid() { + this.writer = new ReferrerPolicyHeaderWriter(null); + } + +}