SEC-2230: Add Header JavaConfig

Added JavaConfig for Headers. In the process, more HeaderWriter instances
were added so that we can reuse logic between the XML and JavaConfig. This
also prompted repackaging the writers.
This commit is contained in:
Rob Winch
2013-07-30 16:56:46 -05:00
parent 988e97e366
commit 606bddf598
38 changed files with 1038 additions and 156 deletions

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.web.headers;
package org.springframework.security.web.header;
import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Mockito.verify;
@@ -28,6 +28,8 @@ import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.mock.web.MockFilterChain;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.web.header.HeaderWriter;
import org.springframework.security.web.header.HeaderWriterFilter;
/**
* Tests for the {@code HeadersFilter}
@@ -37,7 +39,7 @@ import org.springframework.mock.web.MockHttpServletResponse;
* @since 3.2
*/
@RunWith(MockitoJUnitRunner.class)
public class HeadersFilterTests {
public class HeaderWriterFilterTests {
@Mock
private HeaderWriter writer1;
@@ -47,12 +49,12 @@ public class HeadersFilterTests {
@Test(expected = IllegalArgumentException.class)
public void noHeadersConfigured() throws Exception {
List<HeaderWriter> headerWriters = new ArrayList<HeaderWriter>();
new HeadersFilter(headerWriters);
new HeaderWriterFilter(headerWriters);
}
@Test(expected = IllegalArgumentException.class)
public void constructorNullWriters() throws Exception {
new HeadersFilter(null);
new HeaderWriterFilter(null);
}
@Test
@@ -61,7 +63,7 @@ public class HeadersFilterTests {
headerWriters.add(writer1);
headerWriters.add(writer2);
HeadersFilter filter = new HeadersFilter(headerWriters);
HeaderWriterFilter filter = new HeaderWriterFilter(headerWriters);
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();

View File

@@ -0,0 +1,54 @@
/*
* Copyright 2002-2013 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 static org.fest.assertions.Assertions.assertThat;
import java.util.Arrays;
import org.junit.Before;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
/**
* @author Rob Winch
*
*/
public class CacheControlHeadersWriterTests {
private MockHttpServletRequest request;
private MockHttpServletResponse response;
private CacheControlHeadersWriter writer;
@Before
public void setup() {
request = new MockHttpServletRequest();
response = new MockHttpServletResponse();
writer = new CacheControlHeadersWriter();
}
@Test
public void writeHeaders() {
writer.writeHeaders(request, response);
assertThat(response.getHeaderNames().size()).isEqualTo(2);
assertThat(response.getHeaderValues("Cache-Control")).isEqualTo(Arrays.asList("no-cache","no-store","max-age=0","must-revalidate"));
assertThat(response.getHeaderValues("Pragma")).isEqualTo(Arrays.asList("no-cache"));
}
}

View File

@@ -13,9 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.web.headers;
package org.springframework.security.web.header.writers;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -27,6 +26,7 @@ import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.web.header.HeaderWriter;
import org.springframework.security.web.util.RequestMatcher;
/**

View File

@@ -0,0 +1,145 @@
/*
* Copyright 2002-2013 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 static org.fest.assertions.Assertions.assertThat;
import org.junit.Before;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.web.header.writers.HstsHeaderWriter;
import org.springframework.security.web.util.AnyRequestMatcher;
/**
* @author Rob Winch
*
*/
public class HstsHeaderWriterTests {
private MockHttpServletRequest request;
private MockHttpServletResponse response;
private HstsHeaderWriter writer;
@Before
public void setup() {
request = new MockHttpServletRequest();
request.setSecure(true);
response = new MockHttpServletResponse();
writer = new HstsHeaderWriter();
}
@Test
public void allArgsCustomConstructorWriteHeaders() {
request.setSecure(false);
writer = new HstsHeaderWriter(new AnyRequestMatcher(), 15768000, false);
writer.writeHeaders(request, response);
assertThat(response.getHeaderNames().size()).isEqualTo(1);
assertThat(response.getHeader("Strict-Transport-Security")).isEqualTo("max-age=15768000");
}
@Test
public void maxAgeAndIncludeSubdomainsCustomConstructorWriteHeaders() {
request.setSecure(false);
writer = new HstsHeaderWriter(new AnyRequestMatcher(), 15768000, false);
writer.writeHeaders(request, response);
assertThat(response.getHeaderNames().size()).isEqualTo(1);
assertThat(response.getHeader("Strict-Transport-Security")).isEqualTo("max-age=15768000");
}
@Test
public void maxAgeCustomConstructorWriteHeaders() {
writer = new HstsHeaderWriter(15768000);
writer.writeHeaders(request, response);
assertThat(response.getHeaderNames().size()).isEqualTo(1);
assertThat(response.getHeader("Strict-Transport-Security")).isEqualTo("max-age=15768000 ; includeSubDomains");
}
@Test
public void includeSubDomainsCustomConstructorWriteHeaders() {
writer = new HstsHeaderWriter(false);
writer.writeHeaders(request, response);
assertThat(response.getHeaderNames().size()).isEqualTo(1);
assertThat(response.getHeader("Strict-Transport-Security")).isEqualTo("max-age=31536000");
}
@Test
public void writeHeadersDefaultValues() {
writer.writeHeaders(request, response);
assertThat(response.getHeaderNames().size()).isEqualTo(1);
assertThat(response.getHeader("Strict-Transport-Security")).isEqualTo("max-age=31536000 ; includeSubDomains");
}
@Test
public void writeHeadersIncludeSubDomainsFalse() {
writer.setIncludeSubDomains(false);
writer.writeHeaders(request, response);
assertThat(response.getHeaderNames().size()).isEqualTo(1);
assertThat(response.getHeader("Strict-Transport-Security")).isEqualTo("max-age=31536000");
}
@Test
public void writeHeadersCustomMaxAgeInSeconds() {
writer.setMaxAgeInSeconds(1);
writer.writeHeaders(request, response);
assertThat(response.getHeaderNames().size()).isEqualTo(1);
assertThat(response.getHeader("Strict-Transport-Security")).isEqualTo("max-age=1 ; includeSubDomains");
}
@Test
public void writeHeadersInsecureRequestDoesNotWriteHeader() {
request.setSecure(false);
writer.writeHeaders(request, response);
assertThat(response.getHeaderNames().isEmpty()).isTrue();
}
@Test
public void writeHeadersAnyRequestMatcher() {
writer.setRequestMatcher(new AnyRequestMatcher());
request.setSecure(false);
writer.writeHeaders(request, response);
assertThat(response.getHeaderNames().size()).isEqualTo(1);
assertThat(response.getHeader("Strict-Transport-Security")).isEqualTo("max-age=31536000 ; includeSubDomains");
}
@Test(expected = IllegalArgumentException.class)
public void setMaxAgeInSecondsToNegative() {
writer.setMaxAgeInSeconds(-1);
}
@Test(expected = IllegalArgumentException.class)
public void setRequestMatcherToNull() {
writer.setRequestMatcher(null);
}
}

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.web.headers;
package org.springframework.security.web.header.writers;
import static org.fest.assertions.Assertions.assertThat;
@@ -24,6 +24,8 @@ import org.junit.Before;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.web.header.Header;
import org.springframework.security.web.header.writers.StaticHeadersWriter;
/**
* Test for the {@code StaticHeadersWriter}

View File

@@ -0,0 +1,53 @@
/*
* Copyright 2002-2013 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 static org.fest.assertions.Assertions.assertThat;
import java.util.Arrays;
import org.junit.Before;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
/**
* @author Rob Winch
*
*/
public class XContentTypeOptionsHeaderWriterTests {
private MockHttpServletRequest request;
private MockHttpServletResponse response;
private XContentTypeOptionsHeaderWriter writer;
@Before
public void setup() {
request = new MockHttpServletRequest();
response = new MockHttpServletResponse();
writer = new XContentTypeOptionsHeaderWriter();
}
@Test
public void writeHeaders() {
writer.writeHeaders(request, response);
assertThat(response.getHeaderNames().size()).isEqualTo(1);
assertThat(response.getHeaderValues("X-Content-Type-Options")).isEqualTo(Arrays.asList("nosniff"));
}
}

View File

@@ -13,10 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.web.headers;
package org.springframework.security.web.header.writers;
import static org.fest.assertions.Assertions.assertThat;
import java.util.Arrays;
import org.junit.Before;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest;
@@ -26,65 +28,66 @@ import org.springframework.mock.web.MockHttpServletResponse;
* @author Rob Winch
*
*/
public class HstsHeaderWriterTests {
public class XXssProtectionHeaderWriterTests {
private MockHttpServletRequest request;
private MockHttpServletResponse response;
private HstsHeaderWriter writer;
private XXssProtectionHeaderWriter writer;
@Before
public void setup() {
request = new MockHttpServletRequest();
request.setSecure(true);
response = new MockHttpServletResponse();
writer = new HstsHeaderWriter();
writer = new XXssProtectionHeaderWriter();
}
@Test
public void writeHeadersDefaultValues() {
public void writeHeaders() {
writer.writeHeaders(request, response);
assertThat(response.getHeaderNames().size()).isEqualTo(1);
assertThat(response.getHeader("Strict-Transport-Security")).isEqualTo("max-age=31536000 ; includeSubDomains");
assertThat(response.getHeaderValues("X-XSS-Protection")).isEqualTo(Arrays.asList("1; mode=block"));
}
@Test
public void writeHeadersIncludeSubDomainsFalse() {
writer.setIncludeSubDomains(false);
public void writeHeadersNoBlock() {
writer.setBlock(false);
writer.writeHeaders(request, response);
assertThat(response.getHeaderNames().size()).isEqualTo(1);
assertThat(response.getHeader("Strict-Transport-Security")).isEqualTo("max-age=31536000");
assertThat(response.getHeaderValues("X-XSS-Protection")).isEqualTo(Arrays.asList("1"));
}
@Test
public void writeHeadersCustomMaxAgeInSeconds() {
writer.setMaxAgeInSeconds(1);
public void writeHeadersDisabled() {
writer.setBlock(false);
writer.setEnabled(false);
writer.writeHeaders(request, response);
assertThat(response.getHeaderNames().size()).isEqualTo(1);
assertThat(response.getHeader("Strict-Transport-Security")).isEqualTo("max-age=1 ; includeSubDomains");
assertThat(response.getHeaderValues("X-XSS-Protection")).isEqualTo(Arrays.asList("0"));
}
@Test
public void writeHeadersInsecureRequestDoesNotWriteHeader() {
request.setSecure(false);
public void setEnabledFalseWithBlockTrue() {
writer.setEnabled(false);
writer.writeHeaders(request, response);
assertThat(response.getHeaderNames().isEmpty()).isTrue();
assertThat(response.getHeaderNames().size()).isEqualTo(1);
assertThat(response.getHeaderValues("X-XSS-Protection")).isEqualTo(Arrays.asList("0"));
}
@Test(expected = IllegalArgumentException.class)
public void setMaxAgeInSecondsToNegative() {
writer.setMaxAgeInSeconds(-1);
}
@Test(expected = IllegalArgumentException.class)
public void setRequestMatcherToNull() {
writer.setRequestMatcher(null);
@Test(expected=IllegalArgumentException.class)
public void setBlockTrueWithEnabledFalse() {
writer.setBlock(false);
writer.setEnabled(false);
writer.setBlock(true);
}
}

View File

@@ -13,13 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.web.headers.frameoptions;
package org.springframework.security.web.header.writers.frameoptions;
import static org.fest.assertions.Assertions.assertThat;
import org.junit.Before;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.security.web.header.writers.frameoptions.AbstractRequestParameterAllowFromStrategy;
/**
* @author Rob Winch

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.web.headers.frameoptions;
package org.springframework.security.web.header.writers.frameoptions;
import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Mockito.when;
@@ -27,7 +27,9 @@ import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.web.headers.frameoptions.XFrameOptionsHeaderWriter.XFrameOptionsMode;
import org.springframework.security.web.header.writers.frameoptions.AllowFromStrategy;
import org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter;
import org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter.XFrameOptionsMode;
/**
* @author Rob Winch

View File

@@ -1,4 +1,4 @@
package org.springframework.security.web.headers.frameoptions;
package org.springframework.security.web.header.writers.frameoptions;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
@@ -7,6 +7,7 @@ import java.util.regex.PatternSyntaxException;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.security.web.header.writers.frameoptions.RegExpAllowFromStrategy;
/**
*

View File

@@ -1,7 +1,8 @@
package org.springframework.security.web.headers.frameoptions;
package org.springframework.security.web.header.writers.frameoptions;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.security.web.header.writers.frameoptions.StaticAllowFromStrategy;
import java.net.URI;

View File

@@ -1,7 +1,8 @@
package org.springframework.security.web.headers.frameoptions;
package org.springframework.security.web.header.writers.frameoptions;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.security.web.header.writers.frameoptions.WhiteListedAllowFromStrategy;
import java.util.ArrayList;
import java.util.List;