不容許從禁用的站點(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 何明旺 */ 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規範的字符串,則返回 null */ 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 何明旺 */ 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"); */ } }