容器提供的过滤器
目录
简介
Tomcat 提供了许多过滤器,可以使用 $CATALINA_BASE/conf/web.xml
为所有 Web 应用程序配置这些过滤器,或者可以通过在应用程序的 WEB-INF/web.xml
中配置这些过滤器来为各个 Web 应用程序配置这些过滤器。下面描述了每个过滤器。
此说明使用变量名称 $CATALINA_BASE 来引用大多数相对路径解析所依据的基本目录。如果您未通过设置 CATALINA_BASE 目录为 Tomcat 配置多个实例,则 $CATALINA_BASE 将被设置为 $CATALINA_HOME 的值,即您已将 Tomcat 安装到的目录。
添加默认字符集过滤器
简介
HTTP 规范明确指出,如果未为“文本”媒体类型的媒体子类型指定字符集,则必须使用 ISO-8859-1 字符集。但是,浏览器可能会尝试自动检测字符集。攻击者可能会利用这一点来执行 XSS 攻击。Internet Explorer 和其他浏览器有一个选项可以启用此行为。
此过滤器通过显式设置字符集来防止攻击。除非用户显式覆盖提供的字符集,否则浏览器将遵循显式设置的字符集,从而防止 XSS 攻击。
过滤器类名
添加默认字符集过滤器的过滤器类名为 org.apache.catalina.filters.AddDefaultCharsetFilter
。
初始化参数
添加默认字符集过滤器支持以下初始化参数
属性 | 说明 |
---|---|
编码 |
如果 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://www.apache.org</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)
编码。
此过滤器通过生成一个随机数并将其存储在会话中来防止 CSRF。URL 也使用相同的随机数进行编码。当收到下一个请求时,请求中的随机数将与会话中的随机数进行比较,并且只有当它们相同时,请求才被允许继续。
过滤器类名
CSRF 防护过滤器的过滤器类名为 org.apache.catalina.filters.CsrfPreventionFilter
。
初始化参数
CSRF 防护过滤器支持以下初始化参数
属性 | 说明 |
---|---|
denyStatus |
拒绝拒绝的请求时使用的 HTTP 响应状态代码。默认值为 |
enforce |
启用或禁用强制执行的标志。当禁用强制执行时,CsrfPreventionFilter 将允许所有请求,并将 CSRF 失败记录为 DEBUG 消息。默认值为 true,启用 CSRF 保护的强制执行。 |
entryPoints |
一个逗号分隔的 URL 列表,不会测试是否存在有效随机数。它们用于在离开受保护应用程序后提供返回受保护应用程序的方法。入口点将仅限于 HTTP GET 请求,并且不应触发任何安全敏感操作。 |
nonceCacheSize |
将基于 LRU 缓存的先前颁发的随机数的数量,以支持并行请求、在浏览器中有限地使用刷新和返回以及可能导致提交先前随机数而不是当前随机数的类似行为。如果没有设置,将使用默认值 5。 |
nonceRequestParameterName |
用于随机数的请求参数的名称。如果没有设置,将使用默认值 |
randomClass |
用于生成随机数的类的名称。该类必须是 |
noNonceURLPatterns |
不会向其添加 CSRF 随机数的 URL 模式列表。你可能不想向某些 URL 添加随机数,以避免创建可能破坏资源缓存等的唯一 URL。 支持多种类型的模式
默认值为 |
REST API 的 CSRF 防护过滤器
简介
此过滤器为 REST API 提供基本 CSRF 保护。CSRF 保护仅适用于修改 HTTP 请求(不同于 GET、HEAD、OPTIONS)以保护资源。它基于自定义标头 X-CSRF-Token
,该标头提供有效的随机数。
REST API 的 CSRF 保护机制包含以下步骤
- 客户端请求有效的随机数。这是通过对受保护资源执行非修改“获取”请求来执行的。
- 服务器使用映射到当前用户会话的有效随机数进行响应。
- 客户端在同一用户会话的后续修改请求中提供此随机数。
- 服务器拒绝所有不包含有效随机数的修改请求以保护资源。
基本配置示例
在服务器端
- 所有 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>
在客户端
- 执行非修改“获取”请求以获取有效的随机数。可以通过发送附加标头
X-CSRF-Token: Fetch
来完成此操作 - 缓存返回的会话 ID 和随机数,以便在后续修改请求中将其提供给受保护资源。
- 如果随机数无效或缺失、会话过期或服务器更改了会话 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。
注意:如果存在 X-CSRF-Token
标头,它将优先于请求中具有相同名称的任何参数。请求参数不能用于获取新的随机数,只能使用标头请求新的随机数。
<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 |
可以通过请求参数 |
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
”),ExpiresByType
匹配不带字符集的内容类型,如果HttpServletResponse.getContentType()
包含字符集(例如“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
请求失败过滤器
简介
此过滤器触发请求中的参数解析,如果由于解析错误或请求大小限制(例如 连接器 中的 maxParameterCount
属性)导致在参数解析期间跳过某些参数,则拒绝该请求。此过滤器可用于确保客户端提交的任何参数值都不会丢失。
请注意,参数解析可能会消耗 HTTP 请求的主体,因此如果此过滤器保护的 servlet 使用 request.getInputStream()
或 request.getReader()
调用,则需要小心。通常,通过添加此过滤器破坏 Web 应用程序的风险并不高,因为参数解析在消耗请求主体之前会检查请求的内容类型。
请注意,为了正确解析 POST 请求,必须在此过滤器上方配置 SetCharacterEncodingFilter
过滤器。有关详细信息,请参阅常见问题解答中的字符编码页面。
该请求将被拒绝,并显示 HTTP 状态代码 400(错误的请求)。
过滤器类名
失败请求过滤器的过滤器类名为 org.apache.catalina.filters.FailedRequestFilter
。
初始化参数
失败请求过滤器不支持任何初始化参数。
HTTP 标头安全过滤器
简介
可以向响应中添加许多 HTTP 标头以提高连接的安全性。此过滤器提供了一种添加这些标头的机制。请注意,具有更复杂要求的安全相关标头(如 CORS)作为单独的过滤器实现。
过滤器类名
HTTP 标头安全过滤器的过滤器类名为 org.apache.catalina.filters.HttpHeaderSecurityFilter
。
初始化参数
HTTP 标头安全过滤器支持以下初始化参数
属性 | 说明 |
---|---|
hstsEnabled |
是否在安全请求的响应中设置 HTTP 严格传输安全 (HSTS) 标头 ( |
hstsMaxAgeSeconds |
应在 HSTS 标头中使用的最大生存期值。负值将视为零。如果未指定,将使用默认值 |
hstsIncludeSubDomains |
是否应在 HSTS 标头中包含 includeSubDomains 参数。如果未指定,将使用默认值 |
hstsPreload |
是否应在 HSTS 标头中包含 preload 参数。如果未指定,将使用默认值 |
antiClickJackingEnabled |
是否应在响应中设置防点击劫持标头 ( |
antiClickJackingOption |
应为防点击劫持标头使用什么值?必须为 |
antiClickJackingUri |
如果将 ALLOW-FROM 用于 antiClickJackingOption,应允许什么 URI?如果未指定,将使用空字符串的默认值。 |
blockContentTypeSniffingEnabled |
是否应在每个响应中设置阻止内容类型嗅探的标头 ( |
xssProtectionEnabled |
注意:此设置已弃用,因为所有主流浏览器已移除对 HTTP 标头的支持。此设置已在 Tomcat 11.0.x 及更高版本中移除。 是否应在每个响应中设置启用浏览器的跨站点脚本过滤器保护的标头 ( |
速率限制过滤器
简介
速率限制过滤器可以通过限制在时间窗口(也称为时间段)内从单个 IP 地址允许的请求数量(例如每 60 秒 300 个请求)来帮助减轻拒绝服务 (DoS) 和暴力攻击。
该过滤器通过为每个 IP 地址在时间段中递增计数器来工作,如果计数器超过允许的限制,则来自该 IP 的进一步请求将以“429 请求过多”响应丢弃,直到时间段结束并开始一个新时间段。
该过滤器经过优化,以提高效率和降低开销,因此它会将一些配置的值转换为更有效的值。例如,60 秒时间段的配置将转换为 65.536 秒。这允许使用位移算术进行非常快速的段计算。为了保持对用户意图的真实性,配置的请求数量随后乘以相同的比率,因此每 60 秒 100 个请求的配置具有每 65 秒 109 个请求的实际值。
为不同的 URI 设置不同的限制很常见。例如,登录页面或身份验证脚本通常比应用程序的其余部分获得的请求少得多,因此您可以添加一个过滤器定义,该定义仅允许每 15 秒 5 个请求,并将这些 URI 映射到该定义。
您可以将 enforce
设置为 false
以禁用终止超过允许限制的请求。然后,您的应用程序代码可以检查请求属性 org.apache.catalina.filters.RateLimitFilter.Count
,并根据其拥有的其他信息决定如何处理请求,例如根据角色允许某些用户进行更多请求等。
警告:如果 Tomcat 位于反向代理之后,则必须确保速率限制过滤器看到客户端 IP 地址,因此,例如,如果您正在使用 远程 IP 过滤器,则速率限制过滤器的过滤器映射必须在远程 IP 过滤器的映射之后,以确保在应用速率限制过滤器之前每个请求都已解析其 IP 地址。否则,将导致同一时间段内来自不同 IP 的请求计数,并导致自我施加的 DoS 攻击。
过滤器类名
远程地址过滤器的过滤器类名为 org.apache.catalina.filters.RateLimitFilter
。
初始化参数
速率限制过滤器支持以下初始化参数
属性 | 说明 |
---|---|
bucketDuration |
时间段内的秒数。默认值为 |
bucketRequests |
时间段内允许的请求数。默认值为 |
enforce |
设置为 false 以允许请求通过,即使它们超过每个时间窗口允许的最大值。您的应用程序代码仍可以检查请求属性 org.apache.catalina.filters.RateLimitFilter.Count 以检索在时间窗口内从该 IP 发出的请求数。默认值为 |
statusCode |
当请求被丢弃时返回的状态代码。默认值为 |
statusMessage |
当请求被丢弃时返回的状态消息。默认值为“请求过多”。 |
示例
将网站速率限制设置为每分钟 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。如果使用 Inet6Address 类从 Java 套接字获取地址,其格式将为 x:x:x:x:x:x:x:x
。也就是说,本地主机的 IP 地址将为 0:0:0:0:0:0:0:1
,而不是更广泛使用的 ::1
。有关实际值,请查阅您的访问日志。
另请参阅:远程主机过滤器。
过滤器类名
远程地址过滤器的过滤器类名为 org.apache.catalina.filters.RemoteAddrFilter
。
初始化参数
远程地址过滤器支持以下初始化参数
属性 | 说明 |
---|---|
allow |
远程客户端的 IP 地址与之进行比较的正则表达式(使用 |
拒绝 |
远程客户端的 IP 地址与之进行比较的正则表达式(使用 |
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 |
远程客户端的主机名与之进行比较的正则表达式(使用 |
拒绝 |
远程客户端的主机名与之进行比较的正则表达式(使用 |
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 |
远程客户端 IP 地址与之匹配的 IPv4 或 IPv6 网罩或地址的逗号分隔列表。如果指定此属性,则远程地址必须匹配才能接受此请求。如果未指定此属性,则将接受所有请求,除非远程 IP 与 |
拒绝 |
远程客户端 IP 地址与之匹配的 IPv4 或 IPv6 网罩或地址的逗号分隔列表。如果指定此属性,则远程地址不能匹配才能接受此请求。如果未指定此属性,则请求接受仅受 |
示例
仅允许来自本地主机和本地网络 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 过滤器
简介
Tomcat 端口 mod_remoteip,此过滤器使用代理或负载平衡器通过请求头(例如“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>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>
请求值
属性 | RemoteIpFilter 之前的 Value | RemoteIpFilter 之后的 Value |
---|---|---|
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>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>
请求值
属性 | RemoteIpFilter 之前的 Value | RemoteIpFilter 之后的 Value |
---|---|---|
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>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>
请求值
属性 | RemoteIpFilter 之前的 Value | RemoteIpFilter 之后的 Value |
---|---|---|
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>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>
请求值
属性 | RemoteIpFilter 之前的 Value | RemoteIpFilter 之后的 Value |
---|---|---|
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
是由 proxy1
验证的 IP untrusted-proxy
。
初始化参数
远程 IP 过滤器支持以下初始化参数
属性 | 说明 |
---|---|
enableLookups |
在调用 |
remoteIpHeader |
此阀门读取的 HTTP 标头名称,其中包含从请求客户端开始遍历的 IP 地址列表。如果未指定,则使用默认值 |
internalProxies |
正则表达式(使用 |
proxiesHeader |
此阀门创建的 HTTP 标头名称,用于保存已在传入 remoteIpHeader 中处理的代理列表。如果未指定,则使用默认值 |
requestAttributesEnabled |
设置为 |
trustedProxies |
正则表达式(使用 |
protocolHeader |
此阀门读取的 HTTP 标头名称,其中包含客户端用于连接到代理的协议。如果未指定,则使用默认值 |
hostHeader |
此阀门读取的 HTTP 标头名称,其中包含客户端用于连接到代理的主机。如果未指定,则使用默认值 |
portHeader |
此阀门读取的 HTTP 标头名称,其中包含客户端用于连接到代理的端口。如果未指定,则使用默认值 |
protocolHeaderHttpsValue |
protocolHeader 的值,表示这是一个 HTTPS 请求。如果未指定,则使用默认值 |
httpServerPort |
当 protocolHeader 指示 |
httpsServerPort |
当protocolHeader指示 |
changeLocalName |
如果为 |
changeLocalPort |
如果为 |
请求转储过滤器
简介
请求转储过滤器会记录来自请求和响应对象的信息,旨在用于调试目的。在使用此过滤器时,建议将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
。如果在握手阶段需要HttpSession
,则 JSR-356 兼容的 WebSocket 实现需要此过滤器。
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 中设置。有关详细信息,请参阅常见问题解答中的字符编码页面。
过滤器类名
设置字符编码过滤器的过滤器类名为 org.apache.catalina.filters.SetCharacterEncodingFilter
。
初始化参数
设置字符编码过滤器支持以下初始化参数
属性 | 说明 |
---|---|
编码 |
应设置的字符编码的名称。 |
ignore |
确定是否忽略用户代理指定的任何字符编码。如果此属性为 |
WebDAV 修复过滤器
简介
Microsoft 操作系统有两个 WebDAV 客户端。一个用于端口 80,另一个用于所有其他端口。用于端口 80 的实现不遵守 WebDAV 规范,并且在尝试与 Tomcat WebDAV Servlet 通信时会失败。此过滤器通过强制使用可正常工作的 WebDAV 实现(即使通过端口 80 连接)来提供此问题的修复程序。
过滤器类名
WebDAV 修复过滤器的过滤器类名为 org.apache.catalina.filters.WebdavFixFilter
。
初始化参数
WebDAV 修复过滤器不支持任何初始化参数。