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

简介:

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!-- 过滤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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
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中配置的不需要过滤的路径集合转换为正则匹配模式,如果把相关代码抽出来就是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
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);
         }
             
     }
 
}

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



本文转自 pangfc 51CTO博客,原文链接:http://blog.51cto.com/983836259/1862603,如需转载请自行联系原作者

相关文章
|
7月前
|
传感器 算法 自动驾驶
混合A*运动规划算法:路径规划和路径跟踪-MPC-LQR-PID算法
混合A*运动规划算法:路径规划和路径跟踪-MPC-LQR-PID算法
|
7月前
|
算法 Java
算法:Java计算二叉树从根节点到叶子结点的最大路径和
算法:Java计算二叉树从根节点到叶子结点的最大路径和
|
7月前
|
算法 测试技术 C++
【动态规划】【图论】【C++算法】1575统计所有可行路径
【动态规划】【图论】【C++算法】1575统计所有可行路径
|
7月前
|
算法
【算法优选】 动态规划之路径问题——贰
【算法优选】 动态规划之路径问题——贰
|
7月前
|
算法
算法修炼-动态规划之路径问题(1)
算法修炼-动态规划之路径问题(1)
|
6月前
|
存储 SQL 算法
LeetCode题目113:多种算法实现 路径总和ll
LeetCode题目113:多种算法实现 路径总和ll
|
2月前
|
数据采集 监控 安全
厂区地图导航制作:GIS技术与路径导航算法融合
在智能化、数字化时代,GIS技术为厂区的运营管理带来了革命性变化。本文探讨了如何利用GIS技术,通过数据采集、地图绘制、路径规划、位置定位和信息查询等功能,打造高效、精准的智能厂区地图导航系统,提升企业的竞争力和管理水平。
87 0
厂区地图导航制作:GIS技术与路径导航算法融合
|
4月前
|
算法
基于多路径路由的全局感知网络流量分配优化算法matlab仿真
本文提出一种全局感知网络流量分配优化算法,针对现代网络中多路径路由的需求,旨在均衡分配流量、减轻拥塞并提升吞吐量。算法基于网络模型G(N, M),包含N节点与M连接,并考虑K种不同优先级的流量。通过迭代调整每种流量在各路径上的分配比例,依据带宽利用率um=Σ(xm,k * dk) / cm来优化网络性能,确保高优先级流量的有效传输同时最大化利用网络资源。算法设定收敛条件以避免陷入局部最优解。
|
5月前
|
人工智能 算法 大数据
算法金 | 推导式、生成器、向量化、map、filter、reduce、itertools,再见 for 循环
这篇内容介绍了编程中避免使用 for 循环的一些方法,特别是针对 Python 语言。它强调了 for 循环在处理大数据或复杂逻辑时可能导致的性能、可读性和复杂度问题。
60 6
算法金 | 推导式、生成器、向量化、map、filter、reduce、itertools,再见 for 循环
|
6月前
|
存储 算法 Unix
掌握Unix路径简化:五种有效算法比较【python力扣71题】
掌握Unix路径简化:五种有效算法比较【python力扣71题】

热门文章

最新文章