Browse Source

SEC-2283: Polish headers doc

Rob Winch 12 years ago
parent
commit
86340b8016
2 changed files with 271 additions and 193 deletions
  1. 269 191
      docs/manual/src/docbook/headers.xml
  2. 2 2
      docs/manual/src/docbook/namespace-config.xml

+ 269 - 191
docs/manual/src/docbook/headers.xml

@@ -29,10 +29,23 @@
             utilize the headers, so additional testing is encouraged. If you are using Spring Security's XML namespace support,
             you can easily add all of the default headers with the
             <link linkend="nsa-headers">&lt;headers&gt;</link> element with no child elements:</para>
-            <programlisting language="xml"><![CDATA[
-<http ...>
-    ...
+            <programlisting language="xml"><![CDATA[<http>
+    <!-- ... -->
+
     <headers />
+</http>]]></programlisting>
+        <para>Alternatively, you can choose to explicitly list the headers you wish to include. For example, the following is
+            the same the previous configuration. Removing any of the elements will remove that header from the responses.</para>
+            <programlisting language="xml"><![CDATA[<http>
+    <!-- ... -->
+
+    <headers>
+        <cache-control />
+        <content-type-options />
+        <hsts />
+        <frame-options />
+        <xss-protection />
+    </headers>
 </http>]]></programlisting>
         <para>If you are using Spring Security's Java configuration, all of the default security headers are added by default.
             They can be disabled using the Java configuration below:</para>
@@ -44,32 +57,49 @@ public class WebSecurityConfig extends
   @Override
   protected void configure(HttpSecurity http) throws Exception {
     http
-      .headers().disable()
-      ...;
+      // ...
+      .headers().disable();
   }
 }]]></programlisting>
