基础算法10:过滤器(Filter)对指定路径不进行过滤

(1)在web.xml中配置这样一个过滤器:

	<!-- 过滤XSS -->
	<filter>
		<filter-name>xssFilter</filter-name>
		<filter-class>cn.zifangsky.filter.XSSFilter</filter-class>
		<init-param>
			<param-name>exclude</param-name>
			<param-value>/;/scripts/*;/styles/*;/images/*</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>xssFilter</filter-name>
		<url-pattern>*.html</url-pattern>
		<!-- 直接从客户端过来的请求以及通过forward过来的请求都要经过该过滤器 -->
		<dispatcher>REQUEST</dispatcher>
		<dispatcher>FORWARD</dispatcher>
	</filter-mapping>

(2)过滤器XSSFilter.java:

package cn.zifangsky.filter;

import java.io.IOException;
import java.util.Enumeration;
import java.util.Map;
import java.util.Vector;
import java.util.regex.Pattern;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

public class XSSFilter extends OncePerRequestFilter {
	private String exclude = null;  //不需要过滤的路径集合
	private Pattern pattern = null;  //匹配不需要过滤路径的正则表达式

	public void setExclude(String exclude) {
		this.exclude = exclude;
		pattern = Pattern.compile(getRegStr(exclude));
	}

	/**
	 * XSS过滤
	 */
	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
			throws ServletException, IOException {
		String requestURI = request.getRequestURI();
		if(StringUtils.isNotBlank(requestURI))
			requestURI = requestURI.replace(request.getContextPath(),"");

		if(pattern.matcher(requestURI).matches())
			filterChain.doFilter(request, response);
		else{
			EscapeScriptwrapper escapeScriptwrapper = new EscapeScriptwrapper(request);
			filterChain.doFilter(escapeScriptwrapper, response);
		}
	}

	/**
	 * 将传递进来的不需要过滤得路径集合的字符串格式化成一系列的正则规则
	 * @param str 不需要过滤的路径集合
	 * @return 正则表达式规则
	 * */
	private String getRegStr(String str){
		if(StringUtils.isNotBlank(str)){
			String[] excludes = str.split(";");  //以分号进行分割
			int length = excludes.length;
			for(int i=0;i<length;i++){
				String tmpExclude = excludes[i];
				//对点、反斜杠和星号进行转义
				tmpExclude = tmpExclude.replace("\\", "\\\\").replace(".", "\\.").replace("*", ".*");

				tmpExclude = "^" + tmpExclude + "$";
				excludes[i] = tmpExclude;
			}
			return StringUtils.join(excludes, "|");
		}
		return str;
	}

	/**
	 * 继承HttpServletRequestWrapper,创建装饰类,以达到修改HttpServletRequest参数的目的
	 * */
	private class EscapeScriptwrapper extends HttpServletRequestWrapper{
		private Map<String, String[]> parameterMap;  //所有参数的Map集合
		public EscapeScriptwrapper(HttpServletRequest request) {
			super(request);
			parameterMap = request.getParameterMap();
		}

		//重写几个HttpServletRequestWrapper中的方法
		/**
		 * 获取所有参数名
		 * @return 返回所有参数名
		 * */
		@Override
		public Enumeration<String> getParameterNames() {
			Vector<String> vector = new Vector<String>(parameterMap.keySet());
			return vector.elements();
		}

		/**
		 * 获取指定参数名的值,如果有重复的参数名,则返回第一个的值
		 * 接收一般变量 ,如text类型
		 * 
		 * @param name 指定参数名
		 * @return 指定参数名的值
		 * */
		@Override
		public String getParameter(String name) {
			String[] results = parameterMap.get(name);
			if(results == null || results.length <= 0)
				return null;
			else{
				return escapeXSS(results[0]);
			}
		}

		/**
		 * 获取指定参数名的所有值的数组,如:checkbox的所有数据
		 * 接收数组变量 ,如checkobx类型
		 * */
		@Override
		public String[] getParameterValues(String name) {
			String[] results = parameterMap.get(name);
			if(results == null || results.length <= 0)
				return null;
			else{
				int length = results.length;
				for(int i=0;i<length;i++){
					results[i] = escapeXSS(results[i]);
				}
				return results;
			}
		}

		/**
		 * 过滤字符串中的js脚本
		 * 解码:StringEscapeUtils.unescapeXml(escapedStr)
		 * */
		private String escapeXSS(String str){
//			return StringEscapeUtils.escapeXml(StringEscapeUtils.escapeEcmaScript(str));
			return StringEscapeUtils.escapeXml(str);
		}
	}

}

当然,我这里主要说的是如何将在web.xml中配置的不需要过滤的路径集合转换为正则匹配模式,如果把相关代码抽出来就是这样的:

import java.util.regex.Pattern;

import org.apache.commons.lang3.StringUtils;

public class Demo3 {
	private static String getRegStr(String str){
		if(StringUtils.isNotBlank(str)){
			String[] excludes = str.split(";");  //以分号进行分割
			int length = excludes.length;
			for(int i=0;i<length;i++){
				String tmpExclude = excludes[i];
				//对点、反斜杠和星号进行转义
				tmpExclude = tmpExclude.replace("\\", "\\\\").replace(".", "\\.").replace("*", ".*");

				tmpExclude = "^" + tmpExclude + "$";
				excludes[i] = tmpExclude;
			}
			return StringUtils.join(excludes, "|");
		}
		return str;
	}

