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-Kousathana
parent 7ec3b55ab3
commit 65426a40ec
38 changed files with 2513 additions and 9 deletions

View File

@@ -0,0 +1,80 @@
/*
* 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.web.header.writers;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
class CrossOriginEmbedderPolicyHeaderWriterTests {
private static final String EMBEDDER_HEADER_NAME = "Cross-Origin-Embedder-Policy";
private CrossOriginEmbedderPolicyHeaderWriter writer;
private MockHttpServletRequest request;
private MockHttpServletResponse response;
@BeforeEach
void setup() {
this.writer = new CrossOriginEmbedderPolicyHeaderWriter();
this.request = new MockHttpServletRequest();
this.response = new MockHttpServletResponse();
}
@Test
void setEmbedderPolicyWhenNullEmbedderPolicyThenThrowsIllegalArgument() {
assertThatIllegalArgumentException().isThrownBy(() -> this.writer.setPolicy(null))
.withMessage("embedderPolicy cannot be null");
}
@Test
void writeHeadersWhenDefaultValuesThenDontWriteHeaders() {
this.writer.writeHeaders(this.request, this.response);
assertThat(this.response.getHeaderNames()).hasSize(0);
}
@Test
void writeHeadersWhenResponseHeaderExistsThenDontOverride() {
this.response.addHeader(EMBEDDER_HEADER_NAME, "require-corp");
this.writer.setPolicy(CrossOriginEmbedderPolicyHeaderWriter.CrossOriginEmbedderPolicy.UNSAFE_NONE);
this.writer.writeHeaders(this.request, this.response);
assertThat(this.response.getHeader(EMBEDDER_HEADER_NAME)).isEqualTo("require-corp");
}
@Test
void writeHeadersWhenSetHeaderValuesThenWrites() {
this.writer.setPolicy(CrossOriginEmbedderPolicyHeaderWriter.CrossOriginEmbedderPolicy.REQUIRE_CORP);
this.writer.writeHeaders(this.request, this.response);
assertThat(this.response.getHeader(EMBEDDER_HEADER_NAME)).isEqualTo("require-corp");
}
@Test
void writeHeadersWhenSetEmbedderPolicyThenWritesEmbedderPolicy() {
this.writer.setPolicy(CrossOriginEmbedderPolicyHeaderWriter.CrossOriginEmbedderPolicy.UNSAFE_NONE);
this.writer.writeHeaders(this.request, this.response);
assertThat(this.response.getHeaderNames()).hasSize(1);
assertThat(this.response.getHeader(EMBEDDER_HEADER_NAME)).isEqualTo("unsafe-none");
}
}

View File

@@ -0,0 +1,80 @@
/*
* 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.web.header.writers;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
class CrossOriginOpenerPolicyHeaderWriterTests {
private static final String OPENER_HEADER_NAME = "Cross-Origin-Opener-Policy";
private CrossOriginOpenerPolicyHeaderWriter writer;
private MockHttpServletRequest request;
private MockHttpServletResponse response;
@BeforeEach
void setup() {
this.writer = new CrossOriginOpenerPolicyHeaderWriter();
this.request = new MockHttpServletRequest();
this.response = new MockHttpServletResponse();
}
@Test
void setOpenerPolicyWhenNullOpenerPolicyThenThrowsIllegalArgument() {
assertThatIllegalArgumentException().isThrownBy(() -> this.writer.setPolicy(null))
.withMessage("openerPolicy cannot be null");
}
@Test
void writeHeadersWhenDefaultValuesThenDontWriteHeaders() {
this.writer.writeHeaders(this.request, this.response);
assertThat(this.response.getHeaderNames()).hasSize(0);
}
@Test
void writeHeadersWhenResponseHeaderExistsThenDontOverride() {
this.response.addHeader(OPENER_HEADER_NAME, "same-origin");
this.writer.setPolicy(CrossOriginOpenerPolicyHeaderWriter.CrossOriginOpenerPolicy.SAME_ORIGIN_ALLOW_POPUPS);
this.writer.writeHeaders(this.request, this.response);
assertThat(this.response.getHeader(OPENER_HEADER_NAME)).isEqualTo("same-origin");
}
@Test
void writeHeadersWhenSetHeaderValuesThenWrites() {
this.writer.setPolicy(CrossOriginOpenerPolicyHeaderWriter.CrossOriginOpenerPolicy.SAME_ORIGIN_ALLOW_POPUPS);
this.writer.writeHeaders(this.request, this.response);
assertThat(this.response.getHeader(OPENER_HEADER_NAME)).isEqualTo("same-origin-allow-popups");
}
@Test
void writeHeadersWhenSetOpenerPolicyThenWritesOpenerPolicy() {
this.writer.setPolicy(CrossOriginOpenerPolicyHeaderWriter.CrossOriginOpenerPolicy.SAME_ORIGIN_ALLOW_POPUPS);
this.writer.writeHeaders(this.request, this.response);
assertThat(this.response.getHeaderNames()).hasSize(1);
assertThat(this.response.getHeader(OPENER_HEADER_NAME)).isEqualTo("same-origin-allow-popups");
}
}

View File

@@ -0,0 +1,80 @@
/*
* 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.web.header.writers;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
class CrossOriginResourcePolicyHeaderWriterTests {
private static final String RESOURCE_HEADER_NAME = "Cross-Origin-Resource-Policy";
private CrossOriginResourcePolicyHeaderWriter writer;
private MockHttpServletRequest request;
private MockHttpServletResponse response;
@BeforeEach
void setup() {
this.writer = new CrossOriginResourcePolicyHeaderWriter();
this.request = new MockHttpServletRequest();
this.response = new MockHttpServletResponse();
}
@Test
void setResourcePolicyWhenNullThenThrowsIllegalArgument() {
assertThatIllegalArgumentException().isThrownBy(() -> this.writer.setPolicy(null))
.withMessage("resourcePolicy cannot be null");
}
@Test
void writeHeadersWhenDefaultValuesThenDontWriteHeaders() {
this.writer.writeHeaders(this.request, this.response);
assertThat(this.response.getHeaderNames()).hasSize(0);
}
@Test
void writeHeadersWhenResponseHeaderExistsThenDontOverride() {
this.response.addHeader(RESOURCE_HEADER_NAME, "same-site");
this.writer.setPolicy(CrossOriginResourcePolicyHeaderWriter.CrossOriginResourcePolicy.CROSS_ORIGIN);
this.writer.writeHeaders(this.request, this.response);
assertThat(this.response.getHeader(RESOURCE_HEADER_NAME)).isEqualTo("same-site");
}
@Test
void writeHeadersWhenSetHeaderValuesThenWrites() {
this.writer.setPolicy(CrossOriginResourcePolicyHeaderWriter.CrossOriginResourcePolicy.SAME_ORIGIN);
this.writer.writeHeaders(this.request, this.response);
assertThat(this.response.getHeader(RESOURCE_HEADER_NAME)).isEqualTo("same-origin");
}
@Test
void writeHeadersWhenSetResourcePolicyThenWritesResourcePolicy() {
this.writer.setPolicy(CrossOriginResourcePolicyHeaderWriter.CrossOriginResourcePolicy.SAME_SITE);
this.writer.writeHeaders(this.request, this.response);
assertThat(this.response.getHeaderNames()).hasSize(1);
assertThat(this.response.getHeader(RESOURCE_HEADER_NAME)).isEqualTo("same-site");
}
}

View File

@@ -0,0 +1,76 @@
/*
* 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.web.server.header;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.http.HttpHeaders;
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
import org.springframework.mock.web.server.MockServerWebExchange;
import org.springframework.web.server.ServerWebExchange;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
class CrossOriginEmbedderPolicyServerHttpHeadersWriterTests {
private ServerWebExchange exchange;
private CrossOriginEmbedderPolicyServerHttpHeadersWriter writer;
@BeforeEach
void setup() {
this.exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/"));
this.writer = new CrossOriginEmbedderPolicyServerHttpHeadersWriter();
}
@Test
void setEmbedderPolicyWhenNullEmbedderPolicyThenThrowsIllegalArgument() {
assertThatIllegalArgumentException().isThrownBy(() -> this.writer.setPolicy(null))
.withMessage("embedderPolicy cannot be null");
}
@Test
void writeHeadersWhenNoValuesThenDoesNotWriteHeaders() {
this.writer.writeHttpHeaders(this.exchange);
HttpHeaders headers = this.exchange.getResponse().getHeaders();
assertThat(headers).isEmpty();
}
@Test
void writeHeadersWhenResponseHeaderExistsThenDontOverride() {
this.exchange.getResponse().getHeaders().add(CrossOriginEmbedderPolicyServerHttpHeadersWriter.EMBEDDER_POLICY,
"require-corp");
this.writer.writeHttpHeaders(this.exchange);
HttpHeaders headers = this.exchange.getResponse().getHeaders();
assertThat(headers).hasSize(1);
assertThat(headers.get(CrossOriginEmbedderPolicyServerHttpHeadersWriter.EMBEDDER_POLICY))
.containsOnly("require-corp");
}
@Test
void writeHeadersWhenSetHeaderValuesThenWrites() {
this.writer.setPolicy(CrossOriginEmbedderPolicyServerHttpHeadersWriter.CrossOriginEmbedderPolicy.REQUIRE_CORP);
this.writer.writeHttpHeaders(this.exchange);
HttpHeaders headers = this.exchange.getResponse().getHeaders();
assertThat(headers).hasSize(1);
assertThat(headers.get(CrossOriginEmbedderPolicyServerHttpHeadersWriter.EMBEDDER_POLICY))
.containsOnly("require-corp");
}
}

View File

@@ -0,0 +1,77 @@
/*
* 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.web.server.header;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.http.HttpHeaders;
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
import org.springframework.mock.web.server.MockServerWebExchange;
import org.springframework.web.server.ServerWebExchange;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
class CrossOriginOpenerPolicyServerHttpHeadersWriterTests {
private ServerWebExchange exchange;
private CrossOriginOpenerPolicyServerHttpHeadersWriter writer;
@BeforeEach
void setup() {
this.exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/"));
this.writer = new CrossOriginOpenerPolicyServerHttpHeadersWriter();
}
@Test
void setOpenerPolicyWhenNullOpenerPolicyThenThrowsIllegalArgument() {
assertThatIllegalArgumentException().isThrownBy(() -> this.writer.setPolicy(null))
.withMessage("openerPolicy cannot be null");
}
@Test
void writeHeadersWhenNoValuesThenDoesNotWriteHeaders() {
this.writer.writeHttpHeaders(this.exchange);
HttpHeaders headers = this.exchange.getResponse().getHeaders();
assertThat(headers).isEmpty();
}
@Test
void writeHeadersWhenResponseHeaderExistsThenDontOverride() {
this.exchange.getResponse().getHeaders().add(CrossOriginOpenerPolicyServerHttpHeadersWriter.OPENER_POLICY,
"same-origin");
this.writer.writeHttpHeaders(this.exchange);
HttpHeaders headers = this.exchange.getResponse().getHeaders();
assertThat(headers).hasSize(1);
assertThat(headers.get(CrossOriginOpenerPolicyServerHttpHeadersWriter.OPENER_POLICY))
.containsOnly("same-origin");
}
@Test
void writeHeadersWhenSetHeaderValuesThenWrites() {
this.writer.setPolicy(
CrossOriginOpenerPolicyServerHttpHeadersWriter.CrossOriginOpenerPolicy.SAME_ORIGIN_ALLOW_POPUPS);
this.writer.writeHttpHeaders(this.exchange);
HttpHeaders headers = this.exchange.getResponse().getHeaders();
assertThat(headers).hasSize(1);
assertThat(headers.get(CrossOriginOpenerPolicyServerHttpHeadersWriter.OPENER_POLICY))
.containsOnly("same-origin-allow-popups");
}
}

View File

@@ -0,0 +1,76 @@
/*
* 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.web.server.header;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.http.HttpHeaders;
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
import org.springframework.mock.web.server.MockServerWebExchange;
import org.springframework.web.server.ServerWebExchange;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
class CrossOriginResourcePolicyServerHttpHeadersWriterTests {
private ServerWebExchange exchange;
private CrossOriginResourcePolicyServerHttpHeadersWriter writer;
@BeforeEach
void setup() {
this.exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/"));
this.writer = new CrossOriginResourcePolicyServerHttpHeadersWriter();
}
@Test
void setResourcePolicyWhenNullThenThrowsIllegalArgument() {
assertThatIllegalArgumentException().isThrownBy(() -> this.writer.setPolicy(null))
.withMessage("resourcePolicy cannot be null");
}
@Test
void writeHeadersWhenNoValuesThenDoesNotWriteHeaders() {
this.writer.writeHttpHeaders(this.exchange);
HttpHeaders headers = this.exchange.getResponse().getHeaders();
assertThat(headers).isEmpty();
}
@Test
void writeHeadersWhenResponseHeaderExistsThenDontOverride() {
this.exchange.getResponse().getHeaders().add(CrossOriginResourcePolicyServerHttpHeadersWriter.RESOURCE_POLICY,
"same-origin");
this.writer.writeHttpHeaders(this.exchange);
HttpHeaders headers = this.exchange.getResponse().getHeaders();
assertThat(headers).hasSize(1);
assertThat(headers.get(CrossOriginResourcePolicyServerHttpHeadersWriter.RESOURCE_POLICY))
.containsOnly("same-origin");
}
@Test
void writeHeadersWhenSetHeaderValuesThenWrites() {
this.writer.setPolicy(CrossOriginResourcePolicyServerHttpHeadersWriter.CrossOriginResourcePolicy.SAME_ORIGIN);
this.writer.writeHttpHeaders(this.exchange);
HttpHeaders headers = this.exchange.getResponse().getHeaders();
assertThat(headers).hasSize(1);
assertThat(headers.get(CrossOriginResourcePolicyServerHttpHeadersWriter.RESOURCE_POLICY))
.containsOnly("same-origin");
}
}