| <?xml version="1.0" encoding="UTF-8"?> |
| <!-- |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to You 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. |
| --> |
| <!DOCTYPE document [ |
| <!ENTITY project SYSTEM "project.xml"> |
| ]> |
| <document url="filter.html"> |
| |
| &project; |
| |
| <properties> |
| <title>Container Provided Filters</title> |
| </properties> |
| |
| <body> |
| |
| <section name="Table of Contents"> |
| <toc/> |
| </section> |
| |
| <section name="Introduction"> |
| |
| <p>Tomcat provides a number of <strong>Filters</strong> which may be |
| configured for use with all web applications using |
| <code>$CATALINA_BASE/conf/web.xml</code> or may be configured for individual |
| web applications by configuring them in the application's |
| <code>WEB-INF/web.xml</code>. Each filter is described below.</p> |
| |
| <p><em>This description uses the variable name $CATALINA_BASE to refer the |
| base directory against which most relative paths are resolved. If you have |
| not configured Tomcat for multiple instances by setting a CATALINA_BASE |
| directory, then $CATALINA_BASE will be set to the value of $CATALINA_HOME, |
| the directory into which you have installed Tomcat.</em></p> |
| |
| </section> |
| |
| |
| <section name="Add Default Character Set Filter"> |
| |
| <subsection name="Introduction"> |
| |
| <p>The HTTP specification is clear that if no character set is specified for |
| media sub-types of the "text" media type, the ISO-8859-1 character set must |
| be used. However, browsers may attempt to auto-detect the character set. |
| This may be exploited by an attacker to perform an XSS attack. Internet |
| Explorer and other browsers have an option to |
| enable this behavior.</p> |
| |
| <p>This filter prevents the attack by explicitly setting a character set. |
| Unless the provided character set is explicitly overridden by the user the |
| browser will adhere to the explicitly set character set, thus preventing the |
| XSS attack.</p> |
| |
| </subsection> |
| |
| <subsection name="Filter Class Name"> |
| |
| <p>The filter class name for the Add Default Character Set Filter is |
| <strong><code>org.apache.catalina.filters.AddDefaultCharsetFilter</code> |
| </strong>.</p> |
| |
| </subsection> |
| |
| <subsection name="Initialisation parameters"> |
| |
| <p>The Add Default Character Set Filter supports the following initialization |
| parameters:</p> |
| |
| <attributes> |
| |
| <attribute name="encoding" required="false"> |
| <p>Name of the character set which should be set, if no other character set |
| was set explicitly by a Servlet. This parameter has two special values |
| <code>default</code> and <code>system</code>. A value of <code>system</code> |
| uses the JVM wide default character set, which is usually set by locale. |
| A value of <code>default</code> will use <strong>ISO-8859-1</strong>.</p> |
| </attribute> |
| |
| </attributes> |
| |
| </subsection> |
| |
| </section> |
| |
| <section name="CORS Filter"> |
| <subsection name="Introduction"> |
| <p>This filter is an implementation of W3C's CORS (Cross-Origin Resource |
| Sharing) <a href="http://www.w3.org/TR/cors/">specification</a>, which is a |
| mechanism that enables cross-origin requests.</p> |
| <p>The filter works by adding required <code>Access-Control-*</code> headers |
| to HttpServletResponse object. The filter also protects against HTTP |
| response splitting. If request is invalid, or is not permitted, then request |
| is rejected with HTTP status code 403 (Forbidden). A |
| <a href="../images/cors-flowchart.png">flowchart</a> that |
| demonstrates request processing by this filter is available.</p> |
| <p>The minimal configuration required to use this filter is:</p> |
| <source><![CDATA[<filter> |
| <filter-name>CorsFilter</filter-name> |
| <filter-class>org.apache.catalina.filters.CorsFilter</filter-class> |
| </filter> |
| <filter-mapping> |
| <filter-name>CorsFilter</filter-name> |
| <url-pattern>/*</url-pattern> |
| </filter-mapping>]]></source> |
| </subsection> |
| <subsection name="Filter Class Name"> |
| <p>The filter class name for the CORS Filter is |
| <strong><code>org.apache.catalina.filters.CorsFilter</code></strong>.</p> |
| </subsection> |
| <subsection name="Initialisation parameters"> |
| <p>The CORS Filter supports following initialisation parameters:</p> |
| <attributes> |
| <attribute name="cors.allowed.origins" required="false"> |
| <p>A list of <a href="http://tools.ietf.org/html/rfc6454">origins</a> |
| that are allowed to access the resource. A <code>*</code> can be |
| specified to enable access to resource from any origin. Otherwise, a |
| whitelist of comma separated origins can be provided. Eg: <code> |
| http://www.w3.org, https://www.apache.org</code>. |
| <strong>Defaults:</strong> <code>*</code> (Any origin is allowed to |
| access the resource).</p> |
| </attribute> |
| <attribute name="cors.allowed.methods" required="false"> |
| <p>A comma separated list of HTTP methods that can be used to access the |
| resource, using cross-origin requests. These are the methods which will |
| also be included as part of <code>Access-Control-Allow-Methods</code> |
| header in pre-flight response. Eg: <code>GET, POST</code>. |
| <strong>Defaults:</strong> <code>GET, POST, HEAD, OPTIONS</code></p> |
| </attribute> |
| <attribute name="cors.allowed.headers" required="false"> |
| <p>A comma separated list of request headers that can be used when |
| making an actual request. These headers will also be returned as part |
| of <code>Access-Control-Allow-Headers</code> header in a pre-flight |
| response. Eg: <code>Origin,Accept</code>. <strong>Defaults:</strong> |
| <code>Origin, Accept, X-Requested-With, Content-Type, |
| Access-Control-Request-Method, Access-Control-Request-Headers</code></p> |
| </attribute> |
| <attribute name="cors.exposed.headers" required="false"> |
| <p>A comma separated list of headers other than simple response headers |
| that browsers are allowed to access. These are the headers which will |
| also be included as part of <code>Access-Control-Expose-Headers</code> |
| header in the pre-flight response. Eg: |
| <code>X-CUSTOM-HEADER-PING,X-CUSTOM-HEADER-PONG</code>. |
| <strong>Default:</strong> None. Non-simple headers are not exposed by |
| default.</p> |
| </attribute> |
| <attribute name="cors.preflight.maxage" required="false"> |
| <p>The amount of seconds, browser is allowed to cache the result of the |
| pre-flight request. This will be included as part of |
| <code>Access-Control-Max-Age</code> header in the pre-flight response. |
| A negative value will prevent CORS Filter from adding this response |
| header to pre-flight response. <strong>Defaults:</strong> |
| <code>1800</code></p> |
| </attribute> |
| <attribute name="cors.support.credentials" required="false"> |
| <p>A flag that indicates whether the resource supports user credentials. |
| This flag is exposed as part of |
| <code>Access-Control-Allow-Credentials</code> header in a pre-flight |
| response. It helps browser determine whether or not an actual request |
| can be made using credentials. <strong>Defaults:</strong> |
| <code>true</code></p> |
| </attribute> |
| <attribute name="cors.request.decorate" required="false"> |
| <p>A flag to control if CORS specific attributes should be added to |
| HttpServletRequest object or not. <strong>Defaults:</strong> |
| <code>true</code></p> |
| </attribute> |
| </attributes> |
| <p>Here's an example of a more advanced configuration, that overrides |
| defaults:</p> |
| <source><![CDATA[<filter> |
| <filter-name>CorsFilter</filter-name> |
| <filter-class>org.apache.catalina.filters.CorsFilter</filter-class> |
| <init-param> |
| <param-name>cors.allowed.origins</param-name> |
| <param-value>*</param-value> |
| </init-param> |
| <init-param> |
| <param-name>cors.allowed.methods</param-name> |
| <param-value>GET,POST,HEAD,OPTIONS,PUT</param-value> |
| </init-param> |
| <init-param> |
| <param-name>cors.allowed.headers</param-name> |
| <param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value> |
| </init-param> |
| <init-param> |
| <param-name>cors.exposed.headers</param-name> |
| <param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value> |
| </init-param> |
| <init-param> |
| <param-name>cors.support.credentials</param-name> |
| <param-value>true</param-value> |
| </init-param> |
| <init-param> |
| <param-name>cors.preflight.maxage</param-name> |
| <param-value>10</param-value> |
| </init-param> |
| </filter> |
| <filter-mapping> |
| <filter-name>CorsFilter</filter-name> |
| <url-pattern>/*</url-pattern> |
| </filter-mapping>]]></source> |
| </subsection> |
| <subsection name="CORS Filter and HttpServletRequest attributes"> |
| <p>CORS Filter adds information about the request, in HttpServletRequest |
| object, for consumption downstream. Following attributes are set, if |
| <code>cors.request.decorate</code> initialisation parameter is |
| <code>true</code>:</p> |
| <ul> |
| <li><strong>cors.isCorsRequest:</strong> Flag to determine if request is |
| a CORS request.</li> |
| <li><strong>cors.request.origin:</strong> The Origin URL, i.e. the URL of |
| the page from where the request originated.</li> |
| <li><strong>cors.request.type:</strong> Type of CORS request. Possible |
| values: |
| <ul> |
| <li><code>SIMPLE</code>: A request which is not preceded by a |
| pre-flight request.</li> |
| <li><code>ACTUAL</code>: A request which is preceded by a pre-flight |
| request.</li> |
| <li><code>PRE_FLIGHT</code>: A pre-flight request.</li> |
| <li><code>NOT_CORS</code>: A normal same-origin request.</li> |
| <li><code>INVALID_CORS</code>: A cross-origin request, which is |
| invalid.</li> |
| </ul> |
| </li> |
| <li><strong>cors.request.headers:</strong> Request headers sent as |
| <code>Access-Control-Request-Headers</code> header, for a pre-flight |
| request. |
| </li> |
| </ul> |
| </subsection> |
| </section> |
| |
| <section name="CSRF Prevention Filter"> |
| |
| <subsection name="Introduction"> |
| |
| <p>This filter provides basic CSRF protection for a web application. The |
| filter assumes that it is mapped to <code>/*</code> and that all URLs |
| returned to the client are encoded via a call to |
| <code>HttpServletResponse#encodeRedirectURL(String)</code> or |
| <code>HttpServletResponse#encodeURL(String)</code>.</p> |
| |
| <p>This filter prevents CSRF by generating a nonce and storing it in the |
| session. URLs are also encoded with the same nonce. When the next request is |
| received the nonce in the request is compared to the nonce in the session |
| and only if they are the same is the request allowed to continue.</p> |
| |
| </subsection> |
| |
| <subsection name="Filter Class Name"> |
| |
| <p>The filter class name for the CSRF Prevention Filter is |
| <strong><code>org.apache.catalina.filters.CsrfPreventionFilter</code> |
| </strong>.</p> |
| |
| </subsection> |
| |
| <subsection name="Initialisation parameters"> |
| |
| <p>The CSRF Prevention Filter supports the following initialisation |
| parameters:</p> |
| |
| <attributes> |
| |
| <attribute name="denyStatus" required="false"> |
| <p>HTTP response status code that is used when rejecting denied |
| request. The default value is <code>403</code>.</p> |
| </attribute> |
| |
| <attribute name="entryPoints" required="false"> |
| <p>A comma separated list of URLs that will not be tested for the |
| presence of a valid nonce. They are used to provide a way to navigate |
| back to a protected application after having navigated away from it. |
| Entry points will be limited to HTTP GET requests and should not trigger |
| any security sensitive actions.</p> |
| </attribute> |
| |
| <attribute name="nonceCacheSize" required="false"> |
| <p>The number of previously issued nonces that will be cached on a LRU |
| basis to support parallel requests, limited use of the refresh and back |
| in the browser and similar behaviors that may result in the submission |
| of a previous nonce rather than the current one. If not set, the default |
| value of 5 will be used.</p> |
| </attribute> |
| |
| <attribute name="randomClass" required="false"> |
| <p>The name of the class to use to generate nonces. The class must be an |
| instance of <code>java.util.Random</code>. If not set, the default value |
| of <code>java.security.SecureRandom</code> will be used.</p> |
| </attribute> |
| |
| </attributes> |
| |
| </subsection> |
| |
| </section> |
| |
| <section name="CSRF Prevention Filter for REST APIs"> |
| |
| <subsection name="Introduction"> |
| |
| <p>This filter provides basic CSRF protection for REST APIs. The CSRF |
| protection is applied only for modifying HTTP requests (different from GET, |
| HEAD, OPTIONS) to protected resources. It is based on a custom header |
| <code>X-CSRF-Token</code> that provides a valid nonce.</p> |
| |
| <p>CSRF protection mechanism for REST APIs consists of the following steps: |
| <ul> |
| <li>Client asks for a valid nonce. This is performed with a |
| non-modifying "Fetch" request to protected resource.</li> |
| <li>Server responds with a valid nonce mapped to the current user |
| session.</li> |
| <li>Client provides this nonce in the subsequent modifying requests in |
| the frame of the same user session.</li> |
| <li>Server rejects all modifying requests to protected resources that |
| do not contain a valid nonce.</li> |
| </ul> |
| </p> |
| |
| </subsection> |
| |
| <subsection name="Basic configuration sample"> |
| |
| <p>On the server side</p> |
| |
| <ul> |
| <li>All CSRF protected REST APIs should be protected with an authentication |
| mechanism.</li> |
| <li>Protect modifying REST APIs with this filter.</li> |
| <li>Provide at least one non-modifying operation.</li> |
| </ul> |
| <source><![CDATA[<filter> |
| <filter-name>RestCSRF</filter-name> |
| <filter-class>org.apache.catalina.filters.RestCsrfPreventionFilter</filter-class> |
| </filter> |
| <filter-mapping> |
| <filter-name>RestCSRF</filter-name> |
| <!-- Modifying operations --> |
| <url-pattern>/resources/removeResource</url-pattern> |
| <url-pattern>/resources/addResource</url-pattern> |
| <!-- Non-modifying operations --> |
| <url-pattern>/resources/listResources</url-pattern> |
| </filter-mapping>]]></source> |
| |
| <p>On the client side</p> |
| |
| <ul> |
| <li>Make a non-modifying "Fetch" request in order to obtain a valid nonce. |
| This can be done with sending additional header |
| <code>X-CSRF-Token: Fetch</code></li> |
| <li>Cache the returned session id and nonce in order to provide them in |
| the subsequent modifying requests to protected resources.</li> |
| <li>Modifying requests can be denied and header |
| <code>X-CSRF-Token: Required</code> will be returned in case of |
| invalid or missing nonce, expired session or in case the session |
| id is changed by the server.</li> |
| </ul> |
| <source><![CDATA[Client Request: |
| GET /rest/resources/listResources HTTP/1.1 |
| X-CSRF-Token: Fetch |
| Authorization: Basic ... |
| Host: localhost:8080 |
| ... |
| |
| Server Response: |
| HTTP/1.1 200 OK |
| Set-Cookie: JSESSIONID=...; Path=/rest; HttpOnly |
| X-CSRF-Token: ... |
| ... |
| |
| Client Request: |
| POST /rest/resources/addResource HTTP/1.1 |
| Cookie: JSESSIONID=... |
| X-CSRF-Token: ... |
| Authorization: Basic ... |
| Host: localhost:8080 |
| ... |
| |
| Server Response: |
| HTTP/1.1 200 OK |
| ...]]></source> |
| |
| </subsection> |
| |
| <subsection name="RestCsrfPreventionFilter and HttpServletRequest parameters"> |
| |
| <p>When the client is not able to insert custom headers in its calls to |
| REST APIs there is additional capability to configure URLs for which a |
| valid nonce will be accepted as a request parameter.</p> |
| |
| <p>Note: If there is a <code>X-CSRF-Token</code> header, it will be taken |
| with preference over any parameter with the same name in the request. |
| Request parameters cannot be used to fetch new nonce, only header can be |
| used to request a new nonce.</p> |
| |
| <source><![CDATA[<filter> |
| <filter-name>RestCSRF</filter-name> |
| <filter-class>org.apache.catalina.filters.RestCsrfPreventionFilter</filter-class> |
| <init-param> |
| <param-name>pathsAcceptingParams</param-name> |
| <param-value>/resources/removeResource,/resources/addResource</param-value> |
| </init-param> |
| </filter> |
| <filter-mapping> |
| <filter-name>RestCSRF</filter-name> |
| <url-pattern>/resources/*</url-pattern> |
| </filter-mapping>]]></source> |
| |
| </subsection> |
| |
| <subsection name="Filter Class Name"> |
| |
| <p>The filter class name for the CSRF Prevention Filter for REST APIs is |
| <strong><code>org.apache.catalina.filters.RestCsrfPreventionFilter</code> |
| </strong>.</p> |
| |
| </subsection> |
| |
| <subsection name="Initialisation parameters"> |
| |
| <p>The CSRF Prevention Filter for REST APIs supports the following |
| initialisation parameters:</p> |
| |
| <attributes> |
| |
| <attribute name="denyStatus" required="false"> |
| <p>HTTP response status code that is used when rejecting denied |
| request. The default value is <code>403</code>.</p> |
| </attribute> |
| |
| <attribute name="pathsAcceptingParams" required="false"> |
| <p>A comma separated list of URLs that can accept nonces via request |
| parameter <code>X-CSRF-Token</code>. For use cases when a nonce information cannot |
| be provided via header, one can provide it via request parameters. If |
| there is a <code>X-CSRF-Token</code> header, it will be taken with preference over |
| any parameter with the same name in the request. Request parameters |
| cannot be used to fetch new nonce, only header can be used to request a |
| new nonce.</p> |
| </attribute> |
| |
| <attribute name="randomClass" required="false"> |
| <p>The name of the class to use to generate nonces. The class must be an |
| instance of <code>java.util.Random</code>. If not set, the default value |
| of <code>java.security.SecureRandom</code> will be used.</p> |
| </attribute> |
| |
| </attributes> |
| |
| </subsection> |
| |
| </section> |
| |
| <section name="Expires Filter"> |
| |
| <subsection name="Introduction"> |
| |
| <p> |
| ExpiresFilter is a Java Servlet API port of <a |
| href="http://httpd.apache.org/docs/2.2/mod/mod_expires.html">Apache |
| mod_expires</a>. |
| This filter controls the setting of the <code>Expires</code> HTTP header and the |
| <code>max-age</code> directive of the <code>Cache-Control</code> HTTP header in |
| server responses. The expiration date can set to be relative to either the |
| time the source file was last modified, or to the time of the client access. |
| </p> |
| |
| <p> |
| These HTTP headers are an instruction to the client about the document's |
| validity and persistence. If cached, the document may be fetched from the |
| cache rather than from the source until this time has passed. After that, the |
| cache copy is considered "expired" and invalid, and a new copy must |
| be obtained from the source. |
| </p> |
| <p> |
| To modify <code>Cache-Control</code> directives other than <code>max-age</code> (see |
| <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9" >RFC |
| 2616 section 14.9</a>), you can use other servlet filters or <a |
| href="http://httpd.apache.org/docs/2.2/mod/mod_headers.html" >Apache Httpd |
| mod_headers</a> module. |
| </p> |
| |
| </subsection> |
| |
| <subsection name="Basic configuration sample"> |
| <p> |
| Basic configuration to add '<code>Expires</code>' and '<code>Cache-Control: max-age=</code>' |
| headers to images, css and javascript. |
| </p> |
| |
| <source><![CDATA[<filter> |
| <filter-name>ExpiresFilter</filter-name> |
| <filter-class>org.apache.catalina.filters.ExpiresFilter</filter-class> |
| <init-param> |
| <param-name>ExpiresByType image</param-name> |
| <param-value>access plus 10 minutes</param-value> |
| </init-param> |
| <init-param> |
| <param-name>ExpiresByType text/css</param-name> |
| <param-value>access plus 10 minutes</param-value> |
| </init-param> |
| <init-param> |
| <param-name>ExpiresByType application/javascript</param-name> |
| <param-value>access plus 10 minutes</param-value> |
| </init-param> |
| </filter> |
| ... |
| <filter-mapping> |
| <filter-name>ExpiresFilter</filter-name> |
| <url-pattern>/*</url-pattern> |
| <dispatcher>REQUEST</dispatcher> |
| </filter-mapping>]]></source> |
| |
| </subsection> |
| |
| <subsection name="Alternate Syntax"> |
| <p> |
| The <code>ExpiresDefault</code> and <code>ExpiresByType</code> directives can also be |
| defined in a more readable syntax of the form: |
| </p> |
| |
| <source><![CDATA[<init-param> |
| <param-name>ExpiresDefault</param-name> |
| <param-value><base> [plus] {<num> <type>}*</param-value> |
| </init-param> |
| |
| <init-param> |
| <param-name>ExpiresByType type</param-name> |
| <param-value><base> [plus] {<num> <type>}*</param-value> |
| </init-param> |
| |
| <init-param> |
| <param-name>ExpiresByType type;encoding</param-name> |
| <param-value><base> [plus] {<num> <type>}*</param-value> |
| </init-param>]]></source> |
| <p> |
| where <code><base></code> is one of: |
| </p> |
| <ul> |
| <li><code>access</code></li> |
| <li><code>now</code> (equivalent to '<code>access</code>')</li> |
| <li><code>modification</code></li> |
| </ul> |
| |
| <p> |
| The <code>plus</code> keyword is optional. <code><num></code> should be an |
| integer value (acceptable to <code>Integer.parseInt()</code>), and |
| <code><type></code> is one of: |
| </p> |
| <ul> |
| <li><code>year</code>, <code>years</code></li> |
| <li><code>month</code>, <code>months</code></li> |
| <li><code>week</code>, <code>weeks</code></li> |
| <li><code>day</code>, <code>days</code></li> |
| <li><code>hour</code>, <code>hours</code></li> |
| <li><code>minute</code>, <code>minutes</code></li> |
| <li><code>second</code>, <code>seconds</code></li> |
| </ul> |
| <p> |
| For example, any of the following directives can be used to make documents |
| expire 1 month after being accessed, by default: |
| </p> |
| |
| <source><![CDATA[<init-param> |
| <param-name>ExpiresDefault</param-name> |
| <param-value>access plus 1 month</param-value> |
| </init-param> |
| |
| <init-param> |
| <param-name>ExpiresDefault</param-name> |
| <param-value>access plus 4 weeks</param-value> |
| </init-param> |
| |
| <init-param> |
| <param-name>ExpiresDefault</param-name> |
| <param-value>access plus 30 days</param-value> |
| </init-param>]]></source> |
| <p> |
| The expiry time can be fine-tuned by adding several |
| '<code><num> <type></code>' clauses: |
| </p> |
| |
| <source><![CDATA[<init-param> |
| <param-name>ExpiresByType text/html</param-name> |
| <param-value>access plus 1 month 15 days 2 hours</param-value> |
| </init-param> |
| |
| <init-param> |
| <param-name>ExpiresByType image/gif</param-name> |
| <param-value>modification plus 5 hours 3 minutes</param-value> |
| </init-param>]]></source> |
| <p> |
| Note that if you use a modification date based setting, the <code>Expires</code> |
| header will <strong>not</strong> be added to content that does not come from |
| a file on disk. This is due to the fact that there is no modification time |
| for such content. |
| </p> |
| </subsection> |
| |
| <subsection name="Expiration headers generation eligibility"> |
| <p> |
| A response is eligible to be enriched by <code>ExpiresFilter</code> if : |
| </p> |
| <ol> |
| <li>no expiration header is defined (<code>Expires</code> header or the |
| <code>max-age</code> directive of the <code>Cache-Control</code> header),</li> |
| <li>the response status code is not excluded by the directive |
| <code>ExpiresExcludedResponseStatusCodes</code>,</li> |
| <li>the <code>Content-Type</code> of the response matches one of the types |
| defined the in <code>ExpiresByType</code> directives or the |
| <code>ExpiresDefault</code> directive is defined.</li> |
| </ol> |
| |
| <p> |
| Note : If <code>Cache-Control</code> header contains other directives than |
| <code>max-age</code>, they are concatenated with the <code>max-age</code> directive |
| that is added by the <code>ExpiresFilter</code>. |
| </p> |
| |
| </subsection> |
| |
| <subsection name="Expiration configuration selection"> |
| <p> |
| The expiration configuration if elected according to the following algorithm: |
| </p> |
| <ol> |
| <li><code>ExpiresByType</code> matching the exact content-type returned by |
| <code>HttpServletResponse.getContentType()</code> possibly including the charset |
| (e.g. '<code>text/xml;charset=UTF-8</code>'),</li> |
| <li><code>ExpiresByType</code> matching the content-type without the charset if |
| <code>HttpServletResponse.getContentType()</code> contains a charset (e.g. |
| '<code>text/xml;charset=UTF-8</code>' -> '<code>text/xml</code>'),</li> |
| <li><code>ExpiresByType</code> matching the major type (e.g. substring before |
| '<code>/</code>') of <code>HttpServletResponse.getContentType()</code> |
| (e.g. '<code>text/xml;charset=UTF-8</code>' -> '<code>text</code>'),</li> |
| <li><code>ExpiresDefault</code></li> |
| </ol> |
| |
| </subsection> |
| |
| <subsection name="Filter Class Name"> |
| |
| <p>The filter class name for the Expires Filter is |
| <strong><code>org.apache.catalina.filters.ExpiresFilter</code> |
| </strong>.</p> |
| |
| </subsection> |
| |
| <subsection name="Initialisation parameters"> |
| |
| <p>The <strong>Expires Filter</strong> supports the following |
| initialisation parameters:</p> |
| |
| <attributes> |
| |
| <attribute name="ExpiresExcludedResponseStatusCodes" required="false"> |
| <p> |
| This directive defines the http response status codes for which the |
| <code>ExpiresFilter</code> will not generate expiration headers. By default, the |
| <code>304</code> status code ("<code>Not modified</code>") is skipped. The |
| value is a comma separated list of http status codes. |
| </p> |
| <p> |
| This directive is useful to ease usage of <code>ExpiresDefault</code> directive. |
| Indeed, the behavior of <code>304 Not modified</code> (which does specify a |
| <code>Content-Type</code> header) combined with <code>Expires</code> and |
| <code>Cache-Control:max-age=</code> headers can be unnecessarily tricky to |
| understand. |
| </p> |
| <p><i>See sample below the table</i></p> |
| </attribute> |
| |
| <attribute name="ExpiresByType <content-type>" required="false"> |
| <p> |
| This directive defines the value of the <code>Expires</code> header and the |
| <code>max-age</code> directive of the <code>Cache-Control</code> header generated for |
| documents of the specified type (<i>e.g.</i>, <code>text/html</code>). The second |
| argument sets the number of seconds that will be added to a base time to |
| construct the expiration date. The <code>Cache-Control: max-age</code> is |
| calculated by subtracting the request time from the expiration date and |
| expressing the result in seconds. |
| </p> |
| <p> |
| The base time is either the last modification time of the file, or the time |
| of the client's access to the document. Which should be used is |
| specified by the <code><code></code> field; <code>M</code> means that the |
| file's last modification time should be used as the base time, and |
| <code>A</code> means the client's access time should be used. The duration |
| is expressed in seconds. <code>A2592000</code> stands for |
| <code>access plus 30 days</code> in alternate syntax. |
| </p> |
| <p> |
| The difference in effect is subtle. If <code>M</code> (<code>modification</code> in |
| alternate syntax) is used, all current copies of the document in all caches |
| will expire at the same time, which can be good for something like a weekly |
| notice that's always found at the same URL. If <code>A</code> ( |
| <code>access</code> or <code>now</code> in alternate syntax) is used, the date of |
| expiration is different for each client; this can be good for image files |
| that don't change very often, particularly for a set of related |
| documents that all refer to the same images (<i>i.e.</i>, the images will be |
| accessed repeatedly within a relatively short timespan). |
| </p> |
| <p> |
| <strong>Note:</strong> When the content type includes a charset (e.g. |
| <code>'ExpiresByType text/xml;charset=utf-8'</code>), Tomcat removes blank chars |
| between the '<code>;</code>' and the '<code>charset</code>' keyword. Due to this, |
| configuration of an expiration with a charset must <strong>not</strong> include |
| such a space character. |
| </p> |
| <p><i>See sample below the table</i></p> |
| <p> |
| It overrides, for the specified MIME type <i>only</i>, any |
| expiration date set by the <code>ExpiresDefault</code> directive. |
| </p> |
| <p> |
| You can also specify the expiration time calculation using an alternate |
| syntax, described earlier in this document. |
| </p> |
| </attribute> |
| |
| <attribute name="ExpiresDefault" required="false"> |
| <p> |
| This directive sets the default algorithm for calculating the |
| expiration time for all documents in the affected realm. It can be |
| overridden on a type-by-type basis by the <code>ExpiresByType</code> directive. See the |
| description of that directive for details about the syntax of the |
| argument, and the "alternate syntax" |
| description as well. |
| </p> |
| </attribute> |
| </attributes> |
| |
| <p><i>Sample: exclude response status codes 302, 500 and 503</i></p> |
| |
| <source><![CDATA[<init-param> |
| <param-name>ExpiresExcludedResponseStatusCodes</param-name> |
| <param-value>302, 500, 503</param-value> |
| </init-param>]]></source> |
| |
| <p><i>Sample for ExpiresByType initialization parameter</i></p> |
| |
| <source><![CDATA[<init-param> |
| <param-name>ExpiresByType text/html</param-name> |
| <param-value>access plus 1 month 15 days 2 hours</param-value> |
| </init-param> |
| |
| <init-param> |
| <!-- 2592000 seconds = 30 days --> |
| <param-name>ExpiresByType image/gif</param-name> |
| <param-value>A2592000</param-value> |
| </init-param>]]></source> |
| |
| </subsection> |
| |
| <subsection name="Troubleshooting"> |
| <p> |
| To troubleshoot, enable logging on the |
| <code>org.apache.catalina.filters.ExpiresFilter</code>. |
| </p> |
| <p> |
| Extract of logging.properties |
| </p> |
| |
| <source>org.apache.catalina.filters.ExpiresFilter.level = FINE </source> |
| <p> |
| Sample of initialization log message: |
| </p> |
| |
| <source>Mar 26, 2010 2:01:41 PM org.apache.catalina.filters.ExpiresFilter init |
| FINE: Filter initialized with configuration ExpiresFilter[ |
| excludedResponseStatusCode=[304], |
| default=null, |
| byType={ |
| image=ExpiresConfiguration[startingPoint=ACCESS_TIME, duration=[10 MINUTE]], |
| text/css=ExpiresConfiguration[startingPoint=ACCESS_TIME, duration=[10 MINUTE]], |
| text/javascript=ExpiresConfiguration[startingPoint=ACCESS_TIME, duration=[10 MINUTE]]}]</source> |
| <p> |
| Sample of per-request log message where <code>ExpiresFilter</code> adds an |
| expiration date is below. The message is on one line and is wrapped here |
| for better readability. |
| </p> |
| |
| <source>Mar 26, 2010 2:09:47 PM org.apache.catalina.filters.ExpiresFilter onBeforeWriteResponseBody |
| FINE: Request "/tomcat.gif" with response status "200" |
| content-type "image/gif", set expiration date 3/26/10 2:19 PM</source> |
| <p> |
| Sample of per-request log message where <code>ExpiresFilter</code> does not add |
| an expiration date: |
| </p> |
| |
| <source>Mar 26, 2010 2:10:27 PM org.apache.catalina.filters.ExpiresFilter onBeforeWriteResponseBody |
| FINE: Request "/docs/config/manager.html" with response status "200" |
| content-type "text/html", no expiration configured</source> |
| </subsection> |
| |
| </section> |
| |
| <section name="Failed Request Filter"> |
| |
| <subsection name="Introduction"> |
| |
| <p>This filter triggers parameters parsing in a request and rejects the |
| request if some parameters were skipped during parameter parsing because |
| of parsing errors or request size limitations (such as |
| <code>maxParameterCount</code> attribute in a |
| <a href="http.html">Connector</a>). |
| This filter can be used to ensure that none parameter values submitted by |
| client are lost.</p> |
| |
| <p>Note that parameter parsing may consume the body of an HTTP request, so |
| caution is needed if the servlet protected by this filter uses |
| <code>request.getInputStream()</code> or <code>request.getReader()</code> |
| calls. In general the risk of breaking a web application by adding this |
| filter is not so high, because parameter parsing does check content type |
| of the request before consuming the request body.</p> |
| |
| <p>Note, that for the POST requests to be parsed correctly, a |
| <code>SetCharacterEncodingFilter</code> filter must be configured above |
| this one. See CharacterEncoding page in the FAQ for details.</p> |
| |
| <p>The request is rejected with HTTP status code 400 (Bad Request).</p> |
| |
| </subsection> |
| |
| <subsection name="Filter Class Name"> |
| |
| <p>The filter class name for the Failed Request Filter is |
| <strong><code>org.apache.catalina.filters.FailedRequestFilter</code> |
| </strong>.</p> |
| |
| </subsection> |
| |
| <subsection name="Initialisation parameters"> |
| |
| <p>The Failed Request Filter does not support any initialization parameters.</p> |
| |
| </subsection> |
| |
| </section> |
| |
| <section name="HTTP Header Security Filter"> |
| |
| <subsection name="Introduction"> |
| |
| <p>There are a number of HTTP headers that can be added to the response to |
| improve the security of the connection. This filter provides a mechanism for |
| adding those headers. Note that security related headers with more complex |
| requirements, like CORS, are implemented as separate Filters.</p> |
| |
| </subsection> |
| |
| <subsection name="Filter Class Name"> |
| |
| <p>The filter class name for the HTTP Header Security Filter is |
| <strong><code>org.apache.catalina.filters.HttpHeaderSecurityFilter</code> |
| </strong>.</p> |
| |
| </subsection> |
| |
| <subsection name="Initialisation parameters"> |
| |
| <p>The HTTP Header Security Filter supports the following initialization |
| parameters:</p> |
| |
| <attributes> |
| |
| <attribute name="hstsEnabled" required="false"> |
| <p>Will an HTTP Strict Transport Security (HSTS) header |
| (<code>Strict-Transport-Security</code>) be set on the response for |
| secure requests. Any HSTS header already present will be replaced. See |
| <a href="http://tools.ietf.org/html/rfc6797">RFC 6797</a> for further |
| details of HSTS. If not specified, the default value of |
| <code>true</code> will be used.</p> |
| </attribute> |
| |
| <attribute name="hstsMaxAgeSeconds" required="false"> |
| <p>The max age value that should be used in the HSTS header. Negative |
| values will be treated as zero. If not specified, the default value of |
| <code>0</code> will be used.</p> |
| </attribute> |
| |
| <attribute name="hstsIncludeSubDomains" required="false"> |
| <p>Should the includeSubDomains parameter be included in the HSTS |
| header. If not specified, the default value of <code>false</code> will |
| be used.</p> |
| </attribute> |
| |
| <attribute name="hstsPreload" required="false"> |
| <p>Should the preload parameter be included in the HSTS header. If not |
| specified, the default value of <code>false</code> will be used. See |
| <a href="https://hstspreload.org/">https://hstspreload.org</a> for |
| important information about this parameter.</p> |
| </attribute> |
| |
| <attribute name="antiClickJackingEnabled" required="false"> |
| <p>Should the anti click-jacking header (<code>X-Frame-Options</code>) |
| be set on the response. Any anti click-jacking header already present |
| will be replaced. If not specified, the default value of |
| <code>true</code> will be used.</p> |
| </attribute> |
| |
| <attribute name="antiClickJackingOption" required="false"> |
| <p>What value should be used for the anticlick-jacking header? Must be |
| one of <code>DENY</code>, <code>SAMEORIGIN</code>, |
| <code>ALLOW-FROM </code> (case-insensitive). If not specified, the |
| default value of <code>DENY</code> will be used.</p> |
| </attribute> |
| |
| <attribute name="antiClickJackingUri" required="false"> |
| <p>If ALLOW-FROM is used for <strong>antiClickJackingOption</strong>, |
| what URI should be allowed? If not specified, the default value of an |
| empty string will be used.</p> |
| </attribute> |
| |
| <attribute name="blockContentTypeSniffingEnabled" required="false"> |
| <p>Should the header that blocks content type sniffing |
| (<code>X-Content-Type-Options</code>) be set on every response. If |
| already present, the header will be replaced. If not specified, the |
| default value of <code>true</code> will be used.</p> |
| </attribute> |
| |
| <attribute name="xssProtectionEnabled" required="false"> |
| <p>Should the header that enables the browser's cross-site scripting |
| filter protection (<code>X-XSS-Protection: 1; mode=block</code>) |
| be set on every response. If already present, the header |
| will be replaced. If not specified, the default value of |
| <code>true</code> will be used.</p> |
| </attribute> |
| |
| </attributes> |
| |
| </subsection> |
| |
| </section> |
| |
| <section name="Remote Address Filter"> |
| |
| <subsection name="Introduction"> |
| |
| <p>The <strong>Remote Address Filter</strong> allows you to compare the |
| IP address of the client that submitted this request against one or more |
| <em>regular expressions</em>, and either allow the request to continue |
| or refuse to process the request from this client. </p> |
| |
| <p>The syntax for <em>regular expressions</em> is different than that for |
| 'standard' wildcard matching. Tomcat uses the <code>java.util.regex</code> |
| package. Please consult the Java documentation for details of the |
| expressions supported.</p> |
| |
| <p><strong>Note:</strong> There is a caveat when using this filter with |
| IPv6 addresses. Format of the IP address that this valve is processing |
| depends on the API that was used to obtain it. If the address was obtained |
| from Java socket using Inet6Address class, its format will be |
| <code>x:x:x:x:x:x:x:x</code>. That is, the IP address for localhost |
| will be <code>0:0:0:0:0:0:0:1</code> instead of the more widely used |
| <code>::1</code>. Consult your access logs for the actual value.</p> |
| |
| <p>See also: <a href="#Remote_Host_Filter">Remote Host Filter</a>.</p> |
| </subsection> |
| |
| <subsection name="Filter Class Name"> |
| |
| <p>The filter class name for the Remote Address Filter is |
| <strong><code>org.apache.catalina.filters.RemoteAddrFilter</code> |
| </strong>.</p> |
| |
| </subsection> |
| |
| <subsection name="Initialisation parameters"> |
| |
| <p>The <strong>Remote Address Filter</strong> supports the following |
| initialisation parameters:</p> |
| |
| <attributes> |
| |
| <attribute name="allow" required="false"> |
| <p>A regular expression (using <code>java.util.regex</code>) that the |
| remote client's IP address is compared to. If this attribute |
| is specified, the remote address MUST match for this request to be |
| accepted. If this attribute is not specified, all requests will be |
| accepted UNLESS the remote address matches a <code>deny</code> |
| pattern.</p> |
| </attribute> |
| |
| <attribute name="deny" required="false"> |
| <p>A regular expression (using <code>java.util.regex</code>) that the |
| remote client's IP address is compared to. If this attribute |
| is specified, the remote address MUST NOT match for this request to be |
| accepted. If this attribute is not specified, request acceptance is |
| governed solely by the <code>accept</code> attribute.</p> |
| </attribute> |
| |
| <attribute name="denyStatus" required="false"> |
| <p>HTTP response status code that is used when rejecting denied |
| request. The default value is <code>403</code>. For example, |
| it can be set to the value <code>404</code>.</p> |
| </attribute> |
| |
| </attributes> |
| |
| </subsection> |
| |
| <subsection name="Example"> |
| <p>To allow access only for the clients connecting from localhost:</p> |
| <source><![CDATA[ <filter> |
| <filter-name>Remote Address Filter</filter-name> |
| <filter-class>org.apache.catalina.filters.RemoteAddrFilter</filter-class> |
| <init-param> |
| <param-name>allow</param-name> |
| <param-value>127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1</param-value> |
| </init-param> |
| </filter> |
| <filter-mapping> |
| <filter-name>Remote Address Filter</filter-name> |
| <url-pattern>/*</url-pattern> |
| </filter-mapping>]]></source> |
| </subsection> |
| |
| </section> |
| |
| |
| <section name="Remote Host Filter"> |
| |
| <subsection name="Introduction"> |
| |
| <p>The <strong>Remote Host Filter</strong> allows you to compare the |
| hostname of the client that submitted this request against one or more |
| <em>regular expressions</em>, and either allow the request to continue |
| or refuse to process the request from this client. </p> |
| |
| <p>The syntax for <em>regular expressions</em> is different than that for |
| 'standard' wildcard matching. Tomcat uses the <code>java.util.regex</code> |
| package. Please consult the Java documentation for details of the |
| expressions supported.</p> |
| |
| <p><strong>Note:</strong> This filter processes the value returned by |
| method <code>ServletRequest.getRemoteHost()</code>. To allow the method |
| to return proper host names, you have to enable "DNS lookups" feature on |
| a <strong>Connector</strong>.</p> |
| |
| <p>See also: <a href="#Remote_Address_Filter">Remote Address Filter</a>, |
| <a href="http.html">HTTP Connector</a> configuration.</p> |
| </subsection> |
| |
| <subsection name="Filter Class Name"> |
| |
| <p>The filter class name for the Remote Address Filter is |
| <strong><code>org.apache.catalina.filters.RemoteHostFilter</code> |
| </strong>.</p> |
| |
| </subsection> |
| |
| <subsection name="Initialisation parameters"> |
| |
| <p>The <strong>Remote Host Filter</strong> supports the following |
| initialisation parameters:</p> |
| |
| <attributes> |
| |
| <attribute name="allow" required="false"> |
| <p>A regular expression (using <code>java.util.regex</code>) that the |
| remote client's hostname is compared to. If this attribute |
| is specified, the remote hostname MUST match for this request to be |
| accepted. If this attribute is not specified, all requests will be |
| accepted UNLESS the remote hostname matches a <code>deny</code> |
| pattern.</p> |
| </attribute> |
| |
| <attribute name="deny" required="false"> |
| <p>A regular expression (using <code>java.util.regex</code>) that the |
| remote client's hostname is compared to. If this attribute |
| is specified, the remote hostname MUST NOT match for this request to be |
| accepted. If this attribute is not specified, request acceptance is |
| governed solely by the <code>accept</code> attribute.</p> |
| </attribute> |
| |
| <attribute name="denyStatus" required="false"> |
| <p>HTTP response status code that is used when rejecting denied |
| request. The default value is <code>403</code>. For example, |
| it can be set to the value <code>404</code>.</p> |
| </attribute> |
| |
| </attributes> |
| |
| </subsection> |
| |
| </section> |
| |
| |
| <section name="Remote IP Filter"> |
| |
| <subsection name="Introduction"> |
| |
| <p>Tomcat port of |
| <a href="http://httpd.apache.org/docs/trunk/mod/mod_remoteip.html">mod_remoteip</a>, |
| this filter replaces the apparent client remote IP address and hostname for |
| the request with the IP address list presented by a proxy or a load balancer |
| via a request headers (e.g. "X-Forwarded-For").</p> |
| |
| <p>Another feature of this filter is to replace the apparent scheme |
| (http/https), server port and <code>request.secure</code> with the scheme presented |
| by a proxy or a load balancer via a request header |
| (e.g. "X-Forwarded-Proto").</p> |
| |
| <p>If used in conjunction with Remote Address/Host filters then this filter |
| should be defined first to ensure that the correct client IP address is |
| presented to the Remote Address/Host filters.</p> |
| |
| <p><strong>Note:</strong> By default this filter has no effect on the |
| values that are written into access log. The original values are restored |
| when request processing leaves the filter and that always happens earlier |
| than access logging. To pass the remote address, remote host, server port |
| and protocol values set by this filter to the access log, |
| they are put into request attributes. Publishing these values here |
| is enabled by default, but <code>AccessLogValve</code> should be explicitly |
| configured to use them. See documentation for |
| <code>requestAttributesEnabled</code> attribute of |
| <code>AccessLogValve</code>.</p> |
| |
| <p>The names of request attributes that are set by this filter |
| and can be used by access logging are the following:</p> |
| |
| <ul> |
| <li><code>org.apache.catalina.AccessLog.RemoteAddr</code></li> |
| <li><code>org.apache.catalina.AccessLog.RemoteHost</code></li> |
| <li><code>org.apache.catalina.AccessLog.Protocol</code></li> |
| <li><code>org.apache.catalina.AccessLog.ServerPort</code></li> |
| <li><code>org.apache.tomcat.remoteAddr</code></li> |
| </ul> |
| |
| </subsection> |
| |
| <subsection name="Filter Class Name"> |
| |
| <p>The filter class name for the Remote IP Filter is |
| <strong><code>org.apache.catalina.filters.RemoteIpFilter</code> |
| </strong>.</p> |
| |
| </subsection> |
| |
| <subsection name="Basic configuration to handle 'x-forwarded-for'"> |
| <p> |
| The filter will process the <code>x-forwarded-for</code> http header. |
| </p> |
| <source><![CDATA[ <filter> |
| <filter-name>RemoteIpFilter</filter-name> |
| <filter-class>org.apache.catalina.filters.RemoteIpFilter</filter-class> |
| </filter> |
| |
| <filter-mapping> |
| <filter-name>RemoteIpFilter</filter-name> |
| <url-pattern>/*</url-pattern> |
| <dispatcher>REQUEST</dispatcher> |
| </filter-mapping>]]></source> |
| </subsection> |
| |
| <subsection name="Basic configuration to handle 'x-forwarded-for' and 'x-forwarded-proto'"> |
| |
| <p> |
| The filter will process <code>x-forwarded-for</code> and |
| <code>x-forwarded-proto</code> http headers. Expected value for the |
| <code>x-forwarded-proto</code> header in case of SSL connections is |
| <code>https</code> (case insensitive). </p> |
| <source><![CDATA[ <filter> |
| <filter-name>RemoteIpFilter</filter-name> |
| <filter-class>org.apache.catalina.filters.RemoteIpFilter</filter-class> |
| <init-param> |
| <param-name>protocolHeader</param-name> |
| <param-value>x-forwarded-proto</param-value> |
| </init-param> |
| </filter> |
| |
| <filter-mapping> |
| <filter-name>RemoteIpFilter</filter-name> |
| <url-pattern>/*</url-pattern> |
| <dispatcher>REQUEST</dispatcher> |
| </filter-mapping>]]></source> |
| </subsection> |
| |
| <subsection name="Advanced configuration with internal proxies"> |
| <p>RemoteIpFilter configuration: </p> |
| <source><![CDATA[ <filter> |
| <filter-name>RemoteIpFilter</filter-name> |
| <filter-class>org.apache.catalina.filters.RemoteIpFilter</filter-class> |
| <init-param> |
| <param-name>allowedInternalProxies</param-name> |
| <param-value>192\.168\.0\.10|192\.168\.0\.11</param-value> |
| </init-param> |
| <init-param> |
| <param-name>remoteIpHeader</param-name> |
| <param-value>x-forwarded-for</param-value> |
| </init-param> |
| <init-param> |
| <param-name>remoteIpProxiesHeader</param-name> |
| <param-value>x-forwarded-by</param-value> |
| </init-param> |
| <init-param> |
| <param-name>protocolHeader</param-name> |
| <param-value>x-forwarded-proto</param-value> |
| </init-param> |
| </filter>]]></source> |
| <p>Request values:</p> |
| <table class="defaultTable"> |
| <tr> |
| <th>Property</th> |
| <th>Value Before RemoteIpFilter</th> |
| <th>Value After RemoteIpFilter</th> |
| </tr> |
| <tr> |
| <td> request.remoteAddr </td> |
| <td> 192.168.0.10 </td> |
| <td> 140.211.11.130 </td> |
| </tr> |
| <tr> |
| <td> request.header<code>[</code>'x-forwarded-for'<code>]</code> </td> |
| <td> 140.211.11.130, 192.168.0.10 </td> |
| <td> null </td> |
| </tr> |
| <tr> |
| <td> request.header<code>[</code>'x-forwarded-by'<code>]</code> </td> |
| <td> null </td> |
| <td> null </td> |
| </tr> |
| <tr> |
| <td> request.header<code>[</code>'x-forwarded-proto'<code>]</code> </td> |
| <td> https </td> |
| <td> https </td> |
| </tr> |
| <tr> |
| <td> request.scheme </td> |
| <td> http </td> |
| <td> https </td> |
| </tr> |
| <tr> |
| <td> request.secure </td> |
| <td> false </td> |
| <td> true </td> |
| </tr> |
| <tr> |
| <td> request.serverPort </td> |
| <td> 80 </td> |
| <td> 443 </td> |
| </tr> |
| </table> |
| |
| <p> |
| Note : <code>x-forwarded-by</code> header is <code>null</code> because only |
| internal proxies has been traversed by the request. |
| <code>x-forwarded-for</code> is <code>null</code> because all the proxies are |
| trusted or internal. |
| </p> |
| </subsection> |
| |
| |
| <subsection name="Advanced configuration with trusted proxies"> |
| <p>RemoteIpFilter configuration: </p> |
| <source><![CDATA[ <filter> |
| <filter-name>RemoteIpFilter</filter-name> |
| <filter-class>org.apache.catalina.filters.RemoteIpFilter</filter-class> |
| <init-param> |
| <param-name>allowedInternalProxies</param-name> |
| <param-value>192\.168\.0\.10|192\.168\.0\.11</param-value> |
| </init-param> |
| <init-param> |
| <param-name>remoteIpHeader</param-name> |
| <param-value>x-forwarded-for</param-value> |
| </init-param> |
| <init-param> |
| <param-name>remoteIpProxiesHeader</param-name> |
| <param-value>x-forwarded-by</param-value> |
| </init-param> |
| <init-param> |
| <param-name>trustedProxies</param-name> |
| <param-value>proxy1|proxy2</param-value> |
| </init-param> |
| </filter>]]></source> |
| <p>Request values:</p> |
| <table class="defaultTable"> |
| <tr> |
| <th>Property</th> |
| <th>Value Before RemoteIpFilter</th> |
| <th>Value After RemoteIpFilter</th> |
| </tr> |
| <tr> |
| <td> request.remoteAddr </td> |
| <td> 192.168.0.10 </td> |
| <td> 140.211.11.130 </td> |
| </tr> |
| <tr> |
| <td> request.header<code>[</code>'x-forwarded-for'<code>]</code> </td> |
| <td> 140.211.11.130, proxy1, proxy2 </td> |
| <td> null </td> |
| </tr> |
| <tr> |
| <td> request.header<code>[</code>'x-forwarded-by'<code>]</code> </td> |
| <td> null </td> |
| <td> proxy1, proxy2 </td> |
| </tr> |
| </table> |
| |
| <p> |
| Note : <code>proxy1</code> and <code>proxy2</code> are both trusted proxies that |
| come in <code>x-forwarded-for</code> header, they both are migrated in |
| <code>x-forwarded-by</code> header. <code>x-forwarded-for</code> is <code>null</code> |
| because all the proxies are trusted or internal. |
| </p> |
| </subsection> |
| |
| <subsection name="Advanced configuration with internal and trusted proxies"> |
| <p>RemoteIpFilter configuration: </p> |
| <source><![CDATA[ <filter> |
| <filter-name>RemoteIpFilter</filter-name> |
| <filter-class>org.apache.catalina.filters.RemoteIpFilter</filter-class> |
| <init-param> |
| <param-name>allowedInternalProxies</param-name> |
| <param-value>192\.168\.0\.10|192\.168\.0\.11</param-value> |
| </init-param> |
| <init-param> |
| <param-name>remoteIpHeader</param-name> |
| <param-value>x-forwarded-for</param-value> |
| </init-param> |
| <init-param> |
| <param-name>remoteIpProxiesHeader</param-name> |
| <param-value>x-forwarded-by</param-value> |
| </init-param> |
| <init-param> |
| <param-name>trustedProxies</param-name> |
| <param-value>proxy1|proxy2</param-value> |
| </init-param> |
| </filter>]]></source> |
| <p>Request values:</p> |
| <table class="defaultTable"> |
| <tr> |
| <th>Property</th> |
| <th>Value Before RemoteIpFilter</th> |
| <th>Value After RemoteIpFilter</th> |
| </tr> |
| <tr> |
| <td> request.remoteAddr </td> |
| <td> 192.168.0.10 </td> |
| <td> 140.211.11.130 </td> |
| </tr> |
| <tr> |
| <td> request.header<code>[</code>'x-forwarded-for'<code>]</code> </td> |
| <td> 140.211.11.130, proxy1, proxy2, 192.168.0.10 </td> |
| <td> null </td> |
| </tr> |
| <tr> |
| <td> request.header<code>[</code>'x-forwarded-by'<code>]</code> </td> |
| <td> null </td> |
| <td> proxy1, proxy2 </td> |
| </tr> |
| </table> |
| |
| <p> |
| Note : <code>proxy1</code> and <code>proxy2</code> are both trusted proxies that |
| come in <code>x-forwarded-for</code> header, they both are migrated in |
| <code>x-forwarded-by</code> header. As <code>192.168.0.10</code> is an internal |
| proxy, it does not appear in <code>x-forwarded-by</code>. |
| <code>x-forwarded-for</code> is <code>null</code> because all the proxies are |
| trusted or internal. |
| </p> |
| </subsection> |
| |
| <subsection name="Advanced configuration with an untrusted proxy"> |
| |
| <p>RemoteIpFilter configuration: </p> |
| <source><![CDATA[ <filter> |
| <filter-name>RemoteIpFilter</filter-name> |
| <filter-class>org.apache.catalina.filters.RemoteIpFilter</filter-class> |
| <init-param> |
| <param-name>allowedInternalProxies</param-name> |
| <param-value>192\.168\.0\.10|192\.168\.0\.11</param-value> |
| </init-param> |
| <init-param> |
| <param-name>remoteIpHeader</param-name> |
| <param-value>x-forwarded-for</param-value> |
| </init-param> |
| <init-param> |
| <param-name>remoteIpProxiesHeader</param-name> |
| <param-value>x-forwarded-by</param-value> |
| </init-param> |
| <init-param> |
| <param-name>trustedProxies</param-name> |
| <param-value>proxy1|proxy2</param-value> |
| </init-param> |
| </filter>]]></source> |
| <p>Request values:</p> |
| <table class="defaultTable"> |
| <tr> |
| <th>Property</th> |
| <th>Value Before RemoteIpFilter</th> |
| <th>Value After RemoteIpFilter</th> |
| </tr> |
| <tr> |
| <td> request.remoteAddr </td> |
| <td> 192.168.0.10 </td> |
| <td> untrusted-proxy </td> |
| </tr> |
| <tr> |
| <td> request.header<code>[</code>'x-forwarded-for'<code>]</code> </td> |
| <td> 140.211.11.130, untrusted-proxy, proxy1 </td> |
| <td> 140.211.11.130 </td> |
| </tr> |
| <tr> |
| <td> request.header<code>[</code>'x-forwarded-by'<code>]</code> </td> |
| <td> null </td> |
| <td> proxy1 </td> |
| </tr> |
| </table> |
| |
| <p> |
| Note : <code>x-forwarded-by</code> holds the trusted proxy <code>proxy1</code>. |
| <code>x-forwarded-by</code> holds <code>140.211.11.130</code> because |
| <code>untrusted-proxy</code> is not trusted and thus, we can not trust that |
| <code>untrusted-proxy</code> is the actual remote ip. |
| <code>request.remoteAddr</code> is <code>untrusted-proxy</code> that is an IP |
| verified by <code>proxy1</code>. |
| </p> |
| </subsection> |
| |
| <subsection name="Initialisation parameters"> |
| |
| <p>The <strong>Remote IP Filter</strong> supports the |
| following initialisation parameters:</p> |
| |
| <attributes> |
| |
| <attribute name="remoteIpHeader" required="false"> |
| <p>Name of the HTTP Header read by this valve that holds the list of |
| traversed IP addresses starting from the requesting client. If not |
| specified, the default of <code>x-forwarded-for</code> is used.</p> |
| </attribute> |
| |
| <attribute name="internalProxies" required="false"> |
| <p>Regular expression (using <code>java.util.regex</code>) that a |
| proxy's IP address must match to be considered an internal proxy. |
| Internal proxies that appear in the <strong>remoteIpHeader</strong> will |
| be trusted and will not appear in the <strong>proxiesHeader</strong> |
| value. If not specified the default value of <code> |
| 10\.\d{1,3}\.\d{1,3}\.\d{1,3}|192\.168\.\d{1,3}\.\d{1,3}|169\.254\.\d{1,3}\.\d{1,3}|127\.\d{1,3}\.\d{1,3}\.\d{1,3}|172\.1[6-9]{1}\.\d{1,3}\.\d{1,3}|172\.2[0-9]{1}\.\d{1,3}\.\d{1,3}|172\.3[0-1]{1}\.\d{1,3}\.\d{1,3} |
| </code> will be used.</p> |
| </attribute> |
| |
| <attribute name="proxiesHeader" required="false"> |
| <p>Name of the HTTP header created by this valve to hold the list of |
| proxies that have been processed in the incoming |
| <strong>remoteIpHeader</strong>. If not specified, the default of |
| <code>x-forwarded-by</code> is used.</p> |
| </attribute> |
| |
| <attribute name="requestAttributesEnabled" required="false"> |
| <p>Set to <code>true</code> to set the request attributes used by |
| AccessLog implementations to override the values returned by the |
| request for remote address, remote host, server port and protocol. |
| Request attributes are also used to enable the forwarded remote address |
| to be displayed on the status page of the Manager web application. |
| If not set, the default value of <code>true</code> will be used.</p> |
| </attribute> |
| |
| <attribute name="trustedProxies" required="false"> |
| <p>Regular expression (using <code>java.util.regex</code>) that a |
| proxy's IP address must match to be considered an trusted proxy. |
| Trusted proxies that appear in the <strong>remoteIpHeader</strong> will |
| be trusted and will appear in the <strong>proxiesHeader</strong> value. |
| If not specified, no proxies will be trusted.</p> |
| </attribute> |
| |
| <attribute name="protocolHeader" required="false"> |
| <p>Name of the HTTP Header read by this valve that holds the protocol |
| used by the client to connect to the proxy. If not specified, the |
| default of <code>null</code> is used.</p> |
| </attribute> |
| |
| <attribute name="portHeader" required="false"> |
| <p>Name of the HTTP Header read by this valve that holds the port |
| used by the client to connect to the proxy. If not specified, the |
| default of <code>null</code> is used.</p> |
| </attribute> |
| |
| <attribute name="protocolHeaderHttpsValue" required="false"> |
| <p>Value of the <strong>protocolHeader</strong> to indicate that it is |
| an HTTPS request. If not specified, the default of <code>https</code> is |
| used.</p> |
| </attribute> |
| |
| <attribute name="httpServerPort" required="false"> |
| <p>Value returned by <code>ServletRequest.getServerPort()</code> |
| when the <strong>protocolHeader</strong> indicates <code>http</code> |
| protocol and no <strong>portHeader</strong> is present. If not |
| specified, the default of <code>80</code> is used.</p> |
| </attribute> |
| |
| <attribute name="httpsServerPort" required="false"> |
| <p>Value returned by <code>ServletRequest.getServerPort()</code> |
| when the <strong>protocolHeader</strong> indicates <code>https</code> |
| protocol and no <strong>portHeader</strong> is present. If not |
| specified, the default of <code>443</code> is used.</p> |
| </attribute> |
| |
| <attribute name="changeLocalPort" required="false"> |
| <p>If <code>true</code>, the value returned by |
| <code>ServletRequest.getLocalPort()</code> and |
| <code>ServletRequest.getServerPort()</code> is modified by the this |
| filter. If not specified, the default of <code>false</code> is used.</p> |
| </attribute> |
| |
| </attributes> |
| |
| |
| </subsection> |
| |
| </section> |
| |
| |
| <section name="Request Dumper Filter"> |
| |
| <subsection name="Introduction"> |
| |
| <p>The Request Dumper Filter logs information from the request and response |
| objects and is intended to be used for debugging purposes. When using this |
| Filter, it is recommended that the |
| <code>org.apache.catalina.filter.RequestDumperFilter</code> logger is |
| directed to a dedicated file and that the |
| <code>org.apache.juli.VerbatimFormatter</code> is used.</p> |
| |
| <p><strong>WARNING: Using this filter has side-effects.</strong> The |
| output from this filter includes any parameters included with the request. |
| The parameters will be decoded using the default platform encoding. Any |
| subsequent calls to <code>request.setCharacterEncoding()</code> within |
| the web application will have no effect.</p> |
| |
| </subsection> |
| |
| <subsection name="Filter Class Name"> |
| |
| <p>The filter class name for the Request Dumper Filter is |
| <strong><code>org.apache.catalina.filters.RequestDumperFilter</code> |
| </strong>.</p> |
| |
| </subsection> |
| |
| <subsection name="Initialisation parameters"> |
| |
| <p>The Request Dumper Filter does not support any initialization |
| parameters.</p> |
| |
| </subsection> |
| |
| <subsection name="Sample Configuration"> |
| |
| <p>The following entries in a web application's web.xml would enable the |
| Request Dumper filter for all requests for that web application. If the |
| entries were added to <code>CATALINA_BASE/conf/web.xml</code>, the Request |
| Dumper Filter would be enabled for all web applications.</p> |
| <source><![CDATA[<filter> |
| <filter-name>requestdumper</filter-name> |
| <filter-class> |
| org.apache.catalina.filters.RequestDumperFilter |
| </filter-class> |
| </filter> |
| <filter-mapping> |
| <filter-name>requestdumper</filter-name> |
| <url-pattern>*</url-pattern> |
| </filter-mapping>]]></source> |
| |
| <p>The following entries in CATALINA_BASE/conf/logging.properties would |
| create a separate log file for the Request Dumper Filter output.</p> |
| <source># To this configuration below, 1request-dumper.org.apache.juli.FileHandler |
| # also needs to be added to the handlers property near the top of the file |
| 1request-dumper.org.apache.juli.FileHandler.level = INFO |
| 1request-dumper.org.apache.juli.FileHandler.directory = ${catalina.base}/logs |
| 1request-dumper.org.apache.juli.FileHandler.prefix = request-dumper. |
| 1request-dumper.org.apache.juli.FileHandler.formatter = org.apache.juli.VerbatimFormatter |
| org.apache.catalina.filters.RequestDumperFilter.level = INFO |
| org.apache.catalina.filters.RequestDumperFilter.handlers = \ |
| 1request-dumper.org.apache.juli.FileHandler</source> |
| </subsection> |
| </section> |
| |
| <section name="Session Initializer Filter"> |
| |
| <subsection name="Introduction"> |
| <p>The Session Initializer Filter initializes the <code>javax.servlet.http.HttpSession</code> |
| before the Request is processed. This is required for JSR-356 compliant WebSocket implementations, |
| if the <code>HttpSession</code> is needed during the HandShake phase.</p> |
| |
| <p>The Java API for WebSocket does not mandate that an <code>HttpSession</code> would |
| be initialized upon request, and thus <code>javax.servlet.http.HttpServletRequest</code>'s |
| <code>getSession()</code> returns <code>null</code> if the <code>HttpSession</code> was not |
| initialized in advance.</p> |
| |
| <p>This filter solves that problem by initializing the HttpSession for any <code>HttpServletRequest</code> |
| that matches its <code>url-pattern</code>.</p> |
| </subsection> |
| |
| <subsection name="Filter Class Name"> |
| <p>The filter class name for the Session Initializer Filter is |
| <strong><code>org.apache.catalina.filters.SessionInitializerFilter</code></strong>.</p> |
| </subsection> |
| |
| <subsection name="Initialisation parameters"> |
| <p>The Session Initializer Filter does not support any initialization parameters.</p> |
| </subsection> |
| |
| <subsection name="Sample Configuration"> |
| <p>The following entries in the Web Application Deployment Descriptor, <strong>web.xml</strong>, |
| would enable the Session Initializer Filter for requests that match the given URL pattern |
| (in this example, "/ws/*").</p> |
| |
| <source><![CDATA[<filter> |
| <filter-name>SessionInitializer</filter-name> |
| <filter-class>org.apache.catalina.filters.SessionInitializerFilter</filter-class> |
| </filter> |
| <filter-mapping> |
| <filter-name>SessionInitializer</filter-name> |
| <url-pattern>/ws/*</url-pattern> |
| </filter-mapping>]]></source> |
| </subsection> |
| </section> |
| |
| <section name="Set Character Encoding Filter"> |
| |
| <subsection name="Introduction"> |
| |
| <p>User agents don't always include character encoding information in |
| requests. Depending on the how the request is processed, usually the |
| default encoding of ISO-8859-1 is used. This is not always |
| desirable. This filter provides options for setting that encoding or |
| forcing it to a particular value. Essentially this filter calls |
| <code>ServletRequest.setCharacterEncoding()</code> method.</p> |
| |
| <p>Effectively the value set by this filter is used when parsing parameters |
| in a POST request, if parameter parsing occurs later than this filter. Thus |
| the order of filter mappings is important. Note that the encoding for GET |
| requests is not set here, but on a <b>Connector</b>. See |
| CharacterEncoding page in the FAQ for details.</p> |
| |
| </subsection> |
| |
| <subsection name="Filter Class Name"> |
| |
| <p>The filter class name for the Set Character Encoding Filter is |
| <strong><code>org.apache.catalina.filters.SetCharacterEncodingFilter</code> |
| </strong>.</p> |
| |
| </subsection> |
| |
| <subsection name="Initialisation parameters"> |
| |
| <p>The Set Character Encoding Filter supports the following initialization |
| parameters:</p> |
| |
| <attributes> |
| |
| <attribute name="encoding" required="true"> |
| <p>Name of the character encoding which should be set.</p> |
| </attribute> |
| |
| <attribute name="ignore" required="false"> |
| <p>Determines if any character encoding specified by the user agent is |
| ignored. If this attribute is <code>true</code>, any value provided by |
| the user agent is ignored. If <code>false</code>, the encoding is only |
| set if the user agent did not specify an encoding. The default value |
| is <code>false</code>.</p> |
| </attribute> |
| |
| </attributes> |
| |
| </subsection> |
| |
| </section> |
| |
| |
| <section name="WebDAV Fix Filter"> |
| |
| <subsection name="Introduction"> |
| |
| <p>Microsoft operating systems have two WebDAV clients. One is used with |
| port 80, the other is used for all other ports. The implementation used with |
| port 80 does not adhere to the WebDAV specification and fails when trying to |
| communicate with the Tomcat WebDAV Servlet. This Filter provides a fix for |
| this by forcing the use of the WebDAV implementation that works, even when |
| connecting via port 80.</p> |
| |
| </subsection> |
| |
| <subsection name="Filter Class Name"> |
| |
| <p>The filter class name for the WebDAV Fix Filter is |
| <strong><code>org.apache.catalina.filters.WebdavFixFilter</code> |
| </strong>.</p> |
| |
| </subsection> |
| |
| <subsection name="Initialisation parameters"> |
| |
| <p>The WebDAV Fix Filter does not support any initialization parameters.</p> |
| |
| </subsection> |
| |
| </section> |
| |
| </body> |
| |
| </document> |