什么是白名单及黑名单?
黑名单启用后,被列入到黑名单的用户(或IP地址、IP包、邮件、病毒等)不能通过。如果设立了白名单,则在白名单中的用户(或IP地址、IP包、邮件等)会优先通过,不会被当成垃圾邮件拒收,安全性和快捷性都大大提高。
本文讲解用java实现类似上述所说的拦截及通过功能的过滤链接。
比如我定义了一个mapping,
1
2
3
4
|
< servlet-mapping >
< servlet-name >html_dispatcher</ servlet-name >
< url-pattern >*.html</ url-pattern >
</ servlet-mapping >
|
就是说所有的.html请求都会由html_dispatcher来处理,但现在我的问题是:
我希望某个文件夹下面的.html不用这个html_dispatcher处理,而所有其它的.html请求不变。
因为把所有其它的.html列出来实在太多了,多到我都不知道有多少。所以不能一一列出。
很明显是在白名单里边排除一部分黑名单需求。
大家在开发Java Web时,在使用过滤器时是比较挠头的,比如
1
2
3
4
|
< filter-mapping >
< filter-name >TestFilter</ filter-name >
< url-pattern >/*</ url-pattern >
</ filter-mapping >
|
1、前缀匹配 /user/*
2、后缀匹配 *.do
3、绝对匹配 /myservlet
而且如果我想过滤多个url必须
1
2
3
4
5
6
7
|
< filter-name >TestFilter</ filter-name >
< url-pattern >/a</ url-pattern >
</ filter-mapping >
< filter-mapping >
< filter-name >TestFilter</ filter-name >
< url-pattern >/b</ url-pattern >
</ filter-mapping >
|
两个问题:
1、有的朋友可能需要过滤*.html 但要排除一部分(黑名单);
2、有的朋友可能需要过滤多个url,如/a /b,对于每一个url必须写一个filter-mapping比较繁琐;
因此我写了一个非常简单的具备白名单和黑名单功能的基类Filter,过滤url使用Ant Path:
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
|
package com.sishuok.web.filter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
/**
* Ant语法
* 请参考 http://jinnianshilongnian.iteye.com/blog/1416322
*
* 配置方式
<filter>
<filter-name>TestFilter</filter-name>
<filter-class>com.sishuok.web.filter.TestFilter</filter-class>
<!-- url分隔符可以是 换行 空格 分号 逗号 白名单和黑名单都是可选-->
<init-param>
<param-name>blackListURL</param-name> <!-- 配置黑名单url 表示不走过滤器的url order:1 -->
<param-value>
/aa
/bb/**
/cc/*
</param-value>
</init-param>
<init-param>
<param-name>whiteListURL</param-name> <!-- 配置白名单url 表示走过滤器的url order:2-->
<param-value>
/dd;/ee,/ff /list
</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>TestFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
*
* @author Zhang Kaitao
*
*/
public abstract class BaseFilter implements Filter {
private FilterConfig config = null ;
private final String[] NULL_STRING_ARRAY = new String[ 0 ];
private final String URL_SPLIT_PATTERN = "[, ;\r\n]" ; //逗号 空格 分号 换行
private final PathMatcher pathMatcher = new AntPathMatcher();
private final Logger logger = LoggerFactory.getLogger( "url.filter" );
/**
* 白名单
*/
private String[] whiteListURLs = null ;
/**
* 黑名单
*/
private String[] blackListURLs = null ;
@Override
public final void init(FilterConfig config) throws ServletException {
this .config = config;
this .initConfig();
this .init();
}
/**
* 子类覆盖
*
* @throws ServletException
*/
public void init() throws ServletException {
}
/**
* 1、黑名单匹配 2、白名单匹配
*/
@Override
public final void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
String currentURL = httpRequest.getServletPath();
logger.debug( "url filter : current url : [{}]" , currentURL);
if (isBlackURL(currentURL)) {
chain.doFilter(request, response);
return ;
}
if (isWhiteURL(currentURL)) {
doFilter(httpRequest, httpResponse, chain);
return ;
}
logger.debug( "url filter : no url list matches : [{}] break" , currentURL);
chain.doFilter(request, response);
return ;
}
private boolean isWhiteURL(String currentURL) {
for (String whiteURL : whiteListURLs) {
if (pathMatcher.match(whiteURL, currentURL)) {
logger.debug( "url filter : white url list matches : [{}] match [{}] continue" , whiteURL, currentURL);
return true ;
}
logger.debug( "url filter : white url list not matches : [{}] match [{}]" , whiteURL, currentURL);
}
return false ;
}
private boolean isBlackURL(String currentURL) {
for (String blackURL : blackListURLs) {
if (pathMatcher.match(blackURL, currentURL)) {
logger.debug( "url filter : black url list matches : [{}] match [{}] break" , blackURL, currentURL);
return true ;
}
logger.debug( "url filter : black url list not matches : [{}] match [{}]" , blackURL, currentURL);
}
return false ;
}
/**
* 子类覆盖
*
* @param request
* @param response
* @param chain
* @throws IOException
* @throws ServletException
*/
public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws IOException, ServletException {
chain.doFilter(request, response);
}
/**
* 子类覆盖
*/
@Override
public void destroy() {
}
private void initConfig() {
String whiteListURLStr = this .config.getInitParameter( "whiteListURL" );
whiteListURLs = strToArray(whiteListURLStr);
String blackListURLStr = this .config.getInitParameter( "blackListURL" );
blackListURLs = strToArray(blackListURLStr);
}
private String[] strToArray(String urlStr) {
if (urlStr == null ) {
return NULL_STRING_ARRAY;
}
String[] urlArray = urlStr.split(URL_SPLIT_PATTERN);
List<String> urlList = new ArrayList<String>();
for (String url : urlArray) {
url = url.trim();
if (url.length() == 0 ) {
continue ;
}
urlList.add(url);
}
return urlList.toArray(NULL_STRING_ARRAY);
}
public FilterConfig getConfig() {
return config;
}
}
|
具体使用如下:
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
|
package com.sishuok.web.filter;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class TestFilter extends BaseFilter {
@Override
public void init() throws ServletException { //初始化
FilterConfig config = getConfig();
}
@Override
public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println( "==============" );
chain.doFilter(request, response);
}
@Override
public void destroy() { //销毁
}
}
|
xml配置如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
< filter >
< filter-name >TestFilter</ filter-name >
< filter-class >com.sishuok.web.filter.TestFilter</ filter-class >
<!-- url分隔符可以是 换行 空格 分号 逗号 白名单和黑名单都是可选-->
< init-param >
< param-name >blackListURL</ param-name > <!-- 配置黑名单url 表示不走过滤器的url order:1 -->
< param-value >
/aa
/bb/**
/cc/*
</ param-value >
</ init-param >
< init-param >
< param-name >whiteListURL</ param-name > <!-- 配置白名单url 表示走过滤器的url order:2-->
< param-value >
/dd;/ee,/ff /list
</ param-value >
</ init-param >
</ filter >
< filter-mapping >
< filter-name >TestFilter</ filter-name >
< url-pattern >/*</ url-pattern >
</ filter-mapping >
|
因为相对来说实现很简单,具体实现就不详细介绍了。