??????? 不允许从禁用的站点(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");
?????????*/
????}
}
?