@ -20,6 +20,7 @@ import java.net.URISyntaxException;
@@ -20,6 +20,7 @@ import java.net.URISyntaxException;
import java.util.List ;
import java.util.regex.PatternSyntaxException ;
import org.springframework.beans.BeanMetadataElement ;
import org.springframework.beans.factory.config.BeanDefinition ;
import org.springframework.beans.factory.config.RuntimeBeanReference ;
import org.springframework.beans.factory.support.BeanDefinitionBuilder ;
@ -76,10 +77,10 @@ public class HeadersBeanDefinitionParser implements BeanDefinitionParser {
@@ -76,10 +77,10 @@ public class HeadersBeanDefinitionParser implements BeanDefinitionParser {
private static final String ALLOW_FROM = "ALLOW-FROM" ;
private ManagedList headerWriters ;
private ManagedList < BeanMetadataElement > headerWriters ;
public BeanDefinition parse ( Element element , ParserContext parserContext ) {
headerWriters = new ManagedList ( ) ;
headerWriters = new ManagedList < BeanMetadataElement > ( ) ;
BeanDefinitionBuilder builder = BeanDefinitionBuilder . rootBeanDefinition ( HeadersFilter . class ) ;
parseCacheControlElement ( element ) ;
@ -91,8 +92,18 @@ public class HeadersBeanDefinitionParser implements BeanDefinitionParser {
@@ -91,8 +92,18 @@ public class HeadersBeanDefinitionParser implements BeanDefinitionParser {
parseHeaderElements ( element ) ;
if ( headerWriters . isEmpty ( ) ) {
parserContext . getReaderContext ( ) . error ( "At least one type of header must be specified when using <headers>" ,
element ) ;
addCacheControl ( ) ;
addHsts ( null ) ;
addContentTypeOptions ( ) ;
BeanDefinitionBuilder frameOptions = BeanDefinitionBuilder . genericBeanDefinition ( XFrameOptionsHeaderWriter . class ) ;
frameOptions . addConstructorArgValue ( "DENY" ) ;
headerWriters . add ( frameOptions . getBeanDefinition ( ) ) ;
BeanDefinitionBuilder xss = BeanDefinitionBuilder . genericBeanDefinition ( StaticHeadersWriter . class ) ;
xss . addConstructorArgValue ( XSS_PROTECTION_HEADER ) ;
xss . addConstructorArgValue ( "1; mode=block" ) ;
headerWriters . add ( xss . getBeanDefinition ( ) ) ;
}
builder . addConstructorArgValue ( headerWriters ) ;
return builder . getBeanDefinition ( ) ;
@ -101,36 +112,46 @@ public class HeadersBeanDefinitionParser implements BeanDefinitionParser {
@@ -101,36 +112,46 @@ public class HeadersBeanDefinitionParser implements BeanDefinitionParser {
private void parseCacheControlElement ( Element element ) {
Element cacheControlElement = DomUtils . getChildElementByTagName ( element , CACHE_CONTROL_ELEMENT ) ;
if ( cacheControlElement ! = null ) {
ManagedList < BeanDefinition > headers = new ManagedList < BeanDefinition > ( ) ;
BeanDefinitionBuilder pragmaHeader = BeanDefinitionBuilder . genericBeanDefinition ( Header . class ) ;
pragmaHeader . addConstructorArgValue ( "Pragma" ) ;
ManagedList < String > pragmaValues = new ManagedList < String > ( ) ;
pragmaValues . add ( "no-cache" ) ;
pragmaHeader . addConstructorArgValue ( pragmaValues ) ;
headers . add ( pragmaHeader . getBeanDefinition ( ) ) ;
BeanDefinitionBuilder cacheControlHeader = BeanDefinitionBuilder . genericBeanDefinition ( Header . class ) ;
cacheControlHeader . addConstructorArgValue ( "Cache-Control" ) ;
ManagedList < String > cacheControlValues = new ManagedList < String > ( ) ;
cacheControlValues . add ( "no-cache" ) ;
cacheControlValues . add ( "no-store" ) ;
cacheControlValues . add ( "max-age=0" ) ;
cacheControlValues . add ( "must-revalidate" ) ;
cacheControlHeader . addConstructorArgValue ( cacheControlValues ) ;
headers . add ( cacheControlHeader . getBeanDefinition ( ) ) ;
BeanDefinitionBuilder headersWriter = BeanDefinitionBuilder . genericBeanDefinition ( StaticHeadersWriter . class ) ;
headersWriter . addConstructorArgValue ( headers ) ;
headerWriters . add ( headersWriter . getBeanDefinition ( ) ) ;
addCacheControl ( ) ;
}
}
private void addCacheControl ( ) {
ManagedList < BeanDefinition > headers = new ManagedList < BeanDefinition > ( ) ;
BeanDefinitionBuilder pragmaHeader = BeanDefinitionBuilder . genericBeanDefinition ( Header . class ) ;
pragmaHeader . addConstructorArgValue ( "Pragma" ) ;
ManagedList < String > pragmaValues = new ManagedList < String > ( ) ;
pragmaValues . add ( "no-cache" ) ;
pragmaHeader . addConstructorArgValue ( pragmaValues ) ;
headers . add ( pragmaHeader . getBeanDefinition ( ) ) ;
BeanDefinitionBuilder cacheControlHeader = BeanDefinitionBuilder . genericBeanDefinition ( Header . class ) ;
cacheControlHeader . addConstructorArgValue ( "Cache-Control" ) ;
ManagedList < String > cacheControlValues = new ManagedList < String > ( ) ;
cacheControlValues . add ( "no-cache" ) ;
cacheControlValues . add ( "no-store" ) ;
cacheControlValues . add ( "max-age=0" ) ;
cacheControlValues . add ( "must-revalidate" ) ;
cacheControlHeader . addConstructorArgValue ( cacheControlValues ) ;
headers . add ( cacheControlHeader . getBeanDefinition ( ) ) ;
BeanDefinitionBuilder headersWriter = BeanDefinitionBuilder . genericBeanDefinition ( StaticHeadersWriter . class ) ;
headersWriter . addConstructorArgValue ( headers ) ;
headerWriters . add ( headersWriter . getBeanDefinition ( ) ) ;
}
private void parseHstsElement ( Element element ) {
Element hstsElement = DomUtils . getChildElementByTagName ( element , HSTS_ELEMENT ) ;
if ( hstsElement ! = null ) {
BeanDefinitionBuilder headersWriter = BeanDefinitionBuilder . genericBeanDefinition ( HstsHeaderWriter . class ) ;
addHsts ( hstsElement ) ;
}
}
private void addHsts ( Element hstsElement ) {
BeanDefinitionBuilder headersWriter = BeanDefinitionBuilder . genericBeanDefinition ( HstsHeaderWriter . class ) ;
if ( hstsElement ! = null ) {
String includeSubDomains = hstsElement . getAttribute ( ATT_INCLUDE_SUBDOMAINS ) ;
if ( StringUtils . hasText ( includeSubDomains ) ) {
headersWriter . addPropertyValue ( "includeSubDomains" , includeSubDomains ) ;
@ -143,8 +164,8 @@ public class HeadersBeanDefinitionParser implements BeanDefinitionParser {
@@ -143,8 +164,8 @@ public class HeadersBeanDefinitionParser implements BeanDefinitionParser {
if ( StringUtils . hasText ( requestMatcherRef ) ) {
headersWriter . addPropertyReference ( "requestMatcher" , requestMatcherRef ) ;
}
headerWriters . add ( headersWriter . getBeanDefinition ( ) ) ;
}
headerWriters . add ( headersWriter . getBeanDefinition ( ) ) ;
}
private void parseHeaderElements ( Element element ) {
@ -165,13 +186,17 @@ public class HeadersBeanDefinitionParser implements BeanDefinitionParser {
@@ -165,13 +186,17 @@ public class HeadersBeanDefinitionParser implements BeanDefinitionParser {
private void parseContentTypeOptionsElement ( Element element ) {
Element contentTypeElt = DomUtils . getChildElementByTagName ( element , CONTENT_TYPE_ELEMENT ) ;
if ( contentTypeElt ! = null ) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder . genericBeanDefinition ( StaticHeadersWriter . class ) ;
builder . addConstructorArgValue ( CONTENT_TYPE_OPTIONS_HEADER ) ;
builder . addConstructorArgValue ( "nosniff" ) ;
headerWriters . add ( builder . getBeanDefinition ( ) ) ;
addContentTypeOptions ( ) ;
}
}
private void addContentTypeOptions ( ) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder . genericBeanDefinition ( StaticHeadersWriter . class ) ;
builder . addConstructorArgValue ( CONTENT_TYPE_OPTIONS_HEADER ) ;
builder . addConstructorArgValue ( "nosniff" ) ;
headerWriters . add ( builder . getBeanDefinition ( ) ) ;
}
private void parseFrameOptionsElement ( Element element , ParserContext parserContext ) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder . genericBeanDefinition ( XFrameOptionsHeaderWriter . class ) ;