SEC-2230: HTTP Strict Transport Security (HSTS)Add support for Strict
This is a distinct filter as apposed to reusing StaticHeaderWriter since the specification specifies that the "Strict-Transport-Security" header should only be set on secure requests. It would not make sense to require DelegatingRequestMatcherHeaderWriter since this requirement is in the specification.
This commit is contained in:
@@ -35,6 +35,7 @@ import org.springframework.security.web.authentication.ui.DefaultLoginPageGenera
|
||||
import org.springframework.security.web.headers.HeadersFilter
|
||||
import org.springframework.security.web.headers.StaticHeadersWriter;
|
||||
import org.springframework.security.web.headers.frameoptions.StaticAllowFromStrategy;
|
||||
import org.springframework.security.web.util.AnyRequestMatcher;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -341,6 +342,56 @@ class HttpHeadersConfigTests extends AbstractHttpConfigTests {
|
||||
assertHeaders(response, ['Cache-Control': 'no-cache,no-store,max-age=0,must-revalidate','Pragma':'no-cache'])
|
||||
}
|
||||
|
||||
def 'http headers hsts'() {
|
||||
setup:
|
||||
httpAutoConfig {
|
||||
'headers'() {
|
||||
'hsts'()
|
||||
}
|
||||
}
|
||||
createAppContext()
|
||||
def springSecurityFilterChain = appContext.getBean(FilterChainProxy)
|
||||
MockHttpServletResponse response = new MockHttpServletResponse()
|
||||
when:
|
||||
springSecurityFilterChain.doFilter(new MockHttpServletRequest(secure:true), response, new MockFilterChain())
|
||||
then:
|
||||
assertHeaders(response, ['Strict-Transport-Security': 'max-age=31536000 ; includeSubDomains'])
|
||||
}
|
||||
|
||||
def 'http headers hsts default only invokes on HttpServletRequest.isSecure = true'() {
|
||||
setup:
|
||||
httpAutoConfig {
|
||||
'headers'() {
|
||||
'hsts'()
|
||||
}
|
||||
}
|
||||
createAppContext()
|
||||
def springSecurityFilterChain = appContext.getBean(FilterChainProxy)
|
||||
MockHttpServletResponse response = new MockHttpServletResponse()
|
||||
when:
|
||||
springSecurityFilterChain.doFilter(new MockHttpServletRequest(), response, new MockFilterChain())
|
||||
then:
|
||||
response.headerNames.empty
|
||||
}
|
||||
|
||||
def 'http headers hsts custom'() {
|
||||
setup:
|
||||
httpAutoConfig {
|
||||
'headers'() {
|
||||
'hsts'('max-age-seconds':'1','include-subdomains':false, 'request-matcher-ref' : 'matcher')
|
||||
}
|
||||
}
|
||||
|
||||
xml.'b:bean'(id: 'matcher', 'class': AnyRequestMatcher.name)
|
||||
createAppContext()
|
||||
def springSecurityFilterChain = appContext.getBean(FilterChainProxy)
|
||||
MockHttpServletResponse response = new MockHttpServletResponse()
|
||||
when:
|
||||
springSecurityFilterChain.doFilter(new MockHttpServletRequest(), response, new MockFilterChain())
|
||||
then:
|
||||
assertHeaders(response, ['Strict-Transport-Security': 'max-age=1'])
|
||||
}
|
||||
|
||||
def assertHeaders(MockHttpServletResponse response, Map<String,String> expected) {
|
||||
assert response.headerNames == expected.keySet()
|
||||
expected.each { headerName, value ->
|
||||
|
||||
Reference in New Issue
Block a user