mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-06-01 09:42:13 +00:00
SEC-2283: Update headers documentation and tests
This commit is contained in:
parent
4761614c9f
commit
d89cf6db29
@ -239,6 +239,75 @@ public final class HttpSecurity extends AbstractConfiguredSecurityBuilder<Defaul
|
|||||||
return getOrApply(new OpenIDLoginConfigurer<HttpSecurity>());
|
return getOrApply(new OpenIDLoginConfigurer<HttpSecurity>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the Security headers to the response. This is activated by default
|
||||||
|
* when using {@link WebSecurityConfigurerAdapter}'s default constructor.
|
||||||
|
* Only invoking the {@link #headers()} without invoking additional methods
|
||||||
|
* on it, or accepting the default provided by
|
||||||
|
* {@link WebSecurityConfigurerAdapter}, is the equivalent of:
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* @Configuration
|
||||||
|
* @EnableWebSecurity
|
||||||
|
* public class CsrfSecurityConfig extends WebSecurityConfigurerAdapter {
|
||||||
|
*
|
||||||
|
* @Override
|
||||||
|
* protected void configure(HttpSecurity http) throws Exception {
|
||||||
|
* http
|
||||||
|
* .headers()
|
||||||
|
* .contentTypeOptions();
|
||||||
|
* .xssProtection()
|
||||||
|
* .cacheControl()
|
||||||
|
* .httpStrictTransportSecurity()
|
||||||
|
* .frameOptions()
|
||||||
|
* .and()
|
||||||
|
* ...;
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* You can disable the headers using the following:
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* @Configuration
|
||||||
|
* @EnableWebSecurity
|
||||||
|
* public class CsrfSecurityConfig extends WebSecurityConfigurerAdapter {
|
||||||
|
*
|
||||||
|
* @Override
|
||||||
|
* protected void configure(HttpSecurity http) throws Exception {
|
||||||
|
* http
|
||||||
|
* .headers().disable()
|
||||||
|
* ...;
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* You can enable only a few of the headers by invoking the appropriate
|
||||||
|
* methods on {@link #headers()} result. For example, the following will
|
||||||
|
* enable {@link HeadersConfigurer#cacheControl()} and
|
||||||
|
* {@link HeadersConfigurer#frameOptions()} only.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* @Configuration
|
||||||
|
* @EnableWebSecurity
|
||||||
|
* public class CsrfSecurityConfig extends WebSecurityConfigurerAdapter {
|
||||||
|
*
|
||||||
|
* @Override
|
||||||
|
* protected void configure(HttpSecurity http) throws Exception {
|
||||||
|
* http
|
||||||
|
* .headers()
|
||||||
|
* .cacheControl()
|
||||||
|
* .frameOptions()
|
||||||
|
* .and()
|
||||||
|
* ...;
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
* @see {@link HeadersConfigurer}
|
||||||
|
*/
|
||||||
public HeadersConfigurer<HttpSecurity> headers() throws Exception {
|
public HeadersConfigurer<HttpSecurity> headers() throws Exception {
|
||||||
return getOrApply(new HeadersConfigurer<HttpSecurity>());
|
return getOrApply(new HeadersConfigurer<HttpSecurity>());
|
||||||
}
|
}
|
||||||
@ -664,7 +733,23 @@ public final class HttpSecurity extends AbstractConfiguredSecurityBuilder<Defaul
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds CSRF support
|
* Adds CSRF support. This is activated by default when using
|
||||||
|
* {@link WebSecurityConfigurerAdapter}'s default constructor. You can
|
||||||
|
* disable it using:
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* @Configuration
|
||||||
|
* @EnableWebSecurity
|
||||||
|
* public class CsrfSecurityConfig extends WebSecurityConfigurerAdapter {
|
||||||
|
*
|
||||||
|
* @Override
|
||||||
|
* protected void configure(HttpSecurity http) throws Exception {
|
||||||
|
* http
|
||||||
|
* .csrf().disable()
|
||||||
|
* ...;
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* </pre>
|
||||||
*
|
*
|
||||||
* @return the {@link ServletApiConfigurer} for further customizations
|
* @return the {@link ServletApiConfigurer} for further customizations
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
|
@ -20,6 +20,7 @@ import java.util.List;
|
|||||||
|
|
||||||
import org.springframework.security.config.annotation.web.HttpSecurityBuilder;
|
import org.springframework.security.config.annotation.web.HttpSecurityBuilder;
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
|
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||||
import org.springframework.security.web.header.HeaderWriter;
|
import org.springframework.security.web.header.HeaderWriter;
|
||||||
import org.springframework.security.web.header.HeaderWriterFilter;
|
import org.springframework.security.web.header.HeaderWriterFilter;
|
||||||
import org.springframework.security.web.header.writers.CacheControlHeadersWriter;
|
import org.springframework.security.web.header.writers.CacheControlHeadersWriter;
|
||||||
@ -30,15 +31,80 @@ import org.springframework.security.web.header.writers.frameoptions.XFrameOption
|
|||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Adds the Security headers to the response. This is activated by default when
|
||||||
|
* using {@link WebSecurityConfigurerAdapter}'s default constructor. Only
|
||||||
|
* invoking the {@link #headers()} without invoking additional methods on it, or
|
||||||
|
* accepting the default provided by {@link WebSecurityConfigurerAdapter}, is
|
||||||
|
* the equivalent of:
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* @Configuration
|
||||||
|
* @EnableWebSecurity
|
||||||
|
* public class CsrfSecurityConfig extends WebSecurityConfigurerAdapter {
|
||||||
|
*
|
||||||
|
* @Override
|
||||||
|
* protected void configure(HttpSecurity http) throws Exception {
|
||||||
|
* http
|
||||||
|
* .headers()
|
||||||
|
* .contentTypeOptions();
|
||||||
|
* .xssProtection()
|
||||||
|
* .cacheControl()
|
||||||
|
* .httpStrictTransportSecurity()
|
||||||
|
* .frameOptions()
|
||||||
|
* .and()
|
||||||
|
* ...;
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* You can disable the headers using the following:
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* @Configuration
|
||||||
|
* @EnableWebSecurity
|
||||||
|
* public class CsrfSecurityConfig extends WebSecurityConfigurerAdapter {
|
||||||
|
*
|
||||||
|
* @Override
|
||||||
|
* protected void configure(HttpSecurity http) throws Exception {
|
||||||
|
* http
|
||||||
|
* .headers().disable()
|
||||||
|
* ...;
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* You can enable only a few of the headers by invoking the appropriate methods
|
||||||
|
* on {@link #headers()} result. For example, the following will enable
|
||||||
|
* {@link HeadersConfigurer#cacheControl()} and
|
||||||
|
* {@link HeadersConfigurer#frameOptions()} only.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* @Configuration
|
||||||
|
* @EnableWebSecurity
|
||||||
|
* public class CsrfSecurityConfig extends WebSecurityConfigurerAdapter {
|
||||||
|
*
|
||||||
|
* @Override
|
||||||
|
* protected void configure(HttpSecurity http) throws Exception {
|
||||||
|
* http
|
||||||
|
* .headers()
|
||||||
|
* .cacheControl()
|
||||||
|
* .frameOptions()
|
||||||
|
* .and()
|
||||||
|
* ...;
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
* @author Rob Winch
|
* @author Rob Winch
|
||||||
* @since 3.2
|
* @since 3.2
|
||||||
* @see RememberMeConfigurer
|
|
||||||
*/
|
*/
|
||||||
public final class HeadersConfigurer<H extends HttpSecurityBuilder<H>> extends AbstractHttpConfigurer<HeadersConfigurer<H>,H> {
|
public final class HeadersConfigurer<H extends HttpSecurityBuilder<H>> extends
|
||||||
|
AbstractHttpConfigurer<HeadersConfigurer<H>, H> {
|
||||||
private List<HeaderWriter> headerWriters = new ArrayList<HeaderWriter>();
|
private List<HeaderWriter> headerWriters = new ArrayList<HeaderWriter>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance
|
* Creates a new instance
|
||||||
|
*
|
||||||
* @see HttpSecurity#headers()
|
* @see HttpSecurity#headers()
|
||||||
*/
|
*/
|
||||||
public HeadersConfigurer() {
|
public HeadersConfigurer() {
|
||||||
@ -46,7 +112,9 @@ public final class HeadersConfigurer<H extends HttpSecurityBuilder<H>> extends A
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a {@link HeaderWriter} instance
|
* Adds a {@link HeaderWriter} instance
|
||||||
* @param headerWriter the {@link HeaderWriter} instance to add
|
*
|
||||||
|
* @param headerWriter
|
||||||
|
* the {@link HeaderWriter} instance to add
|
||||||
* @return the {@link HeadersConfigurer} for additional customizations
|
* @return the {@link HeadersConfigurer} for additional customizations
|
||||||
*/
|
*/
|
||||||
public HeadersConfigurer<H> addHeaderWriter(HeaderWriter headerWriter) {
|
public HeadersConfigurer<H> addHeaderWriter(HeaderWriter headerWriter) {
|
||||||
@ -56,7 +124,13 @@ public final class HeadersConfigurer<H extends HttpSecurityBuilder<H>> extends A
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds {@link XContentTypeOptionsHeaderWriter}
|
* Adds {@link XContentTypeOptionsHeaderWriter} which inserts the <a href=
|
||||||
|
* "http://msdn.microsoft.com/en-us/library/ie/gg622941(v=vs.85).aspx"
|
||||||
|
* >X-Content-Type-Options</a>:
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* X-Content-Type-Options: nosniff
|
||||||
|
* </pre>
|
||||||
*
|
*
|
||||||
* @return the {@link HeadersConfigurer} for additional customizations
|
* @return the {@link HeadersConfigurer} for additional customizations
|
||||||
*/
|
*/
|
||||||
@ -65,8 +139,11 @@ public final class HeadersConfigurer<H extends HttpSecurityBuilder<H>> extends A
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds {@link XXssProtectionHeaderWriter}. Note this is not comprehensive
|
* <strong>Note this is not comprehensive XSS protection!</strong>
|
||||||
* XSS protection!
|
*
|
||||||
|
* <para>Adds {@link XXssProtectionHeaderWriter} which adds the <a href=
|
||||||
|
* "http://blogs.msdn.com/b/ieinternals/archive/2011/01/31/controlling-the-internet-explorer-xss-filter-with-the-x-xss-protection-http-header.aspx"
|
||||||
|
* >X-XSS-Protection header</a>
|
||||||
*
|
*
|
||||||
* @return the {@link HeadersConfigurer} for additional customizations
|
* @return the {@link HeadersConfigurer} for additional customizations
|
||||||
*/
|
*/
|
||||||
@ -75,7 +152,12 @@ public final class HeadersConfigurer<H extends HttpSecurityBuilder<H>> extends A
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds {@link CacheControlHeadersWriter}.
|
* Adds {@link CacheControlHeadersWriter}. Specifically it adds the
|
||||||
|
* following headers:
|
||||||
|
* <ul>
|
||||||
|
* <li>Cache-Control: no-cache, no-store, max-age=0, must-revalidate</li>
|
||||||
|
* <li>Pragma: no-cache</li>
|
||||||
|
* </ul>
|
||||||
*
|
*
|
||||||
* @return the {@link HeadersConfigurer} for additional customizations
|
* @return the {@link HeadersConfigurer} for additional customizations
|
||||||
*/
|
*/
|
||||||
@ -84,7 +166,15 @@ public final class HeadersConfigurer<H extends HttpSecurityBuilder<H>> extends A
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds {@link HstsHeaderWriter}.
|
* Adds {@link HstsHeaderWriter} which provides support for <a
|
||||||
|
* href="http://tools.ietf.org/html/rfc6797">HTTP Strict Transport Security
|
||||||
|
* (HSTS)</a>.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* For additional configuration options, use
|
||||||
|
* {@link #addHeaderWriter(HeaderWriter)} and {@link HstsHeaderWriter}
|
||||||
|
* directly.
|
||||||
|
* </p>
|
||||||
*
|
*
|
||||||
* @return the {@link HeadersConfigurer} for additional customizations
|
* @return the {@link HeadersConfigurer} for additional customizations
|
||||||
*/
|
*/
|
||||||
@ -93,7 +183,10 @@ public final class HeadersConfigurer<H extends HttpSecurityBuilder<H>> extends A
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds {@link XFrameOptionsHeaderWriter} with all the default settings.
|
* Adds {@link XFrameOptionsHeaderWriter} with all the default settings. For
|
||||||
|
* additional configuration options, use
|
||||||
|
* {@link #addHeaderWriter(HeaderWriter)} and
|
||||||
|
* {@link XFrameOptionsHeaderWriter} directly.
|
||||||
*
|
*
|
||||||
* @return the {@link HeadersConfigurer} for additional customizations
|
* @return the {@link HeadersConfigurer} for additional customizations
|
||||||
*/
|
*/
|
||||||
@ -109,20 +202,24 @@ public final class HeadersConfigurer<H extends HttpSecurityBuilder<H>> extends A
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the {@link HeaderWriter}
|
* Creates the {@link HeaderWriter}
|
||||||
|
*
|
||||||
* @return the {@link HeaderWriter}
|
* @return the {@link HeaderWriter}
|
||||||
*/
|
*/
|
||||||
private HeaderWriterFilter createHeaderWriterFilter() {
|
private HeaderWriterFilter createHeaderWriterFilter() {
|
||||||
HeaderWriterFilter headersFilter = new HeaderWriterFilter(getHeaderWriters());
|
HeaderWriterFilter headersFilter = new HeaderWriterFilter(
|
||||||
|
getHeaderWriters());
|
||||||
headersFilter = postProcess(headersFilter);
|
headersFilter = postProcess(headersFilter);
|
||||||
return headersFilter;
|
return headersFilter;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the {@link HeaderWriter} instances and possibly initializes with the defaults.
|
* Gets the {@link HeaderWriter} instances and possibly initializes with the
|
||||||
|
* defaults.
|
||||||
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private List<HeaderWriter> getHeaderWriters() {
|
private List<HeaderWriter> getHeaderWriters() {
|
||||||
if(headerWriters.isEmpty()) {
|
if (headerWriters.isEmpty()) {
|
||||||
addDefaultHeaderWriters();
|
addDefaultHeaderWriters();
|
||||||
}
|
}
|
||||||
return headerWriters;
|
return headerWriters;
|
||||||
|
@ -0,0 +1,162 @@
|
|||||||
|
/*
|
||||||
|
* 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.config.annotation.web.configurers
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletResponse
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Configuration
|
||||||
|
import org.springframework.security.config.annotation.BaseSpringSpec
|
||||||
|
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder
|
||||||
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity
|
||||||
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
|
||||||
|
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
|
||||||
|
import org.springframework.security.web.access.AccessDeniedHandler
|
||||||
|
import org.springframework.security.web.csrf.CsrfFilter;
|
||||||
|
import org.springframework.security.web.csrf.CsrfTokenRepository;
|
||||||
|
import org.springframework.security.web.servlet.support.csrf.CsrfRequestDataValueProcessor;
|
||||||
|
import org.springframework.security.web.util.RequestMatcher;
|
||||||
|
import org.springframework.web.servlet.support.RequestDataValueProcessor;
|
||||||
|
|
||||||
|
import spock.lang.Unroll;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Rob Winch
|
||||||
|
*/
|
||||||
|
class HeadersConfigurerTests extends BaseSpringSpec {
|
||||||
|
|
||||||
|
def "headers"() {
|
||||||
|
setup:
|
||||||
|
loadConfig(HeadersConfig)
|
||||||
|
request.secure = true
|
||||||
|
when:
|
||||||
|
springSecurityFilterChain.doFilter(request,response,chain)
|
||||||
|
then:
|
||||||
|
responseHeaders == ['X-Content-Type-Options':'nosniff',
|
||||||
|
'X-Frame-Options':'DENY',
|
||||||
|
'Strict-Transport-Security': 'max-age=31536000 ; includeSubDomains',
|
||||||
|
'Cache-Control': 'no-cache,no-store,max-age=0,must-revalidate',
|
||||||
|
'Pragma':'no-cache',
|
||||||
|
'X-XSS-Protection' : '1; mode=block']
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableWebSecurity
|
||||||
|
static class HeadersConfig extends WebSecurityConfigurerAdapter {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
|
http.headers()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def "headers.contentType"() {
|
||||||
|
setup:
|
||||||
|
loadConfig(ContentTypeOptionsConfig)
|
||||||
|
when:
|
||||||
|
springSecurityFilterChain.doFilter(request,response,chain)
|
||||||
|
then:
|
||||||
|
responseHeaders == ['X-Content-Type-Options':'nosniff']
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableWebSecurity
|
||||||
|
static class ContentTypeOptionsConfig extends WebSecurityConfigurerAdapter {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
|
http.headers().contentTypeOptions()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def "headers.frameOptions"() {
|
||||||
|
setup:
|
||||||
|
loadConfig(FrameOptionsConfig)
|
||||||
|
when:
|
||||||
|
springSecurityFilterChain.doFilter(request,response,chain)
|
||||||
|
then:
|
||||||
|
responseHeaders == ['X-Frame-Options':'DENY']
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableWebSecurity
|
||||||
|
static class FrameOptionsConfig extends WebSecurityConfigurerAdapter {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
|
http.headers().frameOptions()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def "headers.hsts"() {
|
||||||
|
setup:
|
||||||
|
loadConfig(HstsConfig)
|
||||||
|
request.secure = true
|
||||||
|
when:
|
||||||
|
springSecurityFilterChain.doFilter(request,response,chain)
|
||||||
|
then:
|
||||||
|
responseHeaders == ['Strict-Transport-Security': 'max-age=31536000 ; includeSubDomains']
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableWebSecurity
|
||||||
|
static class HstsConfig extends WebSecurityConfigurerAdapter {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
|
http.headers().httpStrictTransportSecurity()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def "headers.cacheControl"() {
|
||||||
|
setup:
|
||||||
|
loadConfig(CacheControlConfig)
|
||||||
|
when:
|
||||||
|
springSecurityFilterChain.doFilter(request,response,chain)
|
||||||
|
then:
|
||||||
|
responseHeaders == ['Cache-Control': 'no-cache,no-store,max-age=0,must-revalidate',
|
||||||
|
'Pragma':'no-cache']
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableWebSecurity
|
||||||
|
static class CacheControlConfig extends WebSecurityConfigurerAdapter {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
|
http.headers().cacheControl()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def "headers.xssProtection"() {
|
||||||
|
setup:
|
||||||
|
loadConfig(XssProtectionConfig)
|
||||||
|
when:
|
||||||
|
springSecurityFilterChain.doFilter(request,response,chain)
|
||||||
|
then:
|
||||||
|
responseHeaders == ['X-XSS-Protection' : '1; mode=block']
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableWebSecurity
|
||||||
|
static class XssProtectionConfig extends WebSecurityConfigurerAdapter {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
|
http.headers().xssProtection()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -354,7 +354,7 @@
|
|||||||
<section xml:id="nsa-frame-options-attributes">
|
<section xml:id="nsa-frame-options-attributes">
|
||||||
<title><literal><frame-options></literal> Attributes</title>
|
<title><literal><frame-options></literal> Attributes</title>
|
||||||
<section xml:id="nsa-frame-options-policy">
|
<section xml:id="nsa-frame-options-policy">
|
||||||
<title><literal>frame-options-policy</literal></title>
|
<title><literal>policy</literal></title>
|
||||||
<para>
|
<para>
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem><literal>DENY</literal> The page cannot be displayed in a frame, regardless of
|
<listitem><literal>DENY</literal> The page cannot be displayed in a frame, regardless of
|
||||||
@ -372,7 +372,7 @@
|
|||||||
</para>
|
</para>
|
||||||
</section>
|
</section>
|
||||||
<section xml:id="nsa-frame-options-strategy">
|
<section xml:id="nsa-frame-options-strategy">
|
||||||
<title><literal>frame-options-strategy</literal></title>
|
<title><literal>strategy</literal></title>
|
||||||
<para>
|
<para>
|
||||||
Select the <classname>AllowFromStrategy</classname> to use when using the ALLOW-FROM policy.
|
Select the <classname>AllowFromStrategy</classname> to use when using the ALLOW-FROM policy.
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
@ -393,18 +393,18 @@
|
|||||||
</para>
|
</para>
|
||||||
</section>
|
</section>
|
||||||
<section xml:id="nsa-frame-options-ref">
|
<section xml:id="nsa-frame-options-ref">
|
||||||
<title><literal>frame-options-ref</literal></title>
|
<title><literal>ref</literal></title>
|
||||||
<para>
|
<para>
|
||||||
Instead of using one of the predefined strategies it is also possible to use a custom <classname>AllowFromStrategy</classname>.
|
Instead of using one of the predefined strategies it is also possible to use a custom <classname>AllowFromStrategy</classname>.
|
||||||
The reference to this bean can be specified through this ref attribute.
|
The reference to this bean can be specified through this ref attribute.
|
||||||
</para>
|
</para>
|
||||||
</section>
|
</section>
|
||||||
<section xml:id="nsa-frame-options-value">
|
<section xml:id="nsa-frame-options-value">
|
||||||
<title><literal>frame-options-value</literal></title>
|
<title><literal>value</literal></title>
|
||||||
<para>The value to use when ALLOW-FROM is used a <link linkend="nsa-frame-options-strategy">strategy</link>.</para>
|
<para>The value to use when ALLOW-FROM is used a <link linkend="nsa-frame-options-strategy">strategy</link>.</para>
|
||||||
</section>
|
</section>
|
||||||
<section xml:id="nsa-frame-options-from-parameter">
|
<section xml:id="nsa-frame-options-from-parameter">
|
||||||
<title><literal>frame-options-from-parameter</literal></title>
|
<title><literal>from-parameter</literal></title>
|
||||||
<para>
|
<para>
|
||||||
Specify the name of the request parameter to use when using regexp or whitelist for the ALLOW-FROM
|
Specify the name of the request parameter to use when using regexp or whitelist for the ALLOW-FROM
|
||||||
strategy.
|
strategy.
|
||||||
|
@ -205,7 +205,8 @@ public class WebSecurityConfig extends
|
|||||||
<note>
|
<note>
|
||||||
<para>Another modern approach to dealing with clickjacking is using a <link xlink:href="http://www.w3.org/TR/CSP/">Content
|
<para>Another modern approach to dealing with clickjacking is using a <link xlink:href="http://www.w3.org/TR/CSP/">Content
|
||||||
Security Policy</link>. Spring Security does not provide
|
Security Policy</link>. Spring Security does not provide
|
||||||
support for this as the specification is not released and it is quite a bit more complicated. To stay up to date with this
|
support for this as the specification is not released and it is quite a bit more complicated. However, you could use the
|
||||||
|
<link linkend="headers-static">static headers</link> feature to implement this. To stay up to date with this
|
||||||
issue and to see how you can implement it with Spring Security refer to
|
issue and to see how you can implement it with Spring Security refer to
|
||||||
<link xlink:href="https://jira.springsource.org/browse/SEC-2117">SEC-2117</link> </para>
|
<link xlink:href="https://jira.springsource.org/browse/SEC-2117">SEC-2117</link> </para>
|
||||||
</note>
|
</note>
|
||||||
@ -242,7 +243,7 @@ public class WebSecurityConfig extends
|
|||||||
}
|
}
|
||||||
}]]></programlisting>
|
}]]></programlisting>
|
||||||
</section>
|
</section>
|
||||||
<section xml:id="xss-protection">
|
<section xml:id="headers-xss-protection">
|
||||||
<title>X-XSS-Protection</title>
|
<title>X-XSS-Protection</title>
|
||||||
<para>Some browsers have built in support for filtering out
|
<para>Some browsers have built in support for filtering out
|
||||||
<link xlink:href="https://www.owasp.org/index.php/Testing_for_Reflected_Cross_site_scripting_(OWASP-DV-001)">reflected
|
<link xlink:href="https://www.owasp.org/index.php/Testing_for_Reflected_Cross_site_scripting_(OWASP-DV-001)">reflected
|
||||||
@ -276,6 +277,75 @@ public class WebSecurityConfig extends
|
|||||||
.and()
|
.and()
|
||||||
...;
|
...;
|
||||||
}
|
}
|
||||||
|
}]]></programlisting>
|
||||||
|
</section>
|
||||||
|
<section xml:id="headers-static">
|
||||||
|
<title>Static Headers</title>
|
||||||
|
<para>There may be times you wish to inject custom security headers into your application that are not supported out of the box. For example, perhaps
|
||||||
|
you wish to have early support for <link xlink:href="http://www.w3.org/TR/CSP/">Content Security Policy</link> in order to ensure that resources
|
||||||
|
are only loaded from the same origin. Since support for Content Security Policy has not been finalized, browsers use one of two common extension headers
|
||||||
|
to implement the feature. This means we will need to inject the policy twice. An example of the headers can be seen below:</para>
|
||||||
|
<programlisting><![CDATA[X-Content-Security-Policy: default-src 'self'
|
||||||
|
X-WebKit-CSP: default-src 'self']]></programlisting>
|
||||||
|
<para>When using the XML namespace, these headers can be added to the response using the <link linkend="nsa-header"><header></link> element as
|
||||||
|
shown below:</para>
|
||||||
|
<programlisting language="xml"><![CDATA[<http ...>
|
||||||
|
...
|
||||||
|
<headers>
|
||||||
|
<header name="X-Content-Security-Policy" value="default-src 'self'"/>
|
||||||
|
<header name="X-WebKit-CSP" value="default-src 'self'"/>
|
||||||
|
</headers>
|
||||||
|
</http>]]></programlisting>
|
||||||
|
<para>Similarly, the headers could be added to the response using Java Configuration as shown in the following:</para>
|
||||||
|
<programlisting language="java"><![CDATA[@EnableWebSecurity
|
||||||
|
@Configuration
|
||||||
|
public class WebSecurityConfig extends
|
||||||
|
WebSecurityConfigurerAdapter {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
|
http
|
||||||
|
.headers()
|
||||||
|
.addHeaderWriter(new StaticHeaderWriter("X-Content-Security-Policy","default-src 'self'"))
|
||||||
|
.addHeaderWriter(new StaticHeaderWriter("X-WebKit-CSP","default-src 'self'"))
|
||||||
|
.and()
|
||||||
|
...;
|
||||||
|
}
|
||||||
|
}]]></programlisting>
|
||||||
|
</section>
|
||||||
|
<section xml:id="headers-writer">
|
||||||
|
<title>Headers Writer</title>
|
||||||
|
<para>When the namespace or Java configuration does not support the headers you want, you can create a custom <interfacename>HeadersWriter</interfacename> instance
|
||||||
|
or even provide a custom implementation of the <interfacename>HeadersWriter</interfacename>.</para>
|
||||||
|
<para>Let's take a look at an example of using an custom instance of <classname>XFrameOptionsHeaderWriter</classname>. Perhaps you want to allow framing of content
|
||||||
|
for the same origin. This is easily supported by setting the <link linkend="nsa-frame-options-policy">policy</link>
|
||||||
|
attribute to "SAMEORIGIN", but let's take a look at a more explicit example.</para>
|
||||||
|
<programlisting language="xml"><![CDATA[<http ...>
|
||||||
|
...
|
||||||
|
<headers>
|
||||||
|
<header header-ref="frameOptionsWriter"/>
|
||||||
|
</headers>
|
||||||
|
</http>
|
||||||
|
<!-- Requires the c-namespace.
|
||||||
|
See http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/beans.html#beans-c-namespace
|
||||||
|
-->
|
||||||
|
<bean:bean id="frameOptionsWriter"
|
||||||
|
class="org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter"
|
||||||
|
c:frameOptionsMode="SAMEORIGIN"/>]]></programlisting>
|
||||||
|
<para>We could also restrict framing of content to the same origin with Java configuration:</para>
|
||||||
|
<programlisting language="java"><![CDATA[@EnableWebSecurity
|
||||||
|
@Configuration
|
||||||
|
public class WebSecurityConfig extends
|
||||||
|
WebSecurityConfigurerAdapter {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
|
http
|
||||||
|
.headers()
|
||||||
|
.addHeaderWriter(new XFrameOptionsHeaderWriter(XFrameOptionsMode.SAMEORIGIN))
|
||||||
|
.and()
|
||||||
|
...;
|
||||||
|
}
|
||||||
}]]></programlisting>
|
}]]></programlisting>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user