-    </section>
-    <section xml:id="headers-cache-control">
-        <title>Cache Control</title>
-        <para>In the past Spring Security required you to provide your own cache control for your web application. This
-            seemed reasonable at the time, but browser caches have evolved to include caches for secure connections as
-            well. This means that a user may view an authenticated page, log out, and then a malicious user can use the
-            browser history to view the cached page. To help mitigate this Spring Security has added cache control support
-            which will insert the following headers into you response.</para>
-        <programlisting><![CDATA[Cache-Control: no-cache, no-store, max-age=0, must-revalidate
+        <para>As soon as you specify any headers that should be included, then only those headers will be include. For example, the
+            following configuration will include support for <link linkend="headers-cache-control">Cache Control</link> and
+            <link linkend="headers-frame-options">X-Frame-Options</link> only.</para>
+                        <programlisting language="java"><![CDATA[@EnableWebSecurity
+@Configuration
+public class WebSecurityConfig extends
+   WebSecurityConfigurerAdapter {
+
+  @Override
+  protected void configure(HttpSecurity http) throws Exception {
+    http
+      // ...
+      .headers()
+        .cacheControl()
+        .frameOptions();
+  }
+}]]></programlisting>
+        <section xml:id="headers-cache-control">
+            <title>Cache Control</title>
+            <para>In the past Spring Security required you to provide your own cache control for your web application. This
+                seemed reasonable at the time, but browser caches have evolved to include caches for secure connections as
+                well. This means that a user may view an authenticated page, log out, and then a malicious user can use the
+                browser history to view the cached page. To help mitigate this Spring Security has added cache control support
+                which will insert the following headers into you response.</para>
+            <programlisting><![CDATA[Cache-Control: no-cache, no-store, max-age=0, must-revalidate
 Pragma: no-cache]]></programlisting>
-        <para>Simply adding the <link linkend="nsa-headers">&lt;headers /&gt;</link> element with no child elements will
-            automatically add Cache Control and quite a few other protections. However, if you only want cache control, you can
-            enable this feature using Spring Security's XML namespace with the
-            <link linkend="nsa-cache-control">&lt;cache-control /&gt;</link> element.</para>
-        <programlisting langauage="xml"><![CDATA[<http ...>
-    ...
+            <para>Simply adding the <link linkend="nsa-headers">&lt;headers&gt;</link> element with no child elements will
+                automatically add Cache Control and quite a few other protections. However, if you only want cache control, you can
+                enable this feature using Spring Security's XML namespace with the
+                <link linkend="nsa-cache-control">&lt;cache-control&gt;</link> element.</para>
+            <programlisting language="xml"><![CDATA[<http>
+    <!-- ... -->
+
     <headers>
         <cache-control />
     </headers>
 </http>]]></programlisting>
-        <para>Similarly, you can enable only cache control within Java Configuration with the following:</para>
-        <programlisting language="java"><![CDATA[@EnableWebSecurity
+            <para>Similarly, you can enable only cache control within Java Configuration with the following:</para>
+            <programlisting language="java"><![CDATA[@EnableWebSecurity
 @Configuration
 public class WebSecurityConfig extends
    WebSecurityConfigurerAdapter {
@@ -77,19 +107,18 @@ public class WebSecurityConfig extends
   @Override
   protected void configure(HttpSecurity http) throws Exception {
     http
+      // ...
       .headers()
-        .cacheControl()
-        .and()
-      ...;
+        .cacheControl();
   }
 }]]></programlisting>
-        <para>If you actually want to cache specific responses, your application can selectively invoke
-            <link xlink:href="http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletResponse.html#setHeader(java.lang.String, java.lang.String)">HttpServletResponse.setHeader(String,String)</link>
-            to override the header set by Spring Security. This is useful to ensure things
-            like CSS, JavaScript, and images are properly cached.</para>
-        <para>When using Spring Web MVC, this is typically done within your configuration. For example, the following configuration will
-            ensure that the cache headers are set for all of your resources:</para>
-        <programlisting language="java"><![CDATA[@EnableWebMvc
+            <para>If you actually want to cache specific responses, your application can selectively invoke
+                <link xlink:href="http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletResponse.html#setHeader(java.lang.String, java.lang.String)">HttpServletResponse.setHeader(String,String)</link>
+                to override the header set by Spring Security. This is useful to ensure things
+                like CSS, JavaScript, and images are properly cached.</para>
+            <para>When using Spring Web MVC, this is typically done within your configuration. For example, the following configuration will
+                ensure that the cache headers are set for all of your resources:</para>
+            <programlisting language="java"><![CDATA[@EnableWebMvc
 public class WebMvcConfiguration extends WebMvcConfigurerAdapter {
 
     @Override
@@ -102,38 +131,39 @@ public class WebMvcConfiguration extends WebMvcConfigurerAdapter {
 
     // ...
 }]]></programlisting>
-    </section>
-    <section xml:id="headers-content-type-options">
-        <title>Content Type Options</title>
-        <para>Historically browsers, including Internet Explorer, would try to guess the content type of a request using
-            <link xlink:href="http://en.wikipedia.org/wiki/Content_sniffing">content sniffing</link>. This
-            allowed browsers to improve the user experience by guessing the content type on resources that had not specified the content type.
-            For example, if a browser encountered a JavaScript file that did not have the content type specified, it would be able to guess the content
-            type and then execute it.</para>
-        <note>
-            <para>There are many additional things one should do (i.e. only display the document in a distinct domain, ensure
-                Content-Type header is set, sanitize the document, etc) when allowing content to be uploaded. However, these measures
-                are out of the scope of what Spring Security provides. It is also important to point out when disabling content sniffing,
-                you must specify the content type in order for things to work properly.</para>
-        </note>
-        <para>The problem with content sniffing is that this allowed malicious users to use polyglots (i.e. a file that is valid as multiple content
-            types) to execute XSS attacks. For example, some sites may allow users to submit a valid postscript document to a website and view it. A malicious
-            user might create a <link xlink:href="http://webblaze.cs.berkeley.edu/papers/barth-caballero-song.pdf">postscript document that is also a valid
-            JavaScript file</link> and execute a XSS attack with it.</para>
-        <para>Content sniffing can be disabled by adding the following header to our response:</para>
-        <programlisting><![CDATA[X-Content-Type-Options: nosniff]]></programlisting>
-        <para>Just as with the cache control element, the nosniff directive is added by default when using the &lt;headers /&gt; element with no child elements.
-            However, if you want more control over which headers are added you can use the
-            <link linkend="nsa-content-type-options">&lt;content-type-options&gt;</link> element as shown below:</para>
-            <programlisting language="xml"><![CDATA[<http ...>
-    ...
+        </section>
+        <section xml:id="headers-content-type-options">
+            <title>Content Type Options</title>
+            <para>Historically browsers, including Internet Explorer, would try to guess the content type of a request using
+                <link xlink:href="http://en.wikipedia.org/wiki/Content_sniffing">content sniffing</link>. This
+                allowed browsers to improve the user experience by guessing the content type on resources that had not specified the content type.
+                For example, if a browser encountered a JavaScript file that did not have the content type specified, it would be able to guess the content
+                type and then execute it.</para>
+            <note>
+                <para>There are many additional things one should do (i.e. only display the document in a distinct domain, ensure
+                    Content-Type header is set, sanitize the document, etc) when allowing content to be uploaded. However, these measures
+                    are out of the scope of what Spring Security provides. It is also important to point out when disabling content sniffing,
+                    you must specify the content type in order for things to work properly.</para>
+            </note>
+            <para>The problem with content sniffing is that this allowed malicious users to use polyglots (i.e. a file that is valid as multiple content
+                types) to execute XSS attacks. For example, some sites may allow users to submit a valid postscript document to a website and view it. A malicious
+                user might create a <link xlink:href="http://webblaze.cs.berkeley.edu/papers/barth-caballero-song.pdf">postscript document that is also a valid
+                JavaScript file</link> and execute a XSS attack with it.</para>
+            <para>Content sniffing can be disabled by adding the following header to our response:</para>
+            <programlisting><![CDATA[X-Content-Type-Options: nosniff]]></programlisting>
+            <para>Just as with the cache control element, the nosniff directive is added by default when using the &lt;headers&gt; element with no child elements.
+                However, if you want more control over which headers are added you can use the
+                <link linkend="nsa-content-type-options">&lt;content-type-options&gt;</link> element as shown below:</para>
+                <programlisting language="xml"><![CDATA[<http>
+    <!-- ... -->
+
     <headers>
         <content-type-options />
     </headers>
 </http>]]></programlisting>
-        <para>The X-Content-Type-Options header is added by default with Spring Security Java configuration. If you want more control over the headers, you can
-            explicitly specify the content type options with the following:</para>
-        <programlisting language="java"><![CDATA[@EnableWebSecurity
+            <para>The X-Content-Type-Options header is added by default with Spring Security Java configuration. If you want more control over the headers, you can
+                explicitly specify the content type options with the following:</para>
+            <programlisting language="java"><![CDATA[@EnableWebSecurity
 @Configuration
 public class WebSecurityConfig extends
    WebSecurityConfigurerAdapter {
@@ -141,46 +171,46 @@ public class WebSecurityConfig extends
   @Override
   protected void configure(HttpSecurity http) throws Exception {
     http
+      // ...
       .headers()
-        .contentTypeOptions()
-        .and()
-      ...;
+        .contentTypeOptions();
   }
 }]]></programlisting>
-    </section>
-    <section xml:id="headers-hsts">
-        <title>HTTP Strict Transport Security (HSTS)</title>
-        <para>When you type in your bank's website, do you enter mybank.example.com or do you enter https://mybank.example.com? If you
-            omit the https protocol, you are potentially vulnerable to
-            <link xlink:href="http://en.wikipedia.org/wiki/Man-in-the-middle_attack">Man in the Middle attacks</link>. Even if the website performs a redirect
-            to https://mybank.example.com a malicious user could intercept the initial HTTP request and manipulate the response (i.e.
-            redirect to https://mibank.example.com and steal their credentials).</para>
-        <para>Many users omit the https protocol and this is why <link xlink:href="http://tools.ietf.org/html/rfc6797">HTTP Strict Transport Security (HSTS)</link>
-            was created. Once mybank.example.com is added as a <link xlink:href="http://tools.ietf.org/html/rfc6797#section-5.1">HSTS host</link>, a browser can
-            know ahead of time that any request to mybank.example.com should be interpreted as
-            https://mybank.example.com. This greatly reduces the possibility of a Man in the Middle attack occurring.</para>
-        <note>
-            <para>In accordance with <link xlink:href="http://tools.ietf.org/html/rfc6797#section-7.2">RFC6797</link>, the HSTS header is only injected into HTTPS
-                responses. In order for the browser to acknowledge the header, the browser must first trust the CA that signed the SSL certificate used to make the
-                connection (not just the SSL certificate).</para>
-        </note>
-        <para>One way for a site to be marked as a HSTS host is to have the host preloaded into the browser. Another is to add the
-            "Strict-Transport-Security" header to the response. For example the following would instruct the browser to treat the domain as an HSTS
-            host for a year (there are approximately 31536000 seconds in a year):</para>
-        <programlisting><![CDATA[Strict-Transport-Security: max-age=31536000 ; includeSubDomains]]></programlisting>
-        <para>The optional includeSubDomains directive instructs Spring Security that subdomains (i.e. secure.mybank.example.com) should also be
-            treated as an HSTS domain.</para>
-        <para>As with the other headers, Spring Security adds the previous header to the response when the &lt;headers&gt; element is specified with
-            no child elements. It is also automatically added when you are using Java Configuration. You can also only use HSTS headers with the
-            <link linkend="nsa-hsts">&lt;hsts&gt;</link> element as shown below:</para>
-        <programlisting language="xml"><![CDATA[<http ...>
-    ...
+        </section>
+        <section xml:id="headers-hsts">
+            <title>HTTP Strict Transport Security (HSTS)</title>
+            <para>When you type in your bank's website, do you enter mybank.example.com or do you enter https://mybank.example.com? If you
+                omit the https protocol, you are potentially vulnerable to
+                <link xlink:href="http://en.wikipedia.org/wiki/Man-in-the-middle_attack">Man in the Middle attacks</link>. Even if the website performs a redirect
+                to https://mybank.example.com a malicious user could intercept the initial HTTP request and manipulate the response (i.e.
+                redirect to https://mibank.example.com and steal their credentials).</para>
+            <para>Many users omit the https protocol and this is why <link xlink:href="http://tools.ietf.org/html/rfc6797">HTTP Strict Transport Security (HSTS)</link>
+                was created. Once mybank.example.com is added as a <link xlink:href="http://tools.ietf.org/html/rfc6797#section-5.1">HSTS host</link>, a browser can
+                know ahead of time that any request to mybank.example.com should be interpreted as
+                https://mybank.example.com. This greatly reduces the possibility of a Man in the Middle attack occurring.</para>
+            <note>
+                <para>In accordance with <link xlink:href="http://tools.ietf.org/html/rfc6797#section-7.2">RFC6797</link>, the HSTS header is only injected into HTTPS
+                    responses. In order for the browser to acknowledge the header, the browser must first trust the CA that signed the SSL certificate used to make the
+                    connection (not just the SSL certificate).</para>
+            </note>
+            <para>One way for a site to be marked as a HSTS host is to have the host preloaded into the browser. Another is to add the
+                "Strict-Transport-Security" header to the response. For example the following would instruct the browser to treat the domain as an HSTS
+                host for a year (there are approximately 31536000 seconds in a year):</para>
+            <programlisting><![CDATA[Strict-Transport-Security: max-age=31536000 ; includeSubDomains]]></programlisting>
+            <para>The optional includeSubDomains directive instructs Spring Security that subdomains (i.e. secure.mybank.example.com) should also be
+                treated as an HSTS domain.</para>
+            <para>As with the other headers, Spring Security adds the previous header to the response when the &lt;headers&gt; element is specified with
+                no child elements. It is also automatically added when you are using Java Configuration. You can also only use HSTS headers with the
+                <link linkend="nsa-hsts">&lt;hsts&gt;</link> element as shown below:</para>
+            <programlisting language="xml"><![CDATA[<http>
+    <!-- ... -->
+
     <headers>
         <hsts />
     </headers>
 </http>]]></programlisting>
-        <para>Similarly, you can enable only HSTS headers with Java Configuration:</para>
-        <programlisting language="java"><![CDATA[@EnableWebSecurity
+            <para>Similarly, you can enable only HSTS headers with Java Configuration:</para>
+            <programlisting language="java"><![CDATA[@EnableWebSecurity
 @Configuration
 public class WebSecurityConfig extends
    WebSecurityConfigurerAdapter {
@@ -188,47 +218,47 @@ public class WebSecurityConfig extends
   @Override
   protected void configure(HttpSecurity http) throws Exception {
     http
+      // ...
       .headers()
-        .hsts()
-        .and()
-      ...;
+        .hsts();
   }
 }]]></programlisting>
-    </section>
-    <section xml:id="headers-frame-options">
-        <title>X-Frame-Options</title>
-        <para>Allowing your website to be added to a frame can be a security issue. For example, using clever CSS styling users
-            could be tricked into clicking on something that they were not intending (
-            <link xlink:href="http://www.youtube.com/watch?v=3mk0RySeNsU">video demo</link>). For example, a user that is logged
-            into their bank might click a button that grants access to other users. This sort of attack is known as
-            <link xlink:href="http://en.wikipedia.org/wiki/Clickjacking">Clickjacking</link>.</para>
-        <note>
-            <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
-                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
-                <link xlink:href="https://jira.springsource.org/browse/SEC-2117">SEC-2117</link> </para>
-        </note>
-        <para>There are a number ways to mitigate clickjacking attacks. For example, to protect legacy browsers from clickjacking attacks you
-            can use
-            <link xlink:href="https://www.owasp.org/index.php/Clickjacking_Defense_Cheat_Sheet#Best-for-now_Legacy_Browser_Frame_Breaking_Script">frame
-            breaking code</link>. While not perfect, the frame breaking code is the best you can do for the legacy browsers.</para>
-        <para>A more modern approach to address clickjacking is to use
-            <link xlink:href="https://developer.mozilla.org/en-US/docs/HTTP/X-Frame-Options">X-Frame-Options</link> header:</para>
-        <programlisting><![CDATA[X-Frame-Options: DENY]]></programlisting>
-        <para>The X-Frame-Options response header instructs the browser to prevent any site with this header in the response from being rendered
-            within a frame. As with the other response headers, this is automatically included when the &lt;headers&gt; element is specified with no
-            child elements. You can also explicitly specify the <link linkend="nsa-frame-options">frame-options</link> element to control which headers
-            are added to the response.</para>
-        <programlisting language="xml"><![CDATA[<http ...>
-    ...
+        </section>
+        <section xml:id="headers-frame-options">
+            <title>X-Frame-Options</title>
+            <para>Allowing your website to be added to a frame can be a security issue. For example, using clever CSS styling users
+                could be tricked into clicking on something that they were not intending (
+                <link xlink:href="http://www.youtube.com/watch?v=3mk0RySeNsU">video demo</link>). For example, a user that is logged
+                into their bank might click a button that grants access to other users. This sort of attack is known as
+                <link xlink:href="http://en.wikipedia.org/wiki/Clickjacking">Clickjacking</link>.</para>
+            <note>
+                <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
+                    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
+                    <link xlink:href="https://jira.springsource.org/browse/SEC-2117">SEC-2117</link> </para>
+            </note>
+            <para>There are a number ways to mitigate clickjacking attacks. For example, to protect legacy browsers from clickjacking attacks you
+                can use
+                <link xlink:href="https://www.owasp.org/index.php/Clickjacking_Defense_Cheat_Sheet#Best-for-now_Legacy_Browser_Frame_Breaking_Script">frame
+                breaking code</link>. While not perfect, the frame breaking code is the best you can do for the legacy browsers.</para>
+            <para>A more modern approach to address clickjacking is to use
+                <link xlink:href="https://developer.mozilla.org/en-US/docs/HTTP/X-Frame-Options">X-Frame-Options</link> header:</para>
+            <programlisting><![CDATA[X-Frame-Options: DENY]]></programlisting>
+            <para>The X-Frame-Options response header instructs the browser to prevent any site with this header in the response from being rendered
+                within a frame. As with the other response headers, this is automatically included when the &lt;headers&gt; element is specified with no
+                child elements. You can also explicitly specify the <link linkend="nsa-frame-options">frame-options</link> element to control which headers
+                are added to the response.</para>
+            <programlisting language="xml"><![CDATA[<http>
+    <!-- ... -->
+
     <headers>
         <frame-options />
     </headers>
 </http>]]></programlisting>
-        <para>Similarly, you can enable only frame options within Java Configuration with the following:</para>
-        <programlisting language="java"><![CDATA[@EnableWebSecurity
+            <para>Similarly, you can enable only frame options within Java Configuration with the following:</para>
+            <programlisting language="java"><![CDATA[@EnableWebSecurity
 @Configuration
 public class WebSecurityConfig extends
    WebSecurityConfigurerAdapter {
@@ -236,35 +266,37 @@ public class WebSecurityConfig extends
   @Override
   protected void configure(HttpSecurity http) throws Exception {
     http
+      // ...
       .headers()
-        .frameOptions()
-        .and()
-      ...;
+        .frameOptions();
   }
 }]]></programlisting>
-    </section>
-    <section xml:id="headers-xss-protection">
-        <title>X-XSS-Protection</title>
-        <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
-            XSS attacks</link>. This is by no means full proof, but does assist in XSS protection.</para>
-        <para>The filtering is typically enabled by default, so adding the header typically just ensures it is enabled and
-            instructs the browser what to do when a XSS attack is detected. For example, the filter might try to change the
-            content in the least invasive way to still render everything. At times, this type of replacement can become a
-            <link xlink:href="http://hackademix.net/2009/11/21/ies-xss-filter-creates-xss-vulnerabilities/">XSS
-            vulnerability in itself</link>. Instead, it is best to block the content rather than attempt to fix it. To do this we can
-            add the following header:</para>
-        <programlisting><![CDATA[X-XSS-Protection: 1; mode=block]]></programlisting>
-        <para>This header is included by default when the &lt;headers&gt; element is specified with no child elements. We can explicitly
-            state it using the <link linkend="nsa-xss-protection">xss-protection</link> element as shown below:</para>
-        <programlisting language="xml"><![CDATA[<http ...>
-    ...
+            <para>If you want to change the value for the X-Frame-Options header, then you can use a
+                <link linkend="headers-headers-writer">XFrameOptionsHeaderWriter instance</link>.</para>
+        </section>
+        <section xml:id="headers-xss-protection">
+            <title>X-XSS-Protection</title>
+            <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
+                XSS attacks</link>. This is by no means full proof, but does assist in XSS protection.</para>
+            <para>The filtering is typically enabled by default, so adding the header typically just ensures it is enabled and
+                instructs the browser what to do when a XSS attack is detected. For example, the filter might try to change the
+                content in the least invasive way to still render everything. At times, this type of replacement can become a
+                <link xlink:href="http://hackademix.net/2009/11/21/ies-xss-filter-creates-xss-vulnerabilities/">XSS
+                vulnerability in itself</link>. Instead, it is best to block the content rather than attempt to fix it. To do this we can
+                add the following header:</para>
+            <programlisting><![CDATA[X-XSS-Protection: 1; mode=block]]></programlisting>
+            <para>This header is included by default when the &lt;headers&gt; element is specified with no child elements. We can explicitly
+                state it using the <link linkend="nsa-xss-protection">xss-protection</link> element as shown below:</para>
+            <programlisting language="xml"><![CDATA[<http>
+    <!-- ... -->
+
     <headers>
         <xss-protection />
     </headers>
 </http>]]></programlisting>
-        <para>Similarly, you can enable only xss protection within Java Configuration with the following:</para>
-        <programlisting language="java"><![CDATA[@EnableWebSecurity
+            <para>Similarly, you can enable only xss protection within Java Configuration with the following:</para>
+            <programlisting language="java"><![CDATA[@EnableWebSecurity
 @Configuration
 public class WebSecurityConfig extends
    WebSecurityConfigurerAdapter {
@@ -272,32 +304,37 @@ public class WebSecurityConfig extends
   @Override
   protected void configure(HttpSecurity http) throws Exception {
     http
+      // ...
       .headers()
-        .xssProtection()
-        .and()
-      ...;
+        .xssProtection();
   }
 }]]></programlisting>
+        </section>
     </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'
+    <section xml:id="headers-custom">
+        <title>Custom Headers</title>
+        <para>Spring Security has mechanisms to make it convenient to add the more common security headers to your application. However, it also provides
+            hooks to enable adding custom headers.</para>
+        <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">&lt;header&gt;</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
+                <para>When using the XML namespace, these headers can be added to the response using the <link linkend="nsa-header">&lt;header&gt;</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 {
@@ -305,35 +342,36 @@ public class WebSecurityConfig extends
   @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()
-      ...;
+        .addHeaderWriter(new StaticHeaderWriter("X-WebKit-CSP","default-src 'self'"));
   }
 }]]></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 ...>
-    ...
+        </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 using the <link linkend="nsa-header-ref">ref</link> attribute.</para>
+                <programlisting language="xml"><![CDATA[<http>
+    <!-- ... -->
+
     <headers>
-        <header header-ref="frameOptionsWriter"/>
+        <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"
+<beans: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
+
+        <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 {
@@ -341,12 +379,52 @@ public class WebSecurityConfig extends
   @Override
   protected void configure(HttpSecurity http) throws Exception {
     http
+      // ...
       .headers()
-        .addHeaderWriter(new XFrameOptionsHeaderWriter(XFrameOptionsMode.SAMEORIGIN))
-        .and()
-      ...;
+        .addHeaderWriter(new XFrameOptionsHeaderWriter(XFrameOptionsMode.SAMEORIGIN));
   }
 }]]></programlisting>
-    </section>
+        </section>
+        <section xml:id="headers-delegatingrequestmatcherheaderwriter">
+            <title>DelegatingRequestMatcherHeaderWriter</title>
+            <para>At times you may want to only write a header for certain requests. For example, perhaps you want to only protect your log in page from being framed. You could use the
+                <classname>DelegatingRequestMatcherHeaderWriter</classname> to do so. When using the XML namespace configuration, this can be done with the following:</para>
+                <programlisting language="xml"><![CDATA[<http>
+    <!-- ... -->
 
+    <headers>
+        <header header-ref="headerWriter"/>
+    </headers>
+</http>
+
+<beans:bean id="headerWriter"
+    class="org.springframework.security.web.header.writers.DelegatingRequestMatcherHeaderWriter">
+    <beans:constructor-arg>
+        <bean class="org.springframework.security.web.util.AntPathRequestMatcher"
+            c:pattern="/login"/>
+    </beans:constructor-arg>
+    <beans:constructor-arg>
+        <beans:bean
+            class="org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter"/>
+    </beans:constructor-arg>
+</beans:bean>]]></programlisting>
+        <para>We could also prevent framing of content to the log in page using java configuration:</para>
+            <programlisting language="java"><![CDATA[@EnableWebSecurity
+@Configuration
+public class WebSecurityConfig extends
+   WebSecurityConfigurerAdapter {
+
+  @Override
+  protected void configure(HttpSecurity http) throws Exception {
+    RequestMatcher matcher = new AntPathRequestMatcher("/login");
+    DelegatingRequestMatcherHeaderWriter headerWriter =
+        new DelegatingRequestMatcherHeaderWriter(matcher,new XFrameOptionsHeaderWriter());
+    http
+      // ...
+      .headers()
+        .addHeaderWriter(headerWriter);
+  }
+}]]></programlisting>
+        </section>
+    </section>
 </chapter>

+ 2 - 2
docs/manual/src/docbook/namespace-config.xml

@@ -659,8 +659,8 @@ List&lt;OpenIDAttribute> attributes = token.getAttributes();</programlisting>The
 </http>]]>
                 </programlisting>
             </para>
-            <para>For additional information on how to customize the headers element refer to the <link linkend="nsa-headers">headers</link>
-                section of the Security Namespace appendix.</para>
+            <para>For additional information on how to customize the headers element refer to the <link linkend="headers">Security Headers</link>
+                section of the reference.</para>
         </section>
         <section xml:id="ns-custom-filters">
             <title>Adding in Your Own Filters</title>