??????? 不允许从禁用的站点(IP)访问当前应用,也不允许从禁用的站点链接到当前应用。
??????? 为了简单起见,设置禁用站点时,暂不支持使用通配符。只是抛砖引玉了。
??????? 比如:禁止其他的网站引用本站的图片资源,只需在此基础上稍作修改即可。
??????? 在 java web 项目的 web.xml 文件中添加如下代码。
monospace !important; font-size: 12px !important; font-style: normal !important; font-weight: normal !important; vertical-align: baseline !important; float: none !important; white-space: pre-wrap;" class="xml comments"><!--设置站点黑名单的过滤器配置? 开始 -->
<
filter
>
?
<
filter-name
>BannedAccessFilter</
filter-name
>
?
<
filter-class
>com.hmw.filter.BannedAccessFilter</
filter-class
>
?
<
init-param
>
?????
<
description
>需要禁用的站点,一个站点占用一行</
description
>
?????
<
param-name
>bannedSites</
param-name
>
?????
<
param-value
>
?????????
192.168.1.101
?????????
192.168.1.102
?????????
www.csdn.net
?????
</
param-value
>
?
</
init-param
>
</
filter
>
?
<
filter-mapping
>
?
<
filter-name
>BannedAccessFilter</
filter-name
>
?
<
url-pattern
>/*</
url-pattern
>
</
filter-mapping
>
<!--设置站点黑名单的过滤器配置? 结束 -->
package
?com.hmw.filter;
?
import
?java.io.IOException;
import
?java.io.PrintWriter;
import
?java.net.MalformedURLException;
import
?java.net.URL;
import
?java.util.HashSet;
import
?java.util.StringTokenizer;
?
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
?org.apache.commons.lang3.StringUtils;
import
?org.apache.log4j.Logger;
?
/**
?
* 设置禁用站点(黑名单)的过滤器
?
*/
public
?class
?BannedAccessFilter
implements
?Filter {
????
static
?final
?Logger logger = Logger.getLogger(BannedAccessFilter.
class
);
????
?
????
private
?HashSet bannedSiteTable;
????
?
????
/**
?????
* 将配置的禁用站点列表初始化到一个 HashSet 中
?????
*/
????
@Override
????
public
?void
?init(FilterConfig config)
throws
?ServletException {
????????
bannedSiteTable =
new
?HashSet();
????????
String bannedSites = config.getInitParameter(
"bannedSites"
);
????????
// Default token set: white space.
????????
StringTokenizer tok =
new
?StringTokenizer(bannedSites);
????????
while
?(tok.hasMoreTokens()) {
????????????
String bannedSite = tok.nextToken();
????????????
bannedSiteTable.add(bannedSite);
????????????
logger.info(
"Banned "
?+ bannedSite);
????????
}
????
}
????
?
????
/**
?????
* 如果请求来自被禁用的站点,或是从被禁用的站点链接过来的,则拒绝访问。
?????
*/
????
@Override
????
public
?void
?doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws
?ServletException, IOException {
????????
logger.debug(
"BannedAccessFilter: Filtering the Request..."
);
????????
?
????????
HttpServletRequest req = (HttpServletRequest) request;
????????
String requestingHost = req.getRemoteHost();
????????
String referringHost = getReferringHost(req.getHeader(
"Referer"
));
????????
?
????????
String bannedSite =
null
;
????????
boolean
?isBanned =
false
;
????????
if
?(bannedSiteTable.contains(requestingHost)) {
????????????
bannedSite = requestingHost;
????????????
isBanned =
true
;
????????
}
else
?if
?(bannedSiteTable.contains(referringHost)) {
????????????
bannedSite = referringHost;
????????????
isBanned =
true
;
????????
}
????????
?
????????
if
?(isBanned) {
????????????
showWarning(response, bannedSite);
????????
}
else
?{
????????????
chain.doFilter(request, response);
????????
}
????????
?
????????
logger.debug(
"BannedAccessFilter: Filtering the Response..."
);
????
}
?
????
@Override
????
public
?void
?destroy() {
????
}
?
????
/**
?????
* 根据 URL 链接地址,取得该链接地址所在的站点
?????
* @param refererringURLString URL链接地址
?????
* @return 该 URL 链接地址所在的站点,如果传入的参数不是一个符合URL规范的字符串,则返回 <code>null</code>
?????
*/
????
private
?String getReferringHost(String refererringURLString) {
????????
if
(StringUtils.isBlank(refererringURLString))
????????????
return
?null
;
????????
?
????????
try
?{
????????????
URL referringURL =
new
?URL(refererringURLString);
????????????
return
?referringURL.getHost();
????????
}
catch
?(MalformedURLException mue) {
// Malformed
????????????
return
?null
;
????????
}
????
}
?
????
/**
?????
* 如果用户是从禁用站点访问的该应用,或是从禁用站点链接过来的,则调用此方法将警告信息展现给用户。
?????
* @param response HTTP请求响应对象
?????
* @param bannedSite 禁止的站点
?????
* @throws ServletException
?????
* @throws IOException
?????
* @author <a href="mailto:hemw@mochasoft.com.cn">何明旺</a>
?????
*/
????
private
?void
?showWarning(ServletResponse response, String bannedSite)
throws
?ServletException, IOException {
????????
String htmlCode? =
""
;
????????
htmlCode +=
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">"
;
????????
htmlCode +=
"<html xmlns=\"http://www.w3.org/1999/xhtml\">"
;
????????
htmlCode +=
"? <head>"
;
????????
htmlCode +=
"????? <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />"
;
????????
htmlCode +=
"????? <title>禁止访问</title>"
;
????????
htmlCode +=
"? </head>"
;
????????
htmlCode +=
"? <body>"
;
????????
htmlCode +=
"????? <h1>禁止访问</h1>"
;
????????
htmlCode +=
"????? <p>对不起,您无法访问该资源,因为您的站点已经被列入我们的黑名单!</p>"
;
????????
htmlCode +=
"????? <p>您的站点是:<strong>"
?+ bannedSite +
"</strong></p>"
;
????????
htmlCode +=
"? </body>"
;
????????
htmlCode +=
"</html>"
;
?
????????
response.setContentType(
"text/html"
);
????????
PrintWriter out =
null
;
????????
try
{
????????????
out = response.getWriter();
????????????
out.println(htmlCode);
????????
}
finally
{
??????????????
if
(out !=
null
){
????????????????
out.flush();
????????????????
out.close();
??????????????
}
????????
}
????????
?
????????
/*
?????????
* 也可以使用下面的方法直接转发或重定向到指定的警告页面
?????????
* 转发:
?????????
*???? ((HttpServletRequest)request).getRequestDispatcher("/warn.html").forward(request, response);
?????????
* 重定向:
?????????
*???? ((HttpServletResponse)response).sendRedirect("webAppContext/warn.html");
?????????
*/
????
}
}
?