設置站點黑名單的過濾器(BannedAccessFilter)

功能描述

        不容許從禁用的站點(IP)訪問當前應用,也不容許從禁用的站點連接到當前應用。
        爲了簡單起見,設置禁用站點時,暫不支持使用通配符。只是拋磚引玉了。
        好比:禁止其餘的網站引用本站的圖片資源,只需在此基礎上稍做修改便可。html

使用方法

        在 java web 項目的 web.xml 文件中添加以下代碼。java

<!--設置站點黑名單的過濾器配置  開始 -->
<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;
 
/**
 * 設置禁用站點(黑名單)的過濾器
 * @author <a href="mailto:hemingwang0902@126.com">何明旺</a>
 */
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");
         */
    }
}
相關文章
相關標籤/搜索