	public static void main(String[] args) {
		String t1 = "/;/scripts/*;/styles/*;/images/*";
		String t2 = "*/js/*;/scripts/*;";
		String t3 = "\\;\\scripts\\*";
		String t4 = "*";
		String t5 = "/pages/*/js/*";
		String t6 = "/page.html/js/*";

		String test = "/pages/scripts/xx.js";
		Pattern pattern = Pattern.compile(Demo3.getRegStr(t1));
		if(pattern.matcher(test).matches()){
			System.out.println("该路径不需要过滤");
//			filterChain.doFilter(request, response);
		}else{
			System.out.println("需要过滤处理");
//			EscapeScriptwrapper escapeScriptwrapper = new EscapeScriptwrapper(request);
//			filterChain.doFilter(escapeScriptwrapper, response);
		}

	}

}

代码很简单,因此这里就不多做解释了

时间: 2025-01-01 01:45:53

基础算法10:过滤器(Filter)对指定路径不进行过滤的相关文章

[10] 过滤器 Filter

1.过滤器的基本概念和作用 在网站的页面访问时,我们往往需要做一些控制,如普通用户无法访问VIP用户的页面.如果在每一个需要访问控制的文件中都加上判断代码,那么代码将会很冗余,一旦需要统一修改时也极其繁琐. 过滤器就可以解决这样的问题,配置完成的过滤器,会强制让指定的页面在访问之前先从过滤器走一趟. 2.过滤器相关的API Servlet API中,与过滤器有关的API共有三个接口,分别是: Filter FilterChain (在Filter中init方法作为参数) FilterConfig

javaWeb学习总结(10)- Filter(过滤器)学习

一.Filter简介 Filter也称之为过滤器,它是Servlet技术中最激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有 web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能.例如实现URL级别的权限访问控制.过滤敏感词汇.压缩响应信息等一些高级功能. Servlet API中提供了一个Filter接口,开发web应用时,如果编写的Java类实现了这个接口,则把这个java类称之为过滤器Filter.通过

C#控制台基础 directory判断指定路径下是否存在指定的文件夹

1 探测的文件夹 2 代码 1 using System; 2 using System.Collections.Generic; 3 using System.IO; 4 using System.Linq; 5 using System.Text; 6 using System.Threading.Tasks; 7 8 namespace directory创建一个文件夹 9 { 10 class Program 11 { 12 static void Main(string[] args)

javaWeb学习总结(10)- Filter(过滤器)常见应用(3)

一.统一全站字符编码 通过配置参数charset指明使用何种字符编码,以处理Html Form请求参数的中文问题 package me.gacl.web.filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException;

javaWeb学习总结(10)- Filter(过滤器)学习(2)

在filter中可以得到代表用户请求和响应的request.response对象,因此在编程中可以使用Decorator(装饰器)模式对request.response对象进行包装,再把包装对象传给目标资源,从而实现一些特殊需求. 一.Decorator设计模式 1.1.Decorator设计模式介绍 当某个对象的方法不适应业务需求时,通常有2种方式可以对方法进行增强: 编写子类,覆盖需增强的方法. 使用Decorator设计模式对方法进行增强. 在阎宏博士的<JAVA与模式>一书中开头是这样

C语言的10大基础算法

C语言的10大基础算法 算法是一个程序和软件的灵魂,作为一名优秀的程序员,只有对一些基础的算法有着全面的掌握,才会在设计程序和编写代码的过程中显得得心应手.本文是近百个C语言算法系列的第二篇,包括了经典的Fibonacci数列.简易计算器.回文检查.质数检查等算法.也许他们能在你的毕业设计或者面试中派上用场. 1.计算Fibonacci数列 Fibonacci数列又称斐波那契数列,又称黄金分割数列,指的是这样一个数列:1.1.2.3.5.8.13.21. C语言实现的代码如下: /* Displ

监听器listener&amp;过滤器filter

Servlet技术规范 描述三种技术 : Servlet(服务器小程序) .Filter(过滤器) .Listener(监听器) Filter运行在服务器端,对服务器端web资源的访问 进行拦截,起到过滤的作用 Servlet API中 定义接口 Filter,用户只需要编写程序实现Filter接口,完成过滤器编写 Filter快速入门1.编写类 实现 Filter接口2.在服务器端注册 Filter (配置拦截哪个web资源) ----- web.xml   <!-- 注册过滤器 --> 

springCloud学习05之api网关服务zuul过滤器filter

前面学习了zuul的反向代理.负载均衡.fallback回退.这张学习写过滤器filter,做java web开发的对filter都不陌生,那就是客户端(如浏览器)发起请求的时候,都先经过过滤器filter做一些相关的校验或业务判断(如登录.权限等),zuul也同样提供了过滤器功能.只要继承ZuulFilter类即可. 通过前文的介绍,我们对于Zuul的第一印象通常是这样的:它包含了对请求的路由和过滤两个功能,其中路由功能负责将外部请求转发到具体的微服务实例上,是实现外部访问统一入口的基础:而过

深入分析JavaWeb Item36 -- 过滤器Filter高级应用

在filter中可以得到代表用户请求和响应的request.response对象,因此在编程中可以使用Decorator(装饰器)模式对request.response对象进行包装,再把包装对象传给目标资源,从而实现一些特殊需求. 一.Decorator设计模式 1.1.Decorator设计模式介绍 当某个对象的方法不适应业务需求时,通常有2种方式可以对方法进行增强: 编写子类,覆盖需增强的方法. 使用Decorator设计模式对方法进行增强. 使用代理 在阎宏博士的<JAVA与模式>一书中