博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
基础算法10:过滤器(Filter)对指定路径不进行过滤
阅读量:6534 次
发布时间:2019-06-24

本文共 5791 字,大约阅读时间需要 19 分钟。

(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,如需转载请自行联系原作者

你可能感兴趣的文章
Linux MySQL 储存中文失败简单解决办法
查看>>
洛谷——P1330 封锁阳光大学
查看>>
css选择器
查看>>
zabbix-agent配置文件说明
查看>>
linux系统配置之bash shell的配置(centos)
查看>>
linux C 9*9
查看>>
hdu 1695: GCD 【莫比乌斯反演】
查看>>
python的string操作总结
查看>>
如何把word中的图片怎么导出来呢?
查看>>
CMD指令大全
查看>>
十五天精通WCF——第二天 告别烦恼的config配置
查看>>
Qt多线程学习:创建多线程
查看>>
设计模式学习---UML常见关系的实现
查看>>
图解openssl实现私有CA
查看>>
BZOJ2213 : [Poi2011]Difference
查看>>
c++ Constructor FAQ 继续
查看>>
事务之六:spring 嵌套事务
查看>>
C#:路径
查看>>
js表单计算金额问题
查看>>
iOS图片加载速度极限优化—FastImageCache解析
查看>>