详解Tomcat常用的过滤器

一、跨域过滤器CorsFilter

org.apcache.catalina.filters.CorsFilter是跨域资源共享规范的一个实现,常常用于前后端分离,静态资源与后端分离等情况。它主要在HttpServletResponse中增加Access-Control-*头,同时保护HTTP响应避免拆分,如果请求无效或者禁止访问,则返回403响应码。

1.1、配置示例

<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.2、参数说明

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:正常同域请求

INVALID_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使用该随机数进行编码。当接收到下一个请求时,请求中随机数与会话中的进行对比,只有两者相同时,请求才会被允许。

2.1、配置示例

<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>

2.2、参数说明

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获取)是否符合指定正则表达式。

4.1、配置示例

<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>

4.2、参数说明  

1、allow:指定允许访问的客户端IP地址  

2、deny:拒绝访问的客户端地址  

3、denyStatus:拒绝请求时返回的HTTP响应吗。

五、获取客户端Host过滤器RemoteHostFilter

org.apcache.catalina.filters.RemoteHostFiler允许比较提交请求的客户端主机名是否符合指定的正则表达式,以确定是否允许继续处理请求。参数同RemoteAddrFilter

六、获取原始客户端IP过滤器RemoteIpFilter

 当客户端通过HTTP代理或者负载均衡访问服务器时,对于服务器来说,请求直接源自前置的代理服务器,此时获取到的远程IP实际为代理服务器的IP地址。

6.1、如何获得原始的客户端的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;
}

6.2、配置示例

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编码,而请求中的编码可以在未指定编码时使用,也可以强制覆盖。

7.1、配置示例

<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>

7.2、参数说明  

1、encoding:指定的字符集编码    

2、ignore:表示是否忽略客户端请求设置的字符集编码,如果为true那么都会将请求字符集编码覆盖,如果为false,请求没有指定字符集编码时设置。默认为false

以上就是详解Tomcat常用的过滤器的详细内容,更多关于Tomcat过滤器的资料请关注我们其它相关文章!

(0)

相关推荐

  • Tomcat核心组件及应用架构详解

    Web 容器是什么? 让我们先来简单回顾一下 Web 技术的发展历史,可以帮助你理解 Web 容器的由来. 早期的 Web 应用主要用于浏览新闻等静态页面,HTTP 服务器(比如 Apache.Nginx)向浏览器返回静态 HTML,浏览器负责解析 HTML,将结果呈现给用户. 随着互联网的发展,我们已经不满足于仅仅浏览静态页面,还希望通过一些交互操作,来获取动态结果,因此也就需要一些扩展机制能够让 HTTP 服务器调用服务端程序. 于是 Sun 公司推出了 Servlet 技术.你可以把 Se

  • 基于tomcat8 编写字符编码Filter过滤器无效问题的解决方法

    同事遇到编码问题时想做一个解决全站的字符编码过滤器,过滤器类和配置如下: 过滤器类: <span style="font-size:12px;">package com.chaoxing.newspaper.web.filter; import java.io.IOException; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.r

  • 解析Tomcat架构原理到架构设计

    目录 一.学习目的 1.1.掌握 Tomcat 架构设计与原理提高内功 1.2.宏观理解一个请求如何与 Spring 联系起来 1.3.提升自己的系统设计能力 二.整体架构设计 2.1.连接器 2.2.封装变与不变 2.3.容器 2.4.请求定位 Servlet 的过程 三.Tomcat 为何打破双亲委派机制 3.1.双亲委派 3.2.Tomcat 热加载 3.3.Tomcat 的类加载器 3.4.Tomcat 类加载器层次 四.整体架构设计解析收获总结 4.1.连接器 4.2.容器 4.3.类

  • Tomcat源码解析之Web请求与处理

    前言 Tomcat最全UML类图 Tomcat请求处理过程: Connector对象创建的时候,会创建Http11NioProtocol的ProtocolHandler,在Connector的startInteral方法中,会启动AbstractProtocol,AbstractProtocol启动NioEndPoint进行监听客户端的请求,EndPoint接受到客户端的请求之后,会交给Container去处理请求.请求从Engine开始经过的所有容器都含有责任链模式,每经过一个容器都会调用该容

  • Tomcat将配置文件放在外部的解决方法

    问题 我们在平常开发的时候, 如果要把项目部署到Tomcat里面, 一般的做法就是讲项目打成war包, 然后将war包扔到Tomcat的webapps目录下面, 然后启动项目就可以了. 但是在将项目部署到生产环境的时候, 生产环境的配置文件一般是与本地开发不一样的, 那么使用刚刚的方法在生产上部署, 就比较麻烦, 需要手动去删除原来的配置文件, 或者打包的时候排除配置文件, 然后在将正确的配置文件复制到项目的resource目录下面去. 那么,有没有更简单一点的方法呢? 解决方法 我们可以将配置

  • 详解Tomcat常用的过滤器

    一.跨域过滤器CorsFilter org.apcache.catalina.filters.CorsFilter是跨域资源共享规范的一个实现,常常用于前后端分离,静态资源与后端分离等情况.它主要在HttpServletResponse中增加Access-Control-*头,同时保护HTTP响应避免拆分,如果请求无效或者禁止访问,则返回403响应码. 1.1.配置示例 <filter> <filter-name>CorsFilter</filter-name> <

  • 详解AngularJS中$filter过滤器使用(自定义过滤器)

    1.内置过滤器 * $filter 过滤器,是angularJs中用来处理数据以更好的方式展示给我用户.比如格式化日期,转换大小写等等. * 过滤器即有内置过滤器也支持自定义过滤器.内置过滤器很多,可以百度.关键是如何使用: * 1.在HTML中直接使用内置过滤器 * 2.在js代码中使用内置过滤器 * 3.自定义过滤器 * * (1)常用内置过滤器 * number 数字过滤器,可以设置保留数字小数点后几位等 * date 时间格式化过滤器,可自己设置时间格式 * filter 过滤的数据一般

  • 详解Tomcat出现404的解决方法

    Tomcat测试出现404问题出现的问题如下: HTTP状态 404 - 未找到 类型 状态报告 消息 请求的资源[/chapter06/IndexServlet]不可用 描述 源服务器未能找到目标资源的表示或者是不愿公开一个已经存在的资源表示. Apache Tomcat/9.0.37 问题原因,浏览器不能直接访问Java文件 问题的解决方法 1.提交表单时遇到此问题 <form name = "reg" action="/login" method=&qu

  • 详解tomcat各个端口的作用

    从tomcat配置文件中,我们可以看出,在启动tomcat的时候默认启动了3个端口,分别是8080(8443).8009.8005. 8080(8443)端口 <Connector port="80" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> 这个应该是我们最熟悉的一个,平常开发测试也经常用,该Connector用于监听

  • 详解JavaWeb中的过滤器Filter

    一.什么是过滤器 1.Filter过滤器的作用:拦截请求 2.拦截请求常见场景: (1)权限检查 (2)日记操作 (3)事务管理 1.1 使用步骤 Filter 过滤器的使用步骤: 1.编写一个类去实现Filter 接口 2.实现过滤方法doFilter() 3.到web.xml 中去配置Filter 的拦截路径 二.初体验 web工程下新建一个admin目录,作为需要权限才能访问的目录,其中有两个文件 2.1 mynav.html <!DOCTYPE html> <html lang=

  • 详解JSP中使用过滤器进行内容编码的解决办法

    详解JSP中使用过滤器进行内容编码的解决办法 问题 当通过JSP页面,向数据库中插入记录的时候,可能因为JSP页面编码原因,导致插入到数据库中的新纪录出现乱码.因此需要对JSP页面中的内容进行编码操作,从而保证与数据库中的编码一致. 解决方案 使用JSP中过滤器进行处理.处理步骤如下 1.新建一个servlet,使其实现javax.servlet.Filter接口 2.修改Servlet/JSP Mapping URL ,将其改为 /EncodingFilter 3.在EncodingFilte

  • 详解tomcat热部署和热加载的方法

    详解tomcat热部署和热加载的方法 我在项目开发过程中,经常要改动Java/JSP 文件,但是又不想从新启动服务器(服务器从新启动花时间),想直接获得(debug)结果.有两种方式热部署 和热加载: 1.热加载:在server.xml -> context 属性中 设置 reloadable="true" <Context docBase="xxx" path="/xxx" reloadable="true"/&

  • es6系列教程_ Map详解以及常用api介绍

    ECMAScript 6中的Map类型是一种存储着许多键值对的有序列表.键值对支持所有的数据类型. 键 0 和 '0'会被当做两个不同的键,不会发生强制类型转换. 如何使用Map? let map = new Map(); 常用方法: set( 键,值 ): 添加新的键值对元素 get( 键 ): 获取键对应的值,如果这个值不存在,返回undefined let map = new Map(); map.set( '0', 'ghostwu' ); map.set( 0, 'ghostwu' )

  • Git 命令详解及常用命令整理

    Git 命令详解及常用命令 Git作为常用的版本控制工具,多了解一些命令,将能省去很多时间,下面这张图是比较好的一张,贴出了看一下: 关于git,首先需要了解几个名词,如下: Workspace //工作区 Index / Stage //暂存区 Repository //仓库区(或本地仓库) Remote //远程仓 一.新建代码库 // 在当前目录新建一个Git代码库 $ git init // 新建一个目录,将其初始化为Git代码库 $ git init [project-name] //

  • 详解 Linux 常用目录的作用

     详解 Linux 常用目录的作用 一 常用一级目录 注意: 1.根目录下的bin和sbin,usr目录下的bin和sbin,这四个目录都是用来保存系统命令的. 2.bin目录下的命令时任何用户都能执行,sbin目录下的命令只有超级用户才能执行. 3.media用来挂载光盘,misc挂载磁带机,mnt挂载U盘.它们都是空目录. 4.proc和sys目录不能直接操作,这两个目录保存的是内存挂载点. 5.可以在家目录root或home,以及tmp目录下随便放内容. 二 实战 [root@localh

随机推荐