Tomcat常用的过滤器
前言
之前我很肤浅的以为为了实现某种请求过滤功能(比如图片转换、文件上传、安全认证等),都需要自己去实现javax.servlet.Filter。之后在web.xml中配置即可。
但事实上,Tomcat已经提供了部分相关的过滤器(本文只介绍常用的7个过滤器),只需要简单配置就可以使用。最近通过系统学习Tomcat架构之后,结合部分源码记录总结最常用的几种过滤器。
参考资料《Tomcat架构解析》(有需要PFD电子书的朋友可以评论或者私信),Tomcat官方Filter配置(Tomcat 8为例)
一、跨域过滤器CorsFilter
org.apcache.catalina.filters.CorsFilter是跨域资源共享规范的一个实现,常常用于前后端分离,静态资源与后端分离等情况。它主要在HttpServletResponse中增加Access-Control-*头,同时保护HTTP响应避免拆分,如果请求无效或者禁止访问,则返回403响应码。
配置示例
<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>
参数说明
1、cors.allowed.origins
允许访问的跨域资源列表,"*"表示允许访问来自任何域的资源,多个域用逗号分隔,默认为"*"
2、cors.allowed.methods
可以用于访问资源的HTTP方法列表,","分隔,用于跨域请求。这些方法将出现在Prefligh(预检请求)响应头Access-Control-Allow-Methods的一部分,t默认为"GET, POST, HEAD, OPTIONS"
3、cors.allowed.headers
构造请求时可以使用的请求头,以","分隔,这些方法将出现在Prefligh(预检请求)响应头Access-Control-Allow-Headers的一部分,默认为Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers
4、cors.exposed.headers
浏览器允许访问的头部信息列表,","分隔。这些方法将出现在Prefligh(预检请求)响应头Access-Control-Allow-Headers的一部分,默认为空。
5、cors.preflight.maxage
浏览器允许缓存的Preflght请求结果的时间,单位为秒。如果为负数,则表示CorsFilter不会添加头到Preflight响应,这些方法将出现在Prefligh(预检请求)响应头Access-Control-Max-Age的一部分,默认为1800.
6、cors.support.credentials
表示资源是否支持用户证书,这些方法将出现在Prefligh(预检请求)响应头Access-Control-Allow-Credentials的一部分,默认为true
7、cors.request.decorate
Cors规范属性是否已经添加到HttpServletRequest,默认为true。CorsFiter会为HttpServletRequest添加请求相关信息,cors.request.decorate配置为true,那么以下属性将会被添加
1)cors.isCorsRequest: 用于请求是否为Cors请求。
2)cors.request.origin: 源URL,请求源自的页面URL。
3)cors.request.type: Cors的请求类型,如下:
SIMPLE
: 非Preflight请求为先导的请求。
ACTUAL
: 以Preflight请求为先导的请求。
PRE_FLIGHT
: Preflight请求
NOT_CORS
: 正常同域请求
I
NVALID_CORS
: 无效的域请求
4)cors.request.headers: 作为Preflight请求Access-Control-Request-Header头发送的请求头信息。
二、CSRF保护过滤器CsrfPreventionFilter
org.apcache.catalina.filters.CsrfPreventionFilter为Web应用提供了基本的CSRF保护。返回的客户端的所有链接均通过HttpServletResponse.encodeRedirectURL(String)与HttpServletResponse.encodeURL(String)进行编码,该过滤器生成一个随机数并存储到会话session中进行对比,URL使用该随机数进行编码。当接收到下一个请求时,请求中随机数与会话中的进行对比,只有两者相同时,请求才会被允许。
配置示例
<filter>
<filter-name>CsrfPreventionFilter</filter-name>
<filter-class>org.apache.catalina.filters.CsrfPreventionFilter</filter-class>
<init-param>
<param-name>denyStatus</param-name>
<param-value>403</param-value>
</init-param>
<init-param>
<param-name>entryPoints</param-name>
<param-value>/html,/html/list</param-value>
</init-param>
<init-param>
<param-name>nonceCacheSize</param-name>
<param-value>5</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CsrfPreventionFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
参数说明
1、denyStatus:HTTP响应吗,用于驳回拒绝请求,默认为403
2、entryPoints:以","为分隔的URL列表,这些列表将不会进行随机数检测(主要用于通过导航离开受保护应用,之后再返回)
if ("GET".equals(req.getMethod()) && this.entryPoints.contains(this.getRequestedPath(req))) {
skipNonceCheck = true;
}
3、nonceCacheSize:随机数缓存大小。先前发布的随机数被缓存到一个LRU缓存中以支持并发请求,有限的用于浏览器刷新等行为(可能导致随机数不是当前的),默认为5
private int nonceCacheSize = 5;
....
if (nonceCache == null) {
nonceCache = new CsrfPreventionFilter.LruCache(this.nonceCacheSize);
if (session == null) {
session = req.getSession(true);
} session.setAttribute("org.apache.catalina.filters.CSRF_NONCE", nonceCache);
}
4、randomClass:用于生成随机数的类,必须是java.util.Random实例,如不设置默认为java.security.SecureRandom
三、防止参数丢失过滤器FailedRequestFilter
org.apcache.catalina.filters.FailedRequestFilter用于触发请求的参数解析,当参数解析失败时,将会拒绝请求,该Filter用于确保客户端提交的参数信息不发生丢失。该过滤器的原理是:先调用ServletRequest.getParameter(首次调用会触发Tomcat服务器的请求参数解析,如果参数解析失败,将结果放到请求属性org.apache.catalina.parameter_parse_failed中),之后判断属性org.apache.catalina.parameter_parse_failed的值,如果不为空则直接返回400。
为了能正确解析参数,需要该Filter之前设置字符集编码过滤器SetCharacterEncodingFilter。此外,该过滤器是不支持r初始化参数的
// 判断是否为有效的请求:org.apache.catalina.parameter_parse_failed为null
private boolean isGoodRequest(ServletRequest request) {
request.getParameter("none");
return request.getAttribute("org.apache.catalina.parameter_parse_failed") == null;
}
四、获取客户端IP过滤器RemoteAddrFilter
org.apcache.catalina.filters.RemoteAddrFiler允许比较提交的客户端IP地址(通过ServletRequest.getRemoteAddr获取)是否符合指定正则表达式。
配置示例
<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>
参数说明
1、allow:指定允许访问的客户端IP地址
2、deny:拒绝访问的客户端地址
3、denyStatus:拒绝请求时返回的HTTP响应吗。
五、获取客户端Host过滤器RemoteHostFilter
org.apcache.catalina.filters.RemoteHostFiler允许比较提交请求的客户端主机名是否符合指定的正则表达式,以确定是否允许继续处理请求。参数同RemoteAddrFilter
六、获取原始客户端IP过滤器RemoteIpFilter
当客户端通过HTTP代理或者负载均衡访问服务器时,对于服务器来说,请求直接源自前置的代理服务器,此时获取到的远程IP实际为代理服务器的IP地址。
这时候如何获得原始的客户端的IP地址呢?
HTTP协议通过X-Forwarded-For头信息记录了资客户端到应用服务器前置代理的IP地址,RemoteIpFilter通过解析该请求头,将请求中的IP地址与主机名替换为客户端真实的IP地址和主机信息,此外还可以通过X-Forwardred-Proto请求头替换当前的协议名称http/https、服务器端口及request.secure。
X-Forwarded-For的格式如下:
X-Forwarded-For: client, proxy1, proxy2
最左侧client为最原始的客户端IP,如上示例中客户端经过了proxy1、proxy2、proxy3三级代理(最后一层proxy3不显示,通过ServletRquest.getRemoteAddr获取)。在负载均衡的情况下,RemoteAddrFilter和RemoteHostFilter需要与该过滤器配合使用,否则无法正确限制访问客户端。
通常我们获取X-Forwarded-For使用如下Java代码:
public static String getIp(HttpServletRequest request) {
String requestAddr = request.getHeader("x-forwarded-for");
if (requestAddr == null || requestAddr.length() == 0 || "unknown".equalsIgnoreCase(requestAddr)) {
requestAddr = request.getHeader("Proxy-Client-IP");
} if (requestAddr == null || requestAddr.length() == 0 || "unknown".equalsIgnoreCase(requestAddr)) {
requestAddr = request.getHeader("WL-Proxy-Client-IP");
} if (requestAddr == null || requestAddr.length() == 0 || "unknown".equalsIgnoreCase(requestAddr)) {
requestAddr = request.getRemoteAddr();
} return requestAddr;
}
配置示例
1)基本处理X-Forwarded-For头的配置
<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>
2)处理X-Forwarded-For与x-forwarded-proto头部的配置
<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>
3)使用内部代理的高级配置
<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>
4)使用可信任代理高级配置
<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>
七、字符集编码过滤器SetCharacterEncodingFilter
提供了一种设置字符集编码的方式,通常情况下默认ISO-8859-1编码,但实际生产环境推荐使用UTF-8编码,而请求中的编码可以在未指定编码时使用,也可以强制覆盖。
配置示例
<filter>
<filter-name>SetCharacterEncodingFilter</filter-name>
<filter-class>org.apache.catalina.filters.SetCharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>ignore</param-name>
<param-value>false</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>SetCharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
参数说明
1、encoding:指定的字符集编码
2、ignore:表示是否忽略客户端请求设置的字符集编码,如果为true那么都会将请求字符集编码覆盖,如果为false,请求没有指定字符集编码时设置。默认为false
Tomcat常用的过滤器的更多相关文章
- tomcat常用配置详解和优化方法
tomcat常用配置详解和优化方法 参考: http://blog.csdn.net/zj52hm/article/details/51980194 http://blog.csdn.net/wuli ...
- Eclipse下Tomcat常用设置
Eclipse下Tomcat常用设置 1,Eclipse建立Tomcat服务 1.1 新建Server 首先这里是指,jee版的Eclipse.Eclipse是没有像MyEclipse那样集成Tomc ...
- Tomcat常用配置修改
Tomcat常用配置修改 说明 运行需要设置环境变量 JAVA_HOME 即JDK安装目录 tomcat 默认登录地址 http://localhost:8080 配置tomcat 1.端口设置 打开 ...
- 由浅入深讲解责任链模式,理解Tomcat的Filter过滤器
本文将从简单的场景引入, 逐步优化, 最后给出具体的责任链设计模式实现. 场景引入 首先我们考虑这样一个场景: 论坛上用户要发帖子, 但是用户的想法是丰富多变的, 他们可能正常地发帖, 可能会在网页中 ...
- maven学习6 Eclipse下Tomcat常用设置
Eclipse下Tomcat常用设置 1,Eclipse建立Tomcat服务 1.1 新建Server 首先这里是指,jee版的Eclipse.Eclipse是没有像MyEclipse那样集成Tomc ...
- Django 03 模板路径、模板变量、常用的过滤器
Django 03 模板路径.模板变量.常用的过滤器 一.模板路径 #1.在每个app下面添加一个templates文件 #2.在项目views.py里面第33行INSTALLED_APPS里面添加上 ...
- Wireshark常用快捷键&&过滤器语法
目录 一.快捷键 二.过滤器语法 1.捕获过滤器的BPF(Berkeley Packet Filter)语法 2.显示过滤器 一.快捷键 Ctrl+M 标记/取消标记 shift+ctrl+N/B 下 ...
- Tomcat记录-tomcat常用配置详解和优化方法(转载)
常用配置详解 1 目录结构 /bin:脚本文件目录. /common/lib:存放所有web项目都可以访问的公共jar包(使用Common类加载器加载). /conf:存放配置文件,最重要的是serv ...
- Tomcat常用操作
Tomcat简介 TOMCAT是APACHE JAKARTA软件组织的一个子项目,TOMCAT是一个JSP/SERVLET容器,它是在SUN公司的JSWDK(JAVA SERVER WEB DEVEL ...
随机推荐
- wait event & wake up
在linux驱动中一个常用的场景, 驱动需要等待中断的响应, 才得以执行后续的代码,达到一个原子操作的目的 /* 静态申请队列 */ static DECLARE_WAIT_QUEUE_HEAD(s_ ...
- Maven工程无异常 启动没有出现Starting ProtocolHandler的原因
这个情况可能的原因 一般来说有3种1.数据库没连接上2.注册中心没连接上3.逆向工程生成的mapper 有问题解决:哪个Maven工程出问题,就那个工程的src/main/resource目录下面添加 ...
- django 标签的使用
首先重建一个common的app 然后创建__init__使common成为一个包 注意templatetags 名字使固定的 并在下面创建一个名字为fitter的过滤器 注册过滤器app htm ...
- python从入门到实践-9章类
#!/user/bin/env python# -*- coding:utf-8 -*- # 类名采用的是驼峰命名法,即将类名中每个单词的首字母大写,而不使用下划线.# 对于每个类,都应紧跟在类定义后 ...
- 如何安装并且使用jmeter进行简单的性能测试
Jmeter 介绍 Jmeter 是一款使用Java开发的,开源免费的,测试工具, 主要用来做功能测试和性能测试(压力测试/负载测试). 而且用Jmeter 来测试 Restful API, 非常 ...
- RHEL7 配置网络yum源
redhat系统安装好尽管默认带有yum,但是redhat的更新包只对注册用户有效(收费).所以需要更换yum源. 基本的流程就是: 1.删除redhat7.0系统自带的yum软件包: 2.自行下载所 ...
- 用C#+Selenium+ChromeDriver 生成我的咕咚跑步路线地图
先上结果: 之前 在公司业务中用过java+Selenium+ChromeDriver ,使用起来非常顺手,可以完美模拟真实的用户浏览行为.最近休息的时候想用C#也试一下,于是有了本文. 实现原理一样 ...
- 【RL-TCPnet网络教程】第34章 RL-TCPnet之SMTP客户端
第34章 RL-TCPnet之SMTP客户端 本章节为大家讲解RL-TCPnet的SMTP应用,学习本章节前,务必要优先学习第33章的SMTP基础知识.有了这些基础知识之后,再搞本章节会有事 ...
- 基于emWin的WAV,MP3软解软件播放器,带类似千千静听频谱,含uCOS-III和FreeRTOS两个版本
第9期:WAV,MP3软解播放器,带类似千千静听频谱配套例子:V6-916_STemWin提高篇实验_WAV,MP3软解播放器,带类似千千静听频谱(uCOS-III)V6-917_STemWin提高篇 ...
- Angularjs中的缓存以及缓存清理
写在最前面:这篇博文是2篇文章组成,详细介绍了Angularjs中的缓存以及缓存清理,文章由上海尚学堂转载过来,欢迎大家阅读和评论.转载请注明出处,谢谢! 一个缓存就是一个组件,它可以透明地储存数据, ...