容器提供的过滤器
目录
简介
Tomcat 提供了许多可配置的 过滤器(Filters),既可以通过修改 $CATALINA_BASE/conf/web.xml
配置用于所有 Web 应用程序,也可以通过在应用程序的 WEB-INF/web.xml
中配置用于单个 Web 应用程序。每个过滤器将在下面进行描述。
本描述使用变量名 $CATALINA_BASE 来指代大多数相对路径所解析的基础目录。如果您没有通过设置 CATALINA_BASE 目录来为 Tomcat 配置多个实例,那么 $CATALINA_BASE 将被设置为 $CATALINA_HOME 的值,即您安装 Tomcat 的目录。
添加默认字符集过滤器
简介
HTTP 规范明确规定,如果“text”媒体类型的子类型未指定字符集,则必须使用 ISO-8859-1 字符集。然而,浏览器可能会尝试自动检测字符集。攻击者可以利用这一点来执行 XSS 攻击。Internet Explorer 和其他浏览器都有启用此行为的选项。
此过滤器通过显式设置字符集来防止攻击。除非用户显式覆盖提供的字符集,否则浏览器将遵守显式设置的字符集,从而防止 XSS 攻击。
过滤器类名
添加默认字符集过滤器的过滤器类名为 org.apache.catalina.filters.AddDefaultCharsetFilter
。
初始化参数
添加默认字符集过滤器支持以下初始化参数
属性 | 描述 |
---|---|
encoding |
如果 Servlet 没有显式设置其他字符集,则应设置的字符集名称。此参数有两个特殊值: |
CORS 过滤器
简介
此过滤器是 W3C 的 CORS(跨域资源共享)规范的实现,它是一种启用跨域请求的机制。
该过滤器通过向 HttpServletResponse 对象添加所需的 Access-Control-*
头来工作。该过滤器还防止 HTTP 响应拆分。如果请求无效或不允许,则请求将被拒绝,并返回 HTTP 状态码 403(禁止)。提供了演示此过滤器请求处理过程的流程图。
使用此过滤器所需的最小配置是
<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>
上述配置启用过滤器,但不会放松跨域策略。至少,您需要添加一个 cors.allowed.origins 初始化参数,如下所述,以启用跨域请求。根据您的要求,您可能需要提供额外的配置。
此过滤器的一个实例只能实现一种策略。如果您想对 Web 应用程序内的不同 URL 或 URL 集应用不同的策略(例如,不同的允许来源),则需要为要配置的每个策略配置此过滤器的单独实例。
过滤器类名
CORS 过滤器的过滤器类名为 org.apache.catalina.filters.CorsFilter
。
初始化参数
CORS 过滤器支持以下初始化参数
属性 | 描述 |
---|---|
cors.allowed.origins |
允许访问资源的源列表。可以指定 |
cors.allowed.methods |
通过跨域请求可用于访问资源的 HTTP 方法的逗号分隔列表。这些方法也将作为预检响应中 |
cors.allowed.headers |
进行实际请求时可使用的请求头的逗号分隔列表。这些头也将作为预检响应中 |
cors.exposed.headers |
除简单响应头之外,浏览器允许访问的头的逗号分隔列表。这些头也将作为预检响应中 |
cors.preflight.maxage |
浏览器允许缓存预检请求结果的秒数。这将作为预检响应中 |
cors.support.credentials |
一个标志,指示资源是否支持用户凭据。此标志作为预检响应中 |
cors.request.decorate |
一个标志,控制是否将 CORS 特定属性添加到 HttpServletRequest 对象。默认值: |
这是一个更高级的配置示例,它覆盖了默认值
<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>https://apache.ac.cn</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>
CORS 过滤器和 HttpServletRequest 属性
CORS 过滤器将请求信息添加到 HttpServletRequest 对象中,供下游使用。如果 cors.request.decorate
初始化参数为 true
,则设置以下属性
- cors.isCorsRequest: 标志,用于判断请求是否为 CORS 请求。
- cors.request.origin: 源 URL,即请求发起页面的 URL。
- cors.request.type: CORS 请求类型。可能的值有
SIMPLE
: 未经过预检请求的请求。ACTUAL
: 经过预检请求的请求。PRE_FLIGHT
: 预检请求。NOT_CORS
: 普通的同源请求。INVALID_CORS
: 无效的跨域请求。
- cors.request.headers: 作为
Access-Control-Request-Headers
头发送的请求头,用于预检请求。
CSRF 防护过滤器
简介
此过滤器为 Web 应用程序提供基本的 CSRF 保护。该过滤器假定其映射到 /*
,并且所有返回给客户端的 URL 都通过调用 HttpServletResponse#encodeRedirectURL(String)
或 HttpServletResponse#encodeURL(String)
进行编码。
此过滤器通过生成一个随机数(nonce)并将其存储在会话中来防止 CSRF。URL 也使用相同的随机数进行编码。当接收到下一个请求时,将请求中的随机数与会话中的随机数进行比较,只有当它们相同时,请求才会被允许继续。
过滤器类名
CSRF 防护过滤器的过滤器类名为 org.apache.catalina.filters.CsrfPreventionFilter
。
初始化参数
CSRF 防护过滤器支持以下初始化参数
属性 | 描述 |
---|---|
denyStatus |
拒绝被拒绝请求时使用的 HTTP 响应状态码。默认值为 |
enforce |
一个标志,用于启用或禁用强制执行。当强制执行禁用时,CsrfPreventionFilter 将 允许所有请求 并将 CSRF 失败作为 DEBUG 消息记录。默认值为 true,启用 CSRF 保护的强制执行。 |
entryPoints |
一个逗号分隔的 URL 列表,这些 URL 将不测试是否存在有效的 nonce。它们用于提供一种在导航离开受保护应用程序后返回的方法。入口点将仅限于 HTTP GET 请求,并且不应触发任何安全敏感操作。 |
nonceCacheSize |
先前发出的随机数(nonce)的数量,将以 LRU 方式缓存,以支持并行请求、有限地使用浏览器中的刷新和返回功能以及可能导致提交旧随机数而非当前随机数的类似行为。如果未设置,将使用默认值 5。 |
nonceRequestParameterName |
用于随机数(nonce)的请求参数名称。如果未设置,将使用默认值 |
randomClass |
用于生成随机数的类名。该类必须是 |
noNonceURLPatterns |
一个 URL 模式列表,这些 URL 将不添加 CSRF 随机数。您可能不希望将随机数添加到某些 URL,以避免创建可能破坏资源缓存等的唯一 URL。 支持多种类型的模式
默认值为 |
REST API 的 CSRF 防护过滤器
简介
此过滤器为 REST API 提供基本的 CSRF 保护。CSRF 保护仅适用于修改 HTTP 请求(不同于 GET、HEAD、OPTIONS)以保护资源。它基于一个提供有效随机数(nonce)的自定义头 X-CSRF-Token
。
REST API 的 CSRF 保护机制包括以下步骤
- 客户端请求一个有效的 nonce。这通过对受保护资源进行非修改性的“Fetch”请求来完成。
- 服务器响应一个映射到当前用户会话的有效 nonce。
- 客户端在同一用户会话框架内的后续修改请求中提供此 nonce。
- 服务器拒绝所有不包含有效 nonce 的对受保护资源的修改请求。
基本配置示例
在服务器端
- 所有受 CSRF 保护的 REST API 都应使用身份验证机制进行保护。
- 使用此过滤器保护修改 REST API。
- 提供至少一个非修改操作。
<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>
在客户端
- 发出一个非修改性的“Fetch”请求,以获取一个有效的 nonce。这可以通过发送额外的头
X-CSRF-Token: Fetch
来完成 - 缓存返回的会话 ID 和 nonce,以便在后续修改对受保护资源的请求中提供它们。
- 如果 nonce 无效或缺失、会话过期或会话 ID 被服务器更改,修改请求可能会被拒绝,并返回头
X-CSRF-Token: Required
。
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
...
RestCsrfPreventionFilter 和 HttpServletRequest 参数
当客户端无法在其对 REST API 的调用中插入自定义头时,还可以配置 URL,对于这些 URL,有效的 nonce 将作为请求参数接受。
注意:如果存在 X-CSRF-Token
头,它将优先于请求中任何同名参数。请求参数不能用于获取新 nonce,只能使用头来请求新 nonce。
<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>
过滤器类名
REST API 的 CSRF 防护过滤器的过滤器类名为 org.apache.catalina.filters.RestCsrfPreventionFilter
。
初始化参数
REST API 的 CSRF 防护过滤器支持以下初始化参数
属性 | 描述 |
---|---|
denyStatus |
拒绝被拒绝请求时使用的 HTTP 响应状态码。默认值为 |
pathsAcceptingParams |
一个逗号分隔的 URL 列表,这些 URL 可以通过请求参数 |
randomClass |
用于生成随机数的类名。该类必须是 |
Expires 过滤器
简介
ExpiresFilter 是 Apache mod_expires 的 Java Servlet API 移植。此过滤器控制在服务器响应中设置 Expires
HTTP 头和 Cache-Control
HTTP 头的 max-age
指令。过期日期可以设置为相对于源文件上次修改的时间,或相对于客户端访问的时间。
这些 HTTP 头是对客户端关于文档有效性和持久性的指示。如果已缓存,在通过此时间之前,文档可以从缓存而非源获取。之后,缓存副本被视为“过期”和无效,必须从源获取新副本。
要修改 max-age
以外的 Cache-Control
指令(参见 RFC 2616 第 14.9 节),您可以使用其他 servlet 过滤器或 Apache Httpd mod_headers 模块。
基本配置示例
为图片、CSS 和 JavaScript 添加 'Expires
' 和 'Cache-Control: max-age=
' 头的基本配置。
<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 text/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>
备用语法
ExpiresDefault
和 ExpiresByType
指令也可以用更易读的语法形式定义
<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>
其中 <base>
是以下之一
access
now
(等同于 'access
')modification
plus
关键字是可选的。<num>
应该是一个整数值(可被 Integer.parseInt()
接受),而 <type>
是以下之一
year
,years
(年)month
,months
(月)week
,weeks
(周)day
,days
(天)hour
,hours
(小时)minute
,minutes
(分钟)second
,seconds
(秒)
例如,可以使用以下任何指令,默认使文档在访问后 1 个月过期
<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>
可以通过添加多个 '<num> <type>
' 子句来微调过期时间
<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>
请注意,如果您使用基于修改日期的设置,则 Expires
头将不会添加到非磁盘文件的内容中。这是因为此类内容没有修改时间。
过期头生成资格
如果满足以下条件,响应就有资格被 ExpiresFilter
丰富:
- 未定义过期头(
Expires
头或Cache-Control
头的max-age
指令), - 响应状态码未被
ExpiresExcludedResponseStatusCodes
指令排除, - 响应的
Content-Type
与ExpiresByType
指令中定义的类型之一匹配,或者定义了ExpiresDefault
指令。
注意:如果 Cache-Control
头包含除 max-age
之外的其他指令,它们将与 ExpiresFilter
添加的 max-age
指令连接起来。
过期配置选择
过期配置根据以下算法选择
ExpiresByType
匹配HttpServletResponse.getContentType()
返回的确切内容类型,可能包括字符集(例如 'text/xml;charset=UTF-8
'),- 如果
HttpServletResponse.getContentType()
包含字符集,则ExpiresByType
匹配不带字符集的内容类型(例如 'text/xml;charset=UTF-8
' -> 'text/xml
'), ExpiresByType
匹配HttpServletResponse.getContentType()
的主要类型(例如 '/
' 之前的子字符串)(例如 'text/xml;charset=UTF-8
' -> 'text
'),ExpiresDefault
过滤器类名
Expires 过滤器的过滤器类名为 org.apache.catalina.filters.ExpiresFilter
。
初始化参数
Expires 过滤器支持以下初始化参数
属性 | 描述 |
---|---|
ExpiresExcludedResponseStatusCodes |
此指令定义了 此指令有助于简化 请参见下表中的示例 |
ExpiresByType <content-type> |
此指令定义了为指定类型(例如, 基准时间可以是文件上次修改的时间,也可以是客户端访问文档的时间。使用哪个由 效果上的差异是微妙的。如果使用
注意:当内容类型包含字符集(例如 请参见下表中的示例 它仅针对指定的 MIME 类型覆盖 您还可以使用本文档前面描述的备用语法指定过期时间计算。 |
ExpiresDefault |
此指令为受影响领域中的所有文档设置计算过期时间的默认算法。它可以由 |
示例:排除响应状态码 302、500 和 503
<init-param>
<param-name>ExpiresExcludedResponseStatusCodes</param-name>
<param-value>302, 500, 503</param-value>
</init-param>
ExpiresByType 初始化参数示例
<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>
故障排除
要排除故障,请在 org.apache.catalina.filters.ExpiresFilter
上启用日志记录。
logging.properties 摘录
org.apache.catalina.filters.ExpiresFilter.level = FINE
初始化日志消息示例
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]]}]
下面是 ExpiresFilter
添加过期日期的每次请求日志消息示例。消息在一行上,为了提高可读性在此处进行了换行。
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
ExpiresFilter
未添加过期日期的每次请求日志消息示例
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
HTTP 头安全过滤器
简介
有许多 HTTP 头可以添加到响应中以提高连接的安全性。此过滤器提供了一种添加这些头的机制。请注意,具有更复杂要求的安全相关头(如 CORS)是作为单独的过滤器实现的。
过滤器类名
HTTP 头安全过滤器的过滤器类名为 org.apache.catalina.filters.HttpHeaderSecurityFilter
。
初始化参数
HTTP 头安全过滤器支持以下初始化参数
属性 | 描述 |
---|---|
hstsEnabled |
是否在安全请求的响应中设置 HTTP 严格传输安全 (HSTS) 头( |
hstsMaxAgeSeconds |
HSTS 头中应使用的最大年龄值。负值将被视为零。如果未指定,将使用默认值 |
hstsIncludeSubDomains |
HSTS 头中是否应包含 includeSubDomains 参数。如果未指定,将使用默认值 |
hstsPreload |
HSTS 头中是否应包含 preload 参数。如果未指定,将使用默认值 |
antiClickJackingEnabled |
是否在响应中设置防点击劫持头( |
antiClickJackingOption |
防点击劫持头应使用什么值?必须是 |
antiClickJackingUri |
如果 antiClickJackingOption 使用 ALLOW-FROM,则应允许哪个 URI?如果未指定,将使用空字符串的默认值。 |
blockContentTypeSniffingEnabled |
是否在每个响应中设置阻止内容类型嗅探的头( |
速率限制过滤器
简介
速率限制过滤器可以帮助缓解拒绝服务 (DoS) 和暴力攻击,方法是限制在一段时间窗口(也称为时间桶)内允许来自单个 IP 地址的请求数量,例如每 60 秒 300 个请求。
此过滤器的工作原理是,为每个 IP 地址在时间桶中增加一个计数器,如果计数器超过允许的限制,则来自该 IP 的后续请求将被丢弃并返回“429 Too many requests”响应,直到桶时间结束并开始一个新的桶。
RateLimiter 的实现可以通过 rateLimitClassName
初始化参数设置。默认实现 org.apache.catalina.util.FastRateLimiter
针对效率和低开销进行了优化,因此它会将一些配置值转换为更高效的值。例如,60 秒时间桶的配置会转换为 65.536 秒。这允许使用位移算术进行非常快速的桶计算。为了保持用户意图,配置的请求数量会乘以相同的比例,因此每 60 秒 100 个请求的配置,实际值为每 65 秒 109 个请求。另一种实现 org.apache.catalina.util.ExactRateLimiter
旨在提供效率较低但更精确的控制,其有效持续时间(秒)和允许的请求数量与配置值一致。您可以指定不同的类,只要它实现 org.apache.catalina.util.RateLimiter
接口即可。
通常为不同的 URI 设置不同的限制。例如,登录页面或身份验证脚本通常预计会比应用程序的其他部分获得少得多的请求,因此您可以添加一个过滤器定义,该定义将允许每 15 秒仅 5 个请求,并将这些 URI 映射到它。
您可以将 enforce
设置为 false
以禁用终止超出允许限制的请求。然后,您的应用程序代码可以检查请求属性 org.apache.catalina.filters.RateLimitFilter.Count
并根据其拥有的其他信息决定如何处理请求,例如根据角色允许某些用户进行更多请求等。
exposeHeaders
根据 HTTP 的 RateLimit 头字段(草案)启用通过 HTTP 响应头输出速率限制器配置和状态。
警告:如果 Tomcat 位于反向代理之后,则必须确保速率限制过滤器看到客户端 IP 地址,因此,例如,如果您正在使用 远程 IP 过滤器,则速率限制过滤器的过滤器映射必须位于远程 IP 过滤器映射之后,以确保每个请求在应用速率限制过滤器之前解析其 IP 地址。否则,来自不同 IP 的请求将被计入同一个桶中,并导致自发性 DoS 攻击。
过滤器类名
远程地址过滤器的过滤器类名为 org.apache.catalina.filters.RateLimitFilter
。
初始化参数
速率限制过滤器支持以下初始化参数
属性 | 描述 |
---|---|
bucketDuration |
时间桶的秒数。默认值为 |
bucketRequests |
时间桶中允许的请求数量。默认值为 |
enforce |
设置为 false 以允许请求通过,即使它们超出每个时间窗口的最大允许值。您的应用程序代码仍然可以检查请求属性 org.apache.catalina.filters.RateLimitFilter.Count 以检索该 IP 在时间窗口内发出的请求数量。默认值为 |
exposeHeaders |
设置为 true 以根据 HTTP 的 RateLimit 头字段(草案)通过 HTTP 响应头公开速率限制器的配置和状态。默认值为 |
rateLimitClassName |
RateLimiter 接口实现类的完整类名。默认值为“org.apache.catalina.util.FastRateLimiter”,该实现针对效率进行了优化。如果您需要精确的速率限制并且可以接受效率上的轻微下降,则可以使用“org.apache.catalina.util.ExactRateLimiter”代替。 |
statusCode |
请求被丢弃时返回的状态码。默认值为 |
statusMessage |
请求被丢弃时返回的状态消息。默认值为“Too many requests”。 |
示例
将站点速率限制设置为每分钟 300 个请求(默认值)
<filter>
<filter-name>RateLimitFilter Global</filter-name>
<filter-class>org.apache.catalina.filters.RateLimitFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>RateLimitFilter Global</filter-name>
<url-pattern>*</url-pattern>
</filter-mapping>
将 /auth/* 脚本的速率限制设置为每分钟 20 个请求
<filter>
<filter-name>RateLimitFilter Login</filter-name>
<filter-class>org.apache.catalina.filters.RateLimitFilter</filter-class>
<init-param>
<param-name>bucketRequests</param-name>
<param-value>20</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>RateLimitFilter Login</filter-name>
<url-pattern>/auth/*</url-pattern>
</filter-mapping>
远程地址过滤器
简介
远程地址过滤器允许您将提交此请求的客户端的 IP 地址与一个或多个正则表达式进行比较,并允许请求继续或拒绝处理来自此客户端的请求。
正则表达式的语法与“标准”通配符匹配不同。Tomcat 使用 java.util.regex
包。请查阅 Java 文档以了解支持的表达式的详细信息。
注意:将此过滤器与 IPv6 地址一起使用时存在一个注意事项。此阀门处理的 IP 地址的格式取决于用于获取它的 API。如果地址是从 Java 套接字使用 Inet6Address 类获取的,其格式将是 x:x:x:x:x:x:x:x
。也就是说,localhost 的 IP 地址将是 0:0:0:0:0:0:0:1
,而不是更广泛使用的 ::1
。请查阅您的访问日志以获取实际值。
另请参阅:远程主机过滤器。
过滤器类名
远程地址过滤器的过滤器类名为 org.apache.catalina.filters.RemoteAddrFilter
。
初始化参数
远程地址过滤器支持以下初始化参数
属性 | 描述 |
---|---|
allow |
一个正则表达式(使用 |
deny |
一个正则表达式(使用 |
denyStatus |
拒绝被拒绝请求时使用的 HTTP 响应状态码。默认值为 |
示例
只允许来自本地主机的客户端访问
<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>
远程主机过滤器
简介
过滤器类名
远程地址过滤器的过滤器类名为 org.apache.catalina.filters.RemoteHostFilter
。
初始化参数
远程主机过滤器支持以下初始化参数
属性 | 描述 |
---|---|
allow |
一个正则表达式(使用 |
deny |
一个正则表达式(使用 |
denyStatus |
拒绝被拒绝请求时使用的 HTTP 响应状态码。默认值为 |
远程 CIDR 过滤器
简介
远程 CIDR 过滤器允许您将提交此请求的客户端的 IP 地址与一个或多个遵循 CIDR 表示法的网络掩码进行比较,并允许请求继续或拒绝处理来自此客户端的请求。IPv4 和 IPv6 都完全支持。
此过滤器模仿 Apache httpd 的 Order
、Allow from
和 Deny from
指令,但存在以下限制
Order
将始终是allow, deny
;- 不支持网络掩码的点分四段表示法(即,您不能写
192.168.1.0/255.255.255.0
,您必须写192.168.1.0/24
; - 不支持快捷方式,例如
10.10.
,它等同于10.10.0.0/16
; - 正如过滤器名称所示,这是一个仅限 CIDR 的过滤器,因此也不支持诸如
.mydomain.com
之类的子域表示法。
此过滤器的其他一些功能包括
- 如果您省略 CIDR 前缀,此过滤器将变为单个 IP 过滤器;
- 与远程主机过滤器不同,它可以处理压缩形式的 IPv6 地址(
::1
、fe80::/71
等)。
过滤器类名
远程地址过滤器的过滤器类名为 org.apache.catalina.filters.RemoteCIDRFilter
。
初始化参数
远程 CIDR 过滤器支持以下初始化参数
属性 | 描述 |
---|---|
allow |
一个逗号分隔的 IPv4 或 IPv6 网络掩码或地址列表,用于与远程客户端的 IP 地址进行匹配。如果指定此属性,远程地址必须匹配才能接受此请求。如果未指定此属性,则将接受所有请求,除非远程 IP 与 |
deny |
一个逗号分隔的 IPv4 或 IPv6 网络掩码或地址列表,用于与远程客户端的 IP 地址进行匹配。如果指定此属性,远程地址不得匹配才能接受此请求。如果未指定此属性,则请求的接受仅受 |
示例
只允许来自 localhost 和本地网络 192.68.0.* 的客户端访问
<filter>
<filter-name>Remote CIDR Filter</filter-name>
<filter-class>org.apache.catalina.filters.RemoteCIDRFilter</filter-class>
<init-param>
<param-name>allow</param-name>
<param-value>127.0.0.1, ::1, 192.68.0.0/24</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>Remote CIDR Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
远程 IP 过滤器
简介
mod_remoteip 的 Tomcat 端口,此过滤器用代理或负载均衡器通过请求头(例如“X-Forwarded-For”)提供的 IP 地址列表替换请求的显式客户端远程 IP 地址和主机名。
此过滤器的另一个功能是使用代理或负载均衡器通过请求头(例如“X-Forwarded-Proto”)提供的方案替换显式方案(http/https)、服务器端口和 request.secure
。
如果与远程地址/主机过滤器结合使用,则此过滤器应首先定义,以确保将正确的客户端 IP 地址呈现给远程地址/主机过滤器。
注意:默认情况下,此过滤器对写入访问日志的值没有影响。当请求处理离开过滤器时(总是早于访问日志记录发生),原始值会恢复。要将此过滤器设置的远程地址、远程主机、服务器端口和协议值传递给访问日志,它们会放入请求属性中。默认情况下,这些值的发布是启用的,但 AccessLogValve
应明确配置为使用它们。请参阅 AccessLogValve
的 requestAttributesEnabled
属性的文档。
此过滤器设置并可用于访问日志记录的请求属性名称如下
org.apache.catalina.AccessLog.RemoteAddr
org.apache.catalina.AccessLog.RemoteHost
org.apache.catalina.AccessLog.Protocol
org.apache.catalina.AccessLog.ServerPort
org.apache.tomcat.remoteAddr
过滤器类名
远程 IP 过滤器的过滤器类名为 org.apache.catalina.filters.RemoteIpFilter
。
处理 'x-forwarded-for' 的基本配置
此过滤器将处理 x-forwarded-for
http 头。
<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>
处理 'x-forwarded-for' 和 'x-forwarded-proto' 的基本配置
此过滤器将处理 x-forwarded-for
和 x-forwarded-proto
http 头。SSL 连接中 x-forwarded-proto
头的预期值为 https
(不区分大小写)。
<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>
内部代理的高级配置
RemoteIpFilter 配置
<filter>
<filter-name>RemoteIpFilter</filter-name>
<filter-class>org.apache.catalina.filters.RemoteIpFilter</filter-class>
<init-param>
<param-name>internalProxies</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>
<filter-mapping>
<filter-name>RemoteIpFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
请求值
属性 | RemoteIpFilter 之前的值 | RemoteIpFilter 之后的值 |
---|---|---|
request.remoteAddr | 192.168.0.10 | 140.211.11.130 |
request.header[ 'x-forwarded-for'] |
140.211.11.130, 192.168.0.10 | null |
request.header[ 'x-forwarded-by'] |
null | null |
request.header[ 'x-forwarded-proto'] |
https | https |
request.scheme | http | https |
request.secure | false | true |
request.serverPort | 80 | 443 |
注意:x-forwarded-by
头为 null
,因为请求只经过了内部代理。x-forwarded-for
为 null
,因为所有代理都是受信任或内部的。
受信任代理的高级配置
RemoteIpFilter 配置
<filter>
<filter-name>RemoteIpFilter</filter-name>
<filter-class>org.apache.catalina.filters.RemoteIpFilter</filter-class>
<init-param>
<param-name>internalProxies</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>
<filter-mapping>
<filter-name>RemoteIpFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
请求值
属性 | RemoteIpFilter 之前的值 | RemoteIpFilter 之后的值 |
---|---|---|
request.remoteAddr | 192.168.0.10 | 140.211.11.130 |
request.header[ 'x-forwarded-for'] |
140.211.11.130, proxy1, proxy2 | null |
request.header[ 'x-forwarded-by'] |
null | proxy1, proxy2 |
注意:proxy1
和 proxy2
都是 x-forwarded-for
头中的受信任代理,它们都已迁移到 x-forwarded-by
头中。x-forwarded-for
为 null
,因为所有代理都是受信任或内部的。
内部和受信任代理的高级配置
RemoteIpFilter 配置
<filter>
<filter-name>RemoteIpFilter</filter-name>
<filter-class>org.apache.catalina.filters.RemoteIpFilter</filter-class>
<init-param>
<param-name>internalProxies</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>
<filter-mapping>
<filter-name>RemoteIpFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
请求值
属性 | RemoteIpFilter 之前的值 | RemoteIpFilter 之后的值 |
---|---|---|
request.remoteAddr | 192.168.0.10 | 140.211.11.130 |
request.header[ 'x-forwarded-for'] |
140.211.11.130, proxy1, proxy2, 192.168.0.10 | null |
request.header[ 'x-forwarded-by'] |
null | proxy1, proxy2 |
注意:proxy1
和 proxy2
都是 x-forwarded-for
头中的受信任代理,它们都已迁移到 x-forwarded-by
头中。由于 192.168.0.10
是内部代理,它不会出现在 x-forwarded-by
中。x-forwarded-for
为 null
,因为所有代理都是受信任或内部的。
不受信任代理的高级配置
RemoteIpFilter 配置
<filter>
<filter-name>RemoteIpFilter</filter-name>
<filter-class>org.apache.catalina.filters.RemoteIpFilter</filter-class>
<init-param>
<param-name>internalProxies</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>
<filter-mapping>
<filter-name>RemoteIpFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
请求值
属性 | RemoteIpFilter 之前的值 | RemoteIpFilter 之后的值 |
---|---|---|
request.remoteAddr | 192.168.0.10 | untrusted-proxy |
request.header[ 'x-forwarded-for'] |
140.211.11.130, untrusted-proxy, proxy1 | 140.211.11.130 |
request.header[ 'x-forwarded-by'] |
null | proxy1 |
注意:x-forwarded-by
包含受信任代理 proxy1
。x-forwarded-by
包含 140.211.11.130
,因为 untrusted-proxy
不受信任,因此我们无法相信 untrusted-proxy
是实际的远程 IP。request.remoteAddr
是 untrusted-proxy
,这是一个由 proxy1
验证的 IP。
初始化参数
远程 IP 过滤器支持以下初始化参数
属性 | 描述 |
---|---|
enableLookups |
是否执行 DNS 查找以在调用 |
remoteIpHeader |
此阀门读取的 HTTP 头名称,其中包含从请求客户端开始遍历的 IP 地址列表。如果未指定,默认使用 |
internalProxies |
一个正则表达式(使用 |
proxiesHeader |
此阀门创建的 HTTP 头名称,用于保存传入 remoteIpHeader 中已处理的代理列表。如果未指定,默认使用 |
requestAttributesEnabled |
设置为 |
trustedProxies |
一个正则表达式(使用 |
protocolHeader |
此阀门读取的 HTTP 头名称,其中包含客户端用于连接代理的协议。如果未指定,默认使用 |
hostHeader |
此阀门读取的 HTTP 头名称,其中包含客户端用于连接代理的主机。如果未指定,默认使用 |
portHeader |
此阀门读取的 HTTP 头名称,其中包含客户端用于连接代理的端口。如果未指定,默认使用 |
protocolHeaderHttpsValue |
protocolHeader 的值,指示它是 HTTPS 请求。如果未指定,默认使用 |
httpServerPort |
当 protocolHeader 指示 |
httpsServerPort |
当 protocolHeader 指示 |
changeLocalName |
如果为 |
changeLocalPort |
如果为 |
请求转储器过滤器
简介
请求转储器过滤器(Request Dumper Filter)记录来自请求和响应对象的信息,旨在用于调试目的。使用此过滤器时,建议将 org.apache.catalina.filter.RequestDumperFilter
日志器定向到专用文件,并使用 org.apache.juli.VerbatimFormatter
。
警告:使用此过滤器会产生副作用。此过滤器的输出包括请求中包含的任何参数。参数将使用默认平台编码进行解码。之后在 Web 应用程序中对 request.setCharacterEncoding()
的任何调用将无效。
过滤器类名
请求转储器过滤器的过滤器类名为 org.apache.catalina.filters.RequestDumperFilter
。
初始化参数
请求转储器过滤器不支持任何初始化参数。
示例配置
Web 应用程序的 web.xml 中的以下条目将为该 Web 应用程序的所有请求启用请求转储器过滤器。如果这些条目添加到 CATALINA_BASE/conf/web.xml
,则请求转储器过滤器将为所有 Web 应用程序启用。
<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>
CATALINA_BASE/conf/logging.properties 中的以下条目将为请求转储器过滤器输出创建单独的日志文件。
# 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.encoding = UTF-8
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
会话初始化器过滤器
简介
会话初始化器过滤器在处理请求之前初始化 jakarta.servlet.http.HttpSession
。JSR-356 兼容的 WebSocket 实现需要这样做,如果握手阶段需要 HttpSession
。
WebSocket 的 Java API 不要求在请求时初始化 HttpSession
,因此如果 HttpSession
未提前初始化,jakarta.servlet.http.HttpServletRequest
的 getSession()
将返回 null
。
此过滤器通过为任何匹配其 url-pattern
的 HttpServletRequest
初始化 HttpSession 来解决此问题。
过滤器类名
会话初始化器过滤器的过滤器类名为 org.apache.catalina.filters.SessionInitializerFilter
。
初始化参数
会话初始化器过滤器不支持任何初始化参数。
示例配置
Web 应用程序部署描述符 web.xml 中的以下条目将为匹配给定 URL 模式(本例中为“/ws/*”)的请求启用会话初始化器过滤器。
<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>
设置字符编码过滤器
简介
用户代理并不总是将字符编码信息包含在请求中。根据请求的处理方式,通常使用 ISO-8859-1 的默认编码。这并不总是理想的。此过滤器提供了设置该编码或强制将其设置为特定值的选项。本质上,此过滤器调用 ServletRequest.setCharacterEncoding()
方法。
如果参数解析晚于此过滤器发生,则此过滤器设置的值将用于解析 POST 请求中的参数。因此,过滤器映射的顺序很重要。请注意,GET 请求的编码不在此处设置,而是在 Connector 上设置。有关详细信息,请参阅 FAQ 中的 CharacterEncoding 页面。
过滤器类名
设置字符编码过滤器的过滤器类名为 org.apache.catalina.filters.SetCharacterEncodingFilter
。
初始化参数
设置字符编码过滤器支持以下初始化参数
属性 | 描述 |
---|---|
encoding |
应设置的字符编码名称。 |
ignore |
确定是否忽略用户代理指定的任何字符编码。如果此属性为 |