什么是白名單及黑名單?
黑名單啟用后,被列入到黑名單的用戶(或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 >
|
因為相對來說實現很簡單,具體實現就不詳細介紹了。