mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-05-31 09:12:14 +00:00
Introduced placeholder support for Headers tag attributes
Added the functionality to allow the disabled and defaults-disabled attribute of <header> tag to accept a placeholder and resolve it during parsing. - Updated the spring-security .rnc files starting from 4.2 up to 5.2 with xsd:token type instead of boolean - Added unit tests for headers.disabled and headers.defaults-disabled attributes with placeholder - Modified the HeadersBeanDefinitionParser to support resolving placeholders - Updated spring.schemas to point to latest spring-security-5.2.xsd Fixes gh-6547
This commit is contained in:
parent
bfe1e6a154
commit
3617fd257e
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2019 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.
|
||||
@ -49,6 +49,7 @@ import org.w3c.dom.Node;
|
||||
* @author Tim Ysewyn
|
||||
* @author Eddú Meléndez
|
||||
* @author Vedran Pavic
|
||||
* @author Rafiullah Hamedy
|
||||
* @since 3.2
|
||||
*/
|
||||
public class HeadersBeanDefinitionParser implements BeanDefinitionParser {
|
||||
@ -95,14 +96,15 @@ public class HeadersBeanDefinitionParser implements BeanDefinitionParser {
|
||||
private ManagedList<BeanMetadataElement> headerWriters;
|
||||
|
||||
public BeanDefinition parse(Element element, ParserContext parserContext) {
|
||||
|
||||
headerWriters = new ManagedList<>();
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder
|
||||
.rootBeanDefinition(HeaderWriterFilter.class);
|
||||
|
||||
boolean disabled = element != null
|
||||
&& "true".equals(element.getAttribute("disabled"));
|
||||
&& "true".equals(resolveAttribute(parserContext, element, "disabled"));
|
||||
boolean defaultsDisabled = element != null
|
||||
&& "true".equals(element.getAttribute("defaults-disabled"));
|
||||
&& "true".equals(resolveAttribute(parserContext, element, "defaults-disabled"));
|
||||
|
||||
boolean addIfNotPresent = element == null || !disabled && !defaultsDisabled;
|
||||
|
||||
@ -136,6 +138,19 @@ public class HeadersBeanDefinitionParser implements BeanDefinitionParser {
|
||||
return builder.getBeanDefinition();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Resolve the placeholder for a given attribute on a element.
|
||||
*
|
||||
* @param pc
|
||||
* @param element
|
||||
* @param attributeName
|
||||
* @return Resolved value of the placeholder
|
||||
*/
|
||||
private String resolveAttribute(ParserContext pc, Element element, String attributeName) {
|
||||
return pc.getReaderContext().getEnvironment().resolvePlaceholders(element.getAttribute(attributeName));
|
||||
}
|
||||
|
||||
private void parseCacheControlElement(boolean addIfNotPresent, Element element) {
|
||||
Element cacheControlElement = element == null ? null : DomUtils
|
||||
.getChildElementByTagName(element, CACHE_CONTROL_ELEMENT);
|
||||
|
@ -1,4 +1,5 @@
|
||||
http\://www.springframework.org/schema/security/spring-security.xsd=org/springframework/security/config/spring-security-5.1.xsd
|
||||
http\://www.springframework.org/schema/security/spring-security.xsd=org/springframework/security/config/spring-security-5.2.xsd
|
||||
http\://www.springframework.org/schema/security/spring-security-5.2.xsd=org/springframework/security/config/spring-security-5.2.xsd
|
||||
http\://www.springframework.org/schema/security/spring-security-5.1.xsd=org/springframework/security/config/spring-security-5.1.xsd
|
||||
http\://www.springframework.org/schema/security/spring-security-5.0.xsd=org/springframework/security/config/spring-security-5.0.xsd
|
||||
http\://www.springframework.org/schema/security/spring-security-4.2.xsd=org/springframework/security/config/spring-security-4.2.xsd
|
||||
|
@ -746,10 +746,10 @@ headers =
|
||||
element headers { headers-options.attlist, (cache-control? & xss-protection? & hsts? & frame-options? & content-type-options? & hpkp? & content-security-policy? & referrer-policy? & feature-policy? & header*)}
|
||||
headers-options.attlist &=
|
||||
## Specifies if the default headers should be disabled. Default false.
|
||||
attribute defaults-disabled {xsd:boolean}?
|
||||
attribute defaults-disabled {xsd:token}?
|
||||
headers-options.attlist &=
|
||||
## Specifies if headers should be disabled. Default false.
|
||||
attribute disabled {xsd:boolean}?
|
||||
attribute disabled {xsd:token}?
|
||||
hsts =
|
||||
## Adds support for HTTP Strict Transport Security (HSTS)
|
||||
element hsts {hsts-options.attlist}
|
||||
|
@ -2261,13 +2261,13 @@
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:attributeGroup name="headers-options.attlist">
|
||||
<xs:attribute name="defaults-disabled" type="xs:boolean">
|
||||
<xs:attribute name="defaults-disabled" type="xs:token">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Specifies if the default headers should be disabled. Default false.
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="disabled" type="xs:boolean">
|
||||
<xs:attribute name="disabled" type="xs:token">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Specifies if headers should be disabled. Default false.
|
||||
</xs:documentation>
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2019 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.
|
||||
@ -45,6 +45,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
||||
* @author Rob Winch
|
||||
* @author Tim Ysewyn
|
||||
* @author Josh Cummings
|
||||
* @author Rafiullah Hamedy
|
||||
*/
|
||||
public class HttpHeadersConfigTests {
|
||||
|
||||
@ -79,6 +80,45 @@ public class HttpHeadersConfigTests {
|
||||
.andExpect(excludesDefaults());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void requestWhenHeadersDisabledViaPlaceholderThenResponseExcludesAllSecureHeaders()
|
||||
throws Exception {
|
||||
|
||||
System.setProperty("security.headers.disabled", "true");
|
||||
|
||||
this.spring.configLocations(this.xml("DisabledWithPlaceholder")).autowire();
|
||||
|
||||
this.mvc.perform(get("/").secure(true))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(excludesDefaults());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void requestWhenHeadersEnabledViaPlaceholderThenResponseIncludesAllSecureHeaders()
|
||||
throws Exception {
|
||||
|
||||
System.setProperty("security.headers.disabled", "false");
|
||||
|
||||
this.spring.configLocations(this.xml("DisabledWithPlaceholder")).autowire();
|
||||
|
||||
this.mvc.perform(get("/").secure(true))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(includesDefaults());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void requestWhenHeadersDisabledRefMissingPlaceholderThenResponseIncludesAllSecureHeaders()
|
||||
throws Exception {
|
||||
|
||||
System.clearProperty("security.headers.disabled");
|
||||
|
||||
this.spring.configLocations(this.xml("DisabledWithPlaceholder")).autowire();
|
||||
|
||||
this.mvc.perform(get("/").secure(true))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(includesDefaults());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void configureWhenHeadersDisabledHavingChildElementThenAutowireFails() {
|
||||
assertThatThrownBy(() ->
|
||||
@ -139,6 +179,45 @@ public class HttpHeadersConfigTests {
|
||||
.andExpect(excludesDefaults());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void requestWhenDefaultsDisabledWithPlaceholderTrueThenExcludesAllSecureHeaders()
|
||||
throws Exception {
|
||||
|
||||
System.setProperty("security.headers.defaults.disabled", "true");
|
||||
|
||||
this.spring.configLocations(this.xml("DefaultsDisabledWithPlaceholder")).autowire();
|
||||
|
||||
this.mvc.perform(get("/").secure(true))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(excludesDefaults());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void requestWhenDefaultsDisabledWithPlaceholderFalseThenIncludeAllSecureHeaders()
|
||||
throws Exception {
|
||||
|
||||
System.setProperty("security.headers.defaults.disabled", "false");
|
||||
|
||||
this.spring.configLocations(this.xml("DefaultsDisabledWithPlaceholder")).autowire();
|
||||
|
||||
this.mvc.perform(get("/").secure(true))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(includesDefaults());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void requestWhenDefaultsDisabledWithPlaceholderMissingThenIncludeAllSecureHeaders()
|
||||
throws Exception {
|
||||
|
||||
System.clearProperty("security.headers.defaults.disabled");
|
||||
|
||||
this.spring.configLocations(this.xml("DefaultsDisabledWithPlaceholder")).autowire();
|
||||
|
||||
this.mvc.perform(get("/").secure(true))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(includesDefaults());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void requestWhenUsingContentTypeOptionsThenDefaultsToNoSniff()
|
||||
throws Exception {
|
||||
|
@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 2002-2019 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.
|
||||
-->
|
||||
|
||||
<b:beans xmlns:b="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://www.springframework.org/schema/security"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/security
|
||||
http://www.springframework.org/schema/security/spring-security.xsd
|
||||
http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
<http auto-config="true">
|
||||
<headers defaults-disabled="${security.headers.defaults.disabled}"/>
|
||||
</http>
|
||||
|
||||
<b:bean name="propertyPlaceholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/>
|
||||
|
||||
<b:bean name="simple" class="org.springframework.security.config.http.HttpHeadersConfigTests.SimpleController"/>
|
||||
|
||||
<b:import resource="userservice.xml"/>
|
||||
</b:beans>
|
@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 2002-2019 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.
|
||||
-->
|
||||
|
||||
<b:beans xmlns:b="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://www.springframework.org/schema/security"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/security
|
||||
http://www.springframework.org/schema/security/spring-security.xsd
|
||||
http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
<http auto-config="true">
|
||||
<headers disabled="${security.headers.disabled}" />
|
||||
</http>
|
||||
|
||||
<b:bean name="propertyPlaceholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/>
|
||||
|
||||
<b:bean name="simple" class="org.springframework.security.config.http.HttpHeadersConfigTests.SimpleController"/>
|
||||
|
||||
<b:import resource="userservice.xml"/>
|
||||
</b:beans>
|
Loading…
x
Reference in New Issue
Block a user