Add Cross Origin Policies headers

Add DSL support for Cross-Origin-Opener-Policy, Cross-Origin-Embedder-Policy and Cross-Origin-Resource-Policy headers

Closes gh-9385, gh-10118
This commit is contained in:
Marcus Da Coregio
2021-12-03 16:47:21 -03:00
committed by Eleftheria Stein
parent 263665ad55
commit 0beb725259
38 changed files with 2513 additions and 8 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2021 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.
@@ -31,6 +31,9 @@ import org.springframework.security.web.header.HeaderWriter;
import org.springframework.security.web.header.HeaderWriterFilter;
import org.springframework.security.web.header.writers.CacheControlHeadersWriter;
import org.springframework.security.web.header.writers.ContentSecurityPolicyHeaderWriter;
import org.springframework.security.web.header.writers.CrossOriginEmbedderPolicyHeaderWriter;
import org.springframework.security.web.header.writers.CrossOriginOpenerPolicyHeaderWriter;
import org.springframework.security.web.header.writers.CrossOriginResourcePolicyHeaderWriter;
import org.springframework.security.web.header.writers.FeaturePolicyHeaderWriter;
import org.springframework.security.web.header.writers.HpkpHeaderWriter;
import org.springframework.security.web.header.writers.HstsHeaderWriter;
@@ -97,6 +100,12 @@ public class HeadersConfigurer<H extends HttpSecurityBuilder<H>>
private final PermissionsPolicyConfig permissionsPolicy = new PermissionsPolicyConfig();
private final CrossOriginOpenerPolicyConfig crossOriginOpenerPolicy = new CrossOriginOpenerPolicyConfig();
private final CrossOriginEmbedderPolicyConfig crossOriginEmbedderPolicy = new CrossOriginEmbedderPolicyConfig();
private final CrossOriginResourcePolicyConfig crossOriginResourcePolicy = new CrossOriginResourcePolicyConfig();
/**
* Creates a new instance
*
@@ -392,6 +401,9 @@ public class HeadersConfigurer<H extends HttpSecurityBuilder<H>>
addIfNotNull(writers, this.referrerPolicy.writer);
addIfNotNull(writers, this.featurePolicy.writer);
addIfNotNull(writers, this.permissionsPolicy.writer);
addIfNotNull(writers, this.crossOriginOpenerPolicy.writer);
addIfNotNull(writers, this.crossOriginEmbedderPolicy.writer);
addIfNotNull(writers, this.crossOriginResourcePolicy.writer);
writers.addAll(this.headerWriters);
return writers;
}
@@ -544,6 +556,129 @@ public class HeadersConfigurer<H extends HttpSecurityBuilder<H>>
return this.permissionsPolicy;
}
/**
* Allows configuration for <a href=
* "https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Opener-Policy">
* Cross-Origin-Opener-Policy</a> header.
* <p>
* Configuration is provided to the {@link CrossOriginOpenerPolicyHeaderWriter} which
* responsible for writing the header.
* </p>
* @return the {@link CrossOriginOpenerPolicyConfig} for additional confniguration
* @since 5.7
* @see CrossOriginOpenerPolicyHeaderWriter
*/
public CrossOriginOpenerPolicyConfig crossOriginOpenerPolicy() {
this.crossOriginOpenerPolicy.writer = new CrossOriginOpenerPolicyHeaderWriter();
return this.crossOriginOpenerPolicy;
}
/**
* Allows configuration for <a href=
* "https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Opener-Policy">
* Cross-Origin-Opener-Policy</a> header.
* <p>
* Calling this method automatically enables (includes) the
* {@code Cross-Origin-Opener-Policy} header in the response using the supplied
* policy.
* <p>
* <p>
* Configuration is provided to the {@link CrossOriginOpenerPolicyHeaderWriter} which
* responsible for writing the header.
* </p>
* @return the {@link HeadersConfigurer} for additional customizations
* @since 5.7
* @see CrossOriginOpenerPolicyHeaderWriter
*/
public HeadersConfigurer<H> crossOriginOpenerPolicy(
Customizer<CrossOriginOpenerPolicyConfig> crossOriginOpenerPolicyCustomizer) {
this.crossOriginOpenerPolicy.writer = new CrossOriginOpenerPolicyHeaderWriter();
crossOriginOpenerPolicyCustomizer.customize(this.crossOriginOpenerPolicy);
return HeadersConfigurer.this;
}
/**
* Allows configuration for <a href=
* "https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Embedder-Policy">
* Cross-Origin-Embedder-Policy</a> header.
* <p>
* Configuration is provided to the {@link CrossOriginEmbedderPolicyHeaderWriter}
* which is responsible for writing the header.
* </p>
* @return the {@link CrossOriginEmbedderPolicyConfig} for additional customizations
* @since 5.7
* @see CrossOriginEmbedderPolicyHeaderWriter
*/
public CrossOriginEmbedderPolicyConfig crossOriginEmbedderPolicy() {
this.crossOriginEmbedderPolicy.writer = new CrossOriginEmbedderPolicyHeaderWriter();
return this.crossOriginEmbedderPolicy;
}
/**
* Allows configuration for <a href=
* "https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Embedder-Policy">
* Cross-Origin-Embedder-Policy</a> header.
* <p>
* Calling this method automatically enables (includes) the
* {@code Cross-Origin-Embedder-Policy} header in the response using the supplied
* policy.
* <p>
* <p>
* Configuration is provided to the {@link CrossOriginEmbedderPolicyHeaderWriter}
* which is responsible for writing the header.
* </p>
* @return the {@link HeadersConfigurer} for additional customizations
* @since 5.7
* @see CrossOriginEmbedderPolicyHeaderWriter
*/
public HeadersConfigurer<H> crossOriginEmbedderPolicy(
Customizer<CrossOriginEmbedderPolicyConfig> crossOriginEmbedderPolicyCustomizer) {
this.crossOriginEmbedderPolicy.writer = new CrossOriginEmbedderPolicyHeaderWriter();
crossOriginEmbedderPolicyCustomizer.customize(this.crossOriginEmbedderPolicy);
return HeadersConfigurer.this;
}
/**
* Allows configuration for <a href=
* "https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Resource-Policy">
* Cross-Origin-Resource-Policy</a> header.
* <p>
* Configuration is provided to the {@link CrossOriginResourcePolicyHeaderWriter}
* which is responsible for writing the header:
* </p>
* @return the {@link HeadersConfigurer} for additional customizations
* @since 5.7
* @see CrossOriginResourcePolicyHeaderWriter
*/
public CrossOriginResourcePolicyConfig crossOriginResourcePolicy() {
this.crossOriginResourcePolicy.writer = new CrossOriginResourcePolicyHeaderWriter();
return this.crossOriginResourcePolicy;
}
/**
* Allows configuration for <a href=
* "https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Resource-Policy">
* Cross-Origin-Resource-Policy</a> header.
* <p>
* Calling this method automatically enables (includes) the
* {@code Cross-Origin-Resource-Policy} header in the response using the supplied
* policy.
* <p>
* <p>
* Configuration is provided to the {@link CrossOriginResourcePolicyHeaderWriter}
* which is responsible for writing the header:
* </p>
* @return the {@link HeadersConfigurer} for additional customizations
* @since 5.7
* @see CrossOriginResourcePolicyHeaderWriter
*/
public HeadersConfigurer<H> crossOriginResourcePolicy(
Customizer<CrossOriginResourcePolicyConfig> crossOriginResourcePolicyCustomizer) {
this.crossOriginResourcePolicy.writer = new CrossOriginResourcePolicyHeaderWriter();
crossOriginResourcePolicyCustomizer.customize(this.crossOriginResourcePolicy);
return HeadersConfigurer.this;
}
public final class ContentTypeOptionsConfig {
private XContentTypeOptionsHeaderWriter writer;
@@ -1142,4 +1277,96 @@ public class HeadersConfigurer<H extends HttpSecurityBuilder<H>>
}
public final class CrossOriginOpenerPolicyConfig {
private CrossOriginOpenerPolicyHeaderWriter writer;
public CrossOriginOpenerPolicyConfig() {
}
/**
* Sets the policy to be used in the {@code Cross-Origin-Opener-Policy} header
* @param openerPolicy a {@code Cross-Origin-Opener-Policy}
* @return the {@link CrossOriginOpenerPolicyConfig} for additional configuration
* @throws IllegalArgumentException if openerPolicy is null
*/
public CrossOriginOpenerPolicyConfig policy(
CrossOriginOpenerPolicyHeaderWriter.CrossOriginOpenerPolicy openerPolicy) {
this.writer.setPolicy(openerPolicy);
return this;
}
/**
* Allows completing configuration of Cross Origin Opener Policy and continuing
* configuration of headers.
* @return the {@link HeadersConfigurer} for additional configuration
*/
public HeadersConfigurer<H> and() {
return HeadersConfigurer.this;
}
}
public final class CrossOriginEmbedderPolicyConfig {
private CrossOriginEmbedderPolicyHeaderWriter writer;
public CrossOriginEmbedderPolicyConfig() {
}
/**
* Sets the policy to be used in the {@code Cross-Origin-Embedder-Policy} header
* @param embedderPolicy a {@code Cross-Origin-Embedder-Policy}
* @return the {@link CrossOriginEmbedderPolicyConfig} for additional
* configuration
* @throws IllegalArgumentException if embedderPolicy is null
*/
public CrossOriginEmbedderPolicyConfig policy(
CrossOriginEmbedderPolicyHeaderWriter.CrossOriginEmbedderPolicy embedderPolicy) {
this.writer.setPolicy(embedderPolicy);
return this;
}
/**
* Allows completing configuration of Cross-Origin-Embedder-Policy and continuing
* configuration of headers.
* @return the {@link HeadersConfigurer} for additional configuration
*/
public HeadersConfigurer<H> and() {
return HeadersConfigurer.this;
}
}
public final class CrossOriginResourcePolicyConfig {
private CrossOriginResourcePolicyHeaderWriter writer;
public CrossOriginResourcePolicyConfig() {
}
/**
* Sets the policy to be used in the {@code Cross-Origin-Resource-Policy} header
* @param resourcePolicy a {@code Cross-Origin-Resource-Policy}
* @return the {@link CrossOriginResourcePolicyConfig} for additional
* configuration
* @throws IllegalArgumentException if resourcePolicy is null
*/
public CrossOriginResourcePolicyConfig policy(
CrossOriginResourcePolicyHeaderWriter.CrossOriginResourcePolicy resourcePolicy) {
this.writer.setPolicy(resourcePolicy);
return this;
}
/**
* Allows completing configuration of Cross-Origin-Resource-Policy and continuing
* configuration of headers.
* @return the {@link HeadersConfigurer} for additional configuration
*/
public HeadersConfigurer<H> and() {
return HeadersConfigurer.this;
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2021 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.
@@ -36,6 +36,9 @@ import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.security.web.header.HeaderWriterFilter;
import org.springframework.security.web.header.writers.CacheControlHeadersWriter;
import org.springframework.security.web.header.writers.ContentSecurityPolicyHeaderWriter;
import org.springframework.security.web.header.writers.CrossOriginEmbedderPolicyHeaderWriter;
import org.springframework.security.web.header.writers.CrossOriginOpenerPolicyHeaderWriter;
import org.springframework.security.web.header.writers.CrossOriginResourcePolicyHeaderWriter;
import org.springframework.security.web.header.writers.FeaturePolicyHeaderWriter;
import org.springframework.security.web.header.writers.HpkpHeaderWriter;
import org.springframework.security.web.header.writers.HstsHeaderWriter;
@@ -122,6 +125,12 @@ public class HeadersBeanDefinitionParser implements BeanDefinitionParser {
private static final String PERMISSIONS_POLICY_ELEMENT = "permissions-policy";
private static final String CROSS_ORIGIN_OPENER_POLICY_ELEMENT = "cross-origin-opener-policy";
private static final String CROSS_ORIGIN_EMBEDDER_POLICY_ELEMENT = "cross-origin-embedder-policy";
private static final String CROSS_ORIGIN_RESOURCE_POLICY_ELEMENT = "cross-origin-resource-policy";
private static final String ALLOW_FROM = "ALLOW-FROM";
private ManagedList<BeanMetadataElement> headerWriters;
@@ -144,6 +153,9 @@ public class HeadersBeanDefinitionParser implements BeanDefinitionParser {
parseReferrerPolicyElement(element, parserContext);
parseFeaturePolicyElement(element, parserContext);
parsePermissionsPolicyElement(element, parserContext);
parseCrossOriginOpenerPolicy(disabled, element);
parseCrossOriginEmbedderPolicy(disabled, element);
parseCrossOriginResourcePolicy(disabled, element);
parseHeaderElements(element);
boolean noWriters = this.headerWriters.isEmpty();
if (disabled && !noWriters) {
@@ -376,6 +388,75 @@ public class HeadersBeanDefinitionParser implements BeanDefinitionParser {
this.headerWriters.add(headersWriter.getBeanDefinition());
}
private void parseCrossOriginOpenerPolicy(boolean elementDisabled, Element element) {
if (elementDisabled || element == null) {
return;
}
CrossOriginOpenerPolicyHeaderWriter writer = new CrossOriginOpenerPolicyHeaderWriter();
Element crossOriginOpenerPolicyElement = DomUtils.getChildElementByTagName(element,
CROSS_ORIGIN_OPENER_POLICY_ELEMENT);
if (crossOriginOpenerPolicyElement != null) {
addCrossOriginOpenerPolicy(crossOriginOpenerPolicyElement, writer);
}
BeanDefinitionBuilder builder = BeanDefinitionBuilder
.genericBeanDefinition(CrossOriginOpenerPolicyHeaderWriter.class, () -> writer);
this.headerWriters.add(builder.getBeanDefinition());
}
private void parseCrossOriginEmbedderPolicy(boolean elementDisabled, Element element) {
if (elementDisabled || element == null) {
return;
}
CrossOriginEmbedderPolicyHeaderWriter writer = new CrossOriginEmbedderPolicyHeaderWriter();
Element crossOriginEmbedderPolicyElement = DomUtils.getChildElementByTagName(element,
CROSS_ORIGIN_EMBEDDER_POLICY_ELEMENT);
if (crossOriginEmbedderPolicyElement != null) {
addCrossOriginEmbedderPolicy(crossOriginEmbedderPolicyElement, writer);
}
BeanDefinitionBuilder builder = BeanDefinitionBuilder
.genericBeanDefinition(CrossOriginEmbedderPolicyHeaderWriter.class, () -> writer);
this.headerWriters.add(builder.getBeanDefinition());
}
private void parseCrossOriginResourcePolicy(boolean elementDisabled, Element element) {
if (elementDisabled || element == null) {
return;
}
CrossOriginResourcePolicyHeaderWriter writer = new CrossOriginResourcePolicyHeaderWriter();
Element crossOriginResourcePolicyElement = DomUtils.getChildElementByTagName(element,
CROSS_ORIGIN_RESOURCE_POLICY_ELEMENT);
if (crossOriginResourcePolicyElement != null) {
addCrossOriginResourcePolicy(crossOriginResourcePolicyElement, writer);
}
BeanDefinitionBuilder builder = BeanDefinitionBuilder
.genericBeanDefinition(CrossOriginResourcePolicyHeaderWriter.class, () -> writer);
this.headerWriters.add(builder.getBeanDefinition());
}
private void addCrossOriginResourcePolicy(Element crossOriginResourcePolicyElement,
CrossOriginResourcePolicyHeaderWriter writer) {
String policy = crossOriginResourcePolicyElement.getAttribute(ATT_POLICY);
if (StringUtils.hasText(policy)) {
writer.setPolicy(CrossOriginResourcePolicyHeaderWriter.CrossOriginResourcePolicy.from(policy));
}
}
private void addCrossOriginEmbedderPolicy(Element crossOriginEmbedderPolicyElement,
CrossOriginEmbedderPolicyHeaderWriter writer) {
String policy = crossOriginEmbedderPolicyElement.getAttribute(ATT_POLICY);
if (StringUtils.hasText(policy)) {
writer.setPolicy(CrossOriginEmbedderPolicyHeaderWriter.CrossOriginEmbedderPolicy.from(policy));
}
}
private void addCrossOriginOpenerPolicy(Element crossOriginOpenerPolicyElement,
CrossOriginOpenerPolicyHeaderWriter writer) {
String policy = crossOriginOpenerPolicyElement.getAttribute(ATT_POLICY);
if (StringUtils.hasText(policy)) {
writer.setPolicy(CrossOriginOpenerPolicyHeaderWriter.CrossOriginOpenerPolicy.from(policy));
}
}
private void attrNotAllowed(ParserContext context, String attrName, String otherAttrName, Element element) {
context.getReaderContext().error("Only one of '" + attrName + "' or '" + otherAttrName + "' can be set.",
element);

View File

@@ -149,6 +149,12 @@ import org.springframework.security.web.server.header.CacheControlServerHttpHead
import org.springframework.security.web.server.header.CompositeServerHttpHeadersWriter;
import org.springframework.security.web.server.header.ContentSecurityPolicyServerHttpHeadersWriter;
import org.springframework.security.web.server.header.ContentTypeOptionsServerHttpHeadersWriter;
import org.springframework.security.web.server.header.CrossOriginEmbedderPolicyServerHttpHeadersWriter;
import org.springframework.security.web.server.header.CrossOriginEmbedderPolicyServerHttpHeadersWriter.CrossOriginEmbedderPolicy;
import org.springframework.security.web.server.header.CrossOriginOpenerPolicyServerHttpHeadersWriter;
import org.springframework.security.web.server.header.CrossOriginOpenerPolicyServerHttpHeadersWriter.CrossOriginOpenerPolicy;
import org.springframework.security.web.server.header.CrossOriginResourcePolicyServerHttpHeadersWriter;
import org.springframework.security.web.server.header.CrossOriginResourcePolicyServerHttpHeadersWriter.CrossOriginResourcePolicy;
import org.springframework.security.web.server.header.FeaturePolicyServerHttpHeadersWriter;
import org.springframework.security.web.server.header.HttpHeaderWriterWebFilter;
import org.springframework.security.web.server.header.PermissionsPolicyServerHttpHeadersWriter;
@@ -2380,10 +2386,17 @@ public class ServerHttpSecurity {
private ReferrerPolicyServerHttpHeadersWriter referrerPolicy = new ReferrerPolicyServerHttpHeadersWriter();
private CrossOriginOpenerPolicyServerHttpHeadersWriter crossOriginOpenerPolicy = new CrossOriginOpenerPolicyServerHttpHeadersWriter();
private CrossOriginEmbedderPolicyServerHttpHeadersWriter crossOriginEmbedderPolicy = new CrossOriginEmbedderPolicyServerHttpHeadersWriter();
private CrossOriginResourcePolicyServerHttpHeadersWriter crossOriginResourcePolicy = new CrossOriginResourcePolicyServerHttpHeadersWriter();
private HeaderSpec() {
this.writers = new ArrayList<>(Arrays.asList(this.cacheControl, this.contentTypeOptions, this.hsts,
this.frameOptions, this.xss, this.featurePolicy, this.permissionsPolicy, this.contentSecurityPolicy,
this.referrerPolicy));
this.referrerPolicy, this.crossOriginOpenerPolicy, this.crossOriginEmbedderPolicy,
this.crossOriginResourcePolicy));
}
/**
@@ -2595,6 +2608,84 @@ public class ServerHttpSecurity {
return this;
}
/**
* Configures the <a href=
* "https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Opener-Policy">
* Cross-Origin-Opener-Policy</a> header.
* @return the {@link CrossOriginOpenerPolicySpec} to configure
* @since 5.7
* @see CrossOriginOpenerPolicyServerHttpHeadersWriter
*/
public CrossOriginOpenerPolicySpec crossOriginOpenerPolicy() {
return new CrossOriginOpenerPolicySpec();
}
/**
* Configures the <a href=
* "https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Opener-Policy">
* Cross-Origin-Opener-Policy</a> header.
* @return the {@link HeaderSpec} to customize
* @since 5.7
* @see CrossOriginOpenerPolicyServerHttpHeadersWriter
*/
public HeaderSpec crossOriginOpenerPolicy(
Customizer<CrossOriginOpenerPolicySpec> crossOriginOpenerPolicyCustomizer) {
crossOriginOpenerPolicyCustomizer.customize(new CrossOriginOpenerPolicySpec());
return this;
}
/**
* Configures the <a href=
* "https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Embedder-Policy">
* Cross-Origin-Embedder-Policy</a> header.
* @return the {@link CrossOriginEmbedderPolicySpec} to configure
* @since 5.7
* @see CrossOriginEmbedderPolicyServerHttpHeadersWriter
*/
public CrossOriginEmbedderPolicySpec crossOriginEmbedderPolicy() {
return new CrossOriginEmbedderPolicySpec();
}
/**
* Configures the <a href=
* "https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Embedder-Policy">
* Cross-Origin-Embedder-Policy</a> header.
* @return the {@link HeaderSpec} to customize
* @since 5.7
* @see CrossOriginEmbedderPolicyServerHttpHeadersWriter
*/
public HeaderSpec crossOriginEmbedderPolicy(
Customizer<CrossOriginEmbedderPolicySpec> crossOriginEmbedderPolicyCustomizer) {
crossOriginEmbedderPolicyCustomizer.customize(new CrossOriginEmbedderPolicySpec());
return this;
}
/**
* Configures the <a href=
* "https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Resource-Policy">
* Cross-Origin-Resource-Policy</a> header.
* @return the {@link CrossOriginResourcePolicySpec} to configure
* @since 5.7
* @see CrossOriginResourcePolicyServerHttpHeadersWriter
*/
public CrossOriginResourcePolicySpec crossOriginResourcePolicy() {
return new CrossOriginResourcePolicySpec();
}
/**
* Configures the <a href=
* "https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Resource-Policy">
* Cross-Origin-Resource-Policy</a> header.
* @return the {@link HeaderSpec} to customize
* @since 5.7
* @see CrossOriginResourcePolicyServerHttpHeadersWriter
*/
public HeaderSpec crossOriginResourcePolicy(
Customizer<CrossOriginResourcePolicySpec> crossOriginResourcePolicyCustomizer) {
crossOriginResourcePolicyCustomizer.customize(new CrossOriginResourcePolicySpec());
return this;
}
/**
* Configures cache control headers
*
@@ -2910,6 +3001,99 @@ public class ServerHttpSecurity {
}
/**
* Configures the Cross-Origin-Opener-Policy header
*
* @since 5.7
*/
public final class CrossOriginOpenerPolicySpec {
private CrossOriginOpenerPolicySpec() {
}
/**
* Sets the value to be used in the `Cross-Origin-Opener-Policy` header
* @param openerPolicy a opener policy
* @return the {@link CrossOriginOpenerPolicySpec} to continue configuring
*/
public CrossOriginOpenerPolicySpec policy(CrossOriginOpenerPolicy openerPolicy) {
HeaderSpec.this.crossOriginOpenerPolicy.setPolicy(openerPolicy);
return this;
}
/**
* Allows method chaining to continue configuring the
* {@link ServerHttpSecurity}.
* @return the {@link HeaderSpec} to continue configuring
*/
public HeaderSpec and() {
return HeaderSpec.this;
}
}
/**
* Configures the Cross-Origin-Embedder-Policy header
*
* @since 5.7
*/
public final class CrossOriginEmbedderPolicySpec {
private CrossOriginEmbedderPolicySpec() {
}
/**
* Sets the value to be used in the `Cross-Origin-Embedder-Policy` header
* @param embedderPolicy a opener policy
* @return the {@link CrossOriginEmbedderPolicySpec} to continue configuring
*/
public CrossOriginEmbedderPolicySpec policy(CrossOriginEmbedderPolicy embedderPolicy) {
HeaderSpec.this.crossOriginEmbedderPolicy.setPolicy(embedderPolicy);
return this;
}
/**
* Allows method chaining to continue configuring the
* {@link ServerHttpSecurity}.
* @return the {@link HeaderSpec} to continue configuring
*/
public HeaderSpec and() {
return HeaderSpec.this;
}
}
/**
* Configures the Cross-Origin-Resource-Policy header
*
* @since 5.7
*/
public final class CrossOriginResourcePolicySpec {
private CrossOriginResourcePolicySpec() {
}
/**
* Sets the value to be used in the `Cross-Origin-Resource-Policy` header
* @param resourcePolicy a opener policy
* @return the {@link CrossOriginResourcePolicySpec} to continue configuring
*/
public CrossOriginResourcePolicySpec policy(CrossOriginResourcePolicy resourcePolicy) {
HeaderSpec.this.crossOriginResourcePolicy.setPolicy(resourcePolicy);
return this;
}
/**
* Allows method chaining to continue configuring the
* {@link ServerHttpSecurity}.
* @return the {@link HeaderSpec} to continue configuring
*/
public HeaderSpec and() {
return HeaderSpec.this;
}
}
}
/**

View File

@@ -42,6 +42,9 @@ class HeadersDsl {
private var referrerPolicy: ((HeadersConfigurer<HttpSecurity>.ReferrerPolicyConfig) -> Unit)? = null
private var featurePolicyDirectives: String? = null
private var permissionsPolicy: ((HeadersConfigurer<HttpSecurity>.PermissionsPolicyConfig) -> Unit)? = null
private var crossOriginOpenerPolicy: ((HeadersConfigurer<HttpSecurity>.CrossOriginOpenerPolicyConfig) -> Unit)? = null
private var crossOriginEmbedderPolicy: ((HeadersConfigurer<HttpSecurity>.CrossOriginEmbedderPolicyConfig) -> Unit)? = null
private var crossOriginResourcePolicy: ((HeadersConfigurer<HttpSecurity>.CrossOriginResourcePolicyConfig) -> Unit)? = null
private var disabled = false
private var headerWriters = mutableListOf<HeaderWriter>()
@@ -181,6 +184,54 @@ class HeadersDsl {
this.permissionsPolicy = PermissionsPolicyDsl().apply(permissionsPolicyConfig).get()
}
/**
* Allows configuration for <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Opener-Policy">
* Cross-Origin-Opener-Policy</a> header.
*
* <p>
* Calling this method automatically enables (includes) the Cross-Origin-Opener-Policy
* header in the response using the supplied policy.
* <p>
*
* @since 5.7
* @param crossOriginOpenerPolicyConfig the customization to apply to the header
*/
fun crossOriginOpenerPolicy(crossOriginOpenerPolicyConfig: CrossOriginOpenerPolicyDsl.() -> Unit) {
this.crossOriginOpenerPolicy = CrossOriginOpenerPolicyDsl().apply(crossOriginOpenerPolicyConfig).get()
}
/**
* Allows configuration for <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Embedder-Policy">
* Cross-Origin-Embedder-Policy</a> header.
*
* <p>
* Calling this method automatically enables (includes) the Cross-Origin-Embedder-Policy
* header in the response using the supplied policy.
* <p>
*
* @since 5.7
* @param crossOriginEmbedderPolicyConfig the customization to apply to the header
*/
fun crossOriginEmbedderPolicy(crossOriginEmbedderPolicyConfig: CrossOriginEmbedderPolicyDsl.() -> Unit) {
this.crossOriginEmbedderPolicy = CrossOriginEmbedderPolicyDsl().apply(crossOriginEmbedderPolicyConfig).get()
}
/**
* Configures the <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Resource-Policy">
* Cross-Origin-Resource-Policy</a> header.
*
* <p>
* Calling this method automatically enables (includes) the Cross-Origin-Resource-Policy
* header in the response using the supplied policy.
* <p>
*
* @since 5.7
* @param crossOriginResourcePolicyConfig the customization to apply to the header
*/
fun crossOriginResourcePolicy(crossOriginResourcePolicyConfig: CrossOriginResourcePolicyDsl.() -> Unit) {
this.crossOriginResourcePolicy = CrossOriginResourcePolicyDsl().apply(crossOriginResourcePolicyConfig).get()
}
/**
* Adds a [HeaderWriter] instance.
*
@@ -238,6 +289,15 @@ class HeadersDsl {
permissionsPolicy?.also {
headers.permissionsPolicy(permissionsPolicy)
}
crossOriginOpenerPolicy?.also {
headers.crossOriginOpenerPolicy(crossOriginOpenerPolicy)
}
crossOriginEmbedderPolicy?.also {
headers.crossOriginEmbedderPolicy(crossOriginEmbedderPolicy)
}
crossOriginResourcePolicy?.also {
headers.crossOriginResourcePolicy(crossOriginResourcePolicy)
}
headerWriters.forEach { headerWriter ->
headers.addHeaderWriter(headerWriter)
}

View File

@@ -0,0 +1,43 @@
/*
* Copyright 2002-2021 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
*
* https://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.annotation.web.headers
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer
import org.springframework.security.web.header.writers.CrossOriginEmbedderPolicyHeaderWriter
/**
* A Kotlin DSL to configure the [HttpSecurity] Cross-Origin-Embedder-Policy header using
* idiomatic Kotlin code.
*
* @author Marcus Da Coregio
* @since 5.7
* @property policy the policy to be used in the response header.
*/
@HeadersSecurityMarker
class CrossOriginEmbedderPolicyDsl {
var policy: CrossOriginEmbedderPolicyHeaderWriter.CrossOriginEmbedderPolicy? = null
internal fun get(): (HeadersConfigurer<HttpSecurity>.CrossOriginEmbedderPolicyConfig) -> Unit {
return { crossOriginEmbedderPolicy ->
policy?.also {
crossOriginEmbedderPolicy.policy(policy)
}
}
}
}

View File

@@ -0,0 +1,43 @@
/*
* Copyright 2002-2021 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
*
* https://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.annotation.web.headers
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer
import org.springframework.security.web.header.writers.CrossOriginOpenerPolicyHeaderWriter
/**
* A Kotlin DSL to configure the [HttpSecurity] Cross-Origin-Opener-Policy header using
* idiomatic Kotlin code.
*
* @author Marcus Da Coregio
* @since 5.7
* @property policy the policy to be used in the response header.
*/
@HeadersSecurityMarker
class CrossOriginOpenerPolicyDsl {
var policy: CrossOriginOpenerPolicyHeaderWriter.CrossOriginOpenerPolicy? = null
internal fun get(): (HeadersConfigurer<HttpSecurity>.CrossOriginOpenerPolicyConfig) -> Unit {
return { crossOriginOpenerPolicy ->
policy?.also {
crossOriginOpenerPolicy.policy(policy)
}
}
}
}

View File

@@ -0,0 +1,43 @@
/*
* Copyright 2002-2021 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
*
* https://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.annotation.web.headers
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer
import org.springframework.security.web.header.writers.CrossOriginResourcePolicyHeaderWriter
/**
* A Kotlin DSL to configure the [HttpSecurity] Cross-Origin-Resource-Policy header using
* idiomatic Kotlin code.
*
* @author Marcus Da Coregio
* @since 5.7
* @property policy the policy to be used in the response header.
*/
@HeadersSecurityMarker
class CrossOriginResourcePolicyDsl {
var policy: CrossOriginResourcePolicyHeaderWriter.CrossOriginResourcePolicy? = null
internal fun get(): (HeadersConfigurer<HttpSecurity>.CrossOriginResourcePolicyConfig) -> Unit {
return { crossOriginResourcePolicy ->
policy?.also {
crossOriginResourcePolicy.policy(policy)
}
}
}
}

View File

@@ -0,0 +1,42 @@
/*
* Copyright 2002-2021 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
*
* https://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.config.annotation.web.builders.HttpSecurity
import org.springframework.security.web.server.header.CrossOriginEmbedderPolicyServerHttpHeadersWriter
/**
* A Kotlin DSL to configure the [HttpSecurity] Cross-Origin-Embedder-Policy header using
* idiomatic Kotlin code.
*
* @author Marcus Da Coregio
* @since 5.7
* @property policy the policy to be used in the response header.
*/
@ServerSecurityMarker
class ServerCrossOriginEmbedderPolicyDsl {
var policy: CrossOriginEmbedderPolicyServerHttpHeadersWriter.CrossOriginEmbedderPolicy? = null
internal fun get(): (ServerHttpSecurity.HeaderSpec.CrossOriginEmbedderPolicySpec) -> Unit {
return { crossOriginEmbedderPolicy ->
policy?.also {
crossOriginEmbedderPolicy.policy(policy)
}
}
}
}

View File

@@ -0,0 +1,42 @@
/*
* Copyright 2002-2021 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
*
* https://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.config.annotation.web.builders.HttpSecurity
import org.springframework.security.web.server.header.CrossOriginOpenerPolicyServerHttpHeadersWriter
/**
* A Kotlin DSL to configure the [HttpSecurity] Cross-Origin-Opener-Policy header using
* idiomatic Kotlin code.
*
* @author Marcus Da Coregio
* @since 5.7
* @property policy the policy to be used in the response header.
*/
@ServerSecurityMarker
class ServerCrossOriginOpenerPolicyDsl {
var policy: CrossOriginOpenerPolicyServerHttpHeadersWriter.CrossOriginOpenerPolicy? = null
internal fun get(): (ServerHttpSecurity.HeaderSpec.CrossOriginOpenerPolicySpec) -> Unit {
return { crossOriginOpenerPolicy ->
policy?.also {
crossOriginOpenerPolicy.policy(policy)
}
}
}
}

View File

@@ -0,0 +1,42 @@
/*
* Copyright 2002-2021 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
*
* https://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.config.annotation.web.builders.HttpSecurity
import org.springframework.security.web.server.header.CrossOriginResourcePolicyServerHttpHeadersWriter
/**
* A Kotlin DSL to configure the [HttpSecurity] Cross-Origin-Resource-Policy header using
* idiomatic Kotlin code.
*
* @author Marcus Da Coregio
* @since 5.7
* @property policy the policy to be used in the response header.
*/
@ServerSecurityMarker
class ServerCrossOriginResourcePolicyDsl {
var policy: CrossOriginResourcePolicyServerHttpHeadersWriter.CrossOriginResourcePolicy? = null
internal fun get(): (ServerHttpSecurity.HeaderSpec.CrossOriginResourcePolicySpec) -> Unit {
return { crossOriginResourcePolicy ->
policy?.also {
crossOriginResourcePolicy.policy(policy)
}
}
}
}

View File

@@ -16,7 +16,12 @@
package org.springframework.security.config.web.server
import org.springframework.security.web.server.header.*
import org.springframework.security.web.server.header.CacheControlServerHttpHeadersWriter
import org.springframework.security.web.server.header.ContentTypeOptionsServerHttpHeadersWriter
import org.springframework.security.web.server.header.ReferrerPolicyServerHttpHeadersWriter
import org.springframework.security.web.server.header.StrictTransportSecurityServerHttpHeadersWriter
import org.springframework.security.web.server.header.XFrameOptionsServerHttpHeadersWriter
import org.springframework.security.web.server.header.XXssProtectionServerHttpHeadersWriter
/**
* A Kotlin DSL to configure [ServerHttpSecurity] headers using idiomatic Kotlin code.
@@ -35,6 +40,9 @@ class ServerHeadersDsl {
private var referrerPolicy: ((ServerHttpSecurity.HeaderSpec.ReferrerPolicySpec) -> Unit)? = null
private var featurePolicyDirectives: String? = null
private var permissionsPolicy: ((ServerHttpSecurity.HeaderSpec.PermissionsPolicySpec) -> Unit)? = null
private var crossOriginOpenerPolicy: ((ServerHttpSecurity.HeaderSpec.CrossOriginOpenerPolicySpec) -> Unit)? = null
private var crossOriginEmbedderPolicy: ((ServerHttpSecurity.HeaderSpec.CrossOriginEmbedderPolicySpec) -> Unit)? = null
private var crossOriginResourcePolicy: ((ServerHttpSecurity.HeaderSpec.CrossOriginResourcePolicySpec) -> Unit)? = null
private var disabled = false
@@ -157,6 +165,39 @@ class ServerHeadersDsl {
this.permissionsPolicy = ServerPermissionsPolicyDsl().apply(permissionsPolicyConfig).get()
}
/**
* Allows configuration for <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Opener-Policy">
* Cross-Origin-Opener-Policy</a> header.
*
* @since 5.7
* @param crossOriginOpenerPolicyConfig the customization to apply to the header
*/
fun crossOriginOpenerPolicy(crossOriginOpenerPolicyConfig: ServerCrossOriginOpenerPolicyDsl.() -> Unit) {
this.crossOriginOpenerPolicy = ServerCrossOriginOpenerPolicyDsl().apply(crossOriginOpenerPolicyConfig).get()
}
/**
* Allows configuration for <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Embedder-Policy">
* Cross-Origin-Embedder-Policy</a> header.
*
* @since 5.7
* @param crossOriginEmbedderPolicyConfig the customization to apply to the header
*/
fun crossOriginEmbedderPolicy(crossOriginEmbedderPolicyConfig: ServerCrossOriginEmbedderPolicyDsl.() -> Unit) {
this.crossOriginEmbedderPolicy = ServerCrossOriginEmbedderPolicyDsl().apply(crossOriginEmbedderPolicyConfig).get()
}
/**
* Allows configuration for <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Resource-Policy">
* Cross-Origin-Resource-Policy</a> header.
*
* @since 5.7
* @param crossOriginResourcePolicyConfig the customization to apply to the header
*/
fun crossOriginResourcePolicy(crossOriginResourcePolicyConfig: ServerCrossOriginResourcePolicyDsl.() -> Unit) {
this.crossOriginResourcePolicy = ServerCrossOriginResourcePolicyDsl().apply(crossOriginResourcePolicyConfig).get()
}
/**
* Disables HTTP response headers.
*/
@@ -194,6 +235,15 @@ class ServerHeadersDsl {
referrerPolicy?.also {
headers.referrerPolicy(referrerPolicy)
}
crossOriginOpenerPolicy?.also {
headers.crossOriginOpenerPolicy(crossOriginOpenerPolicy)
}
crossOriginEmbedderPolicy?.also {
headers.crossOriginEmbedderPolicy(crossOriginEmbedderPolicy)
}
crossOriginResourcePolicy?.also {
headers.crossOriginResourcePolicy(crossOriginResourcePolicy)
}
if (disabled) {
headers.disable()
}

View File

@@ -943,7 +943,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? & referrer-policy? & feature-policy? & permissions-policy? & header*)}
element headers { headers-options.attlist, (cache-control? & xss-protection? & hsts? & frame-options? & content-type-options? & hpkp? & content-security-policy? & referrer-policy? & feature-policy? & permissions-policy? & cross-origin-opener-policy? & cross-origin-embedder-policy? & cross-origin-resource-policy? & header*)}
headers-options.attlist &=
## Specifies if the default headers should be disabled. Default false.
attribute defaults-disabled {xsd:token}?
@@ -1092,6 +1092,27 @@ content-type-options.attlist &=
## If disabled, the X-Content-Type-Options header will not be included. Default false.
attribute disabled {xsd:boolean}?
cross-origin-opener-policy =
## Adds support for Cross-Origin-Opener-Policy header
element cross-origin-opener-policy {cross-origin-opener-policy-options.attlist,empty}
cross-origin-opener-policy-options.attlist &=
## The policies for the Cross-Origin-Opener-Policy header.
attribute policy {"unsafe-none","same-origin","same-origin-allow-popups"}?
cross-origin-embedder-policy =
## Adds support for Cross-Origin-Embedder-Policy header
element cross-origin-embedder-policy {cross-origin-embedder-policy-options.attlist,empty}
cross-origin-embedder-policy-options.attlist &=
## The policies for the Cross-Origin-Embedder-Policy header.
attribute policy {"unsafe-none","require-corp"}?
cross-origin-resource-policy =
## Adds support for Cross-Origin-Resource-Policy header
element cross-origin-resource-policy {cross-origin-resource-policy-options.attlist,empty}
cross-origin-resource-policy-options.attlist &=
## The policies for the Cross-Origin-Resource-Policy header.
attribute policy {"cross-origin","same-origin","same-site"}?
header=
## Add additional headers to the response.
element header {header.attlist}

View File

@@ -2768,6 +2768,9 @@
<xs:element ref="security:referrer-policy"/>
<xs:element ref="security:feature-policy"/>
<xs:element ref="security:permissions-policy"/>
<xs:element ref="security:cross-origin-opener-policy"/>
<xs:element ref="security:cross-origin-embedder-policy"/>
<xs:element ref="security:cross-origin-resource-policy"/>
<xs:element ref="security:header"/>
</xs:choice>
<xs:attributeGroup ref="security:headers-options.attlist"/>
@@ -3151,6 +3154,77 @@
</xs:annotation>
</xs:attribute>
</xs:attributeGroup>
<xs:element name="cross-origin-opener-policy">
<xs:annotation>
<xs:documentation>Adds support for Cross-Origin-Opener-Policy header
</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:attributeGroup ref="security:cross-origin-opener-policy-options.attlist"/>
</xs:complexType>
</xs:element>
<xs:attributeGroup name="cross-origin-opener-policy-options.attlist">
<xs:attribute name="policy">
<xs:annotation>
<xs:documentation>The policies for the Cross-Origin-Opener-Policy header.
</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:token">
<xs:enumeration value="unsafe-none"/>
<xs:enumeration value="same-origin"/>
<xs:enumeration value="same-origin-allow-popups"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:attributeGroup>
<xs:element name="cross-origin-embedder-policy">
<xs:annotation>
<xs:documentation>Adds support for Cross-Origin-Embedder-Policy header
</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:attributeGroup ref="security:cross-origin-embedder-policy-options.attlist"/>
</xs:complexType>
</xs:element>
<xs:attributeGroup name="cross-origin-embedder-policy-options.attlist">
<xs:attribute name="policy">
<xs:annotation>
<xs:documentation>The policies for the Cross-Origin-Embedder-Policy header.
</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:token">
<xs:enumeration value="unsafe-none"/>
<xs:enumeration value="require-corp"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:attributeGroup>
<xs:element name="cross-origin-resource-policy">
<xs:annotation>
<xs:documentation>Adds support for Cross-Origin-Resource-Policy header
</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:attributeGroup ref="security:cross-origin-resource-policy-options.attlist"/>
</xs:complexType>
</xs:element>
<xs:attributeGroup name="cross-origin-resource-policy-options.attlist">
<xs:attribute name="policy">
<xs:annotation>
<xs:documentation>The policies for the Cross-Origin-Resource-Policy header.
</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:token">
<xs:enumeration value="cross-origin"/>
<xs:enumeration value="same-origin"/>
<xs:enumeration value="same-site"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:attributeGroup>
<xs:element name="header">
<xs:annotation>
<xs:documentation>Add additional headers to the response.