9.8. Example: A Prohibited-Site Filter

Suppose you have a competitor that you want to ban from your site. For example, this competing company might have a service that accesses your site, removes advertisements and information that identify your organization, and displays them to their customers. Or, they might have links to your site that are in framed pages, thus making it appear that your page is part of their site. You’d like to prevent them from accessing certain pages at your site. However, every time their Web hosting company boots them off, they simply change domain names and register with another ISP. So, you want the ability to easily change the domain names that should be banned.

The solution is to make a filter that uses initialization parameters to obtain a list of banned sites. Requests originating or referred from these sites result in a warning message. Other requests proceed normally. To implement this functionality, the filter has the following capabilities.

  1. A class that implements the Filter interface. This class is called BannedAccessFilter and is shown in Listing 9.11. The init method of this class first obtains a list of sites from an initialization parameter called bannedSites. The filter parses the entries in the resultant String with a StringTokenizer and stores each individual site name in a HashMap that is accessible through an instance variable (i.e., field) of the filter. Finally, BannedAccessFilter provides an empty body for the destroy method.

  2. Filtering behavior in the doFilter method. This method looks up the requesting and referring hosts by using the getRemoteHost method of ServletRequest and parsing the Referer HTTP request header, respectively.

  3. A conditional call to the doFilter method of the FilterChain. The filter checks to see if the requesting or referring host is listed in the HashMap of banned sites. If so, it calls the showWarning method, which sends a custom response to the client. If not, the filter calls doFilter on the FilterChain object to let the request proceed normally.

  4. Registration with the daily special servlet; definition of initialization parameters. First, the filter element associates the name BannedAccessFilter with the class moreservlets.filters.BannedAccessFilter. The filter element also includes an init-param subelement that specifies the prohibited sites (separated by white space). Since the resource that the competing sites abuse is the servlet that shows the daily special, the filter-mapping element uses a servlet-name of TodaysSpecial. The servlet element assigns the name TodaysSpecial to more-servlets.TodaysSpecialServlet. See Listing 9.12.

  5. Disablement of the invoker servlet. This operation is shown in Section 9.2 and is not repeated here.

Listing 9.13 shows a very simple page that contains little but a link to the daily special servlet. When that page is hosted on a normal site (Figure 9-3), the link results in the expected output (Figure 9-4). But, when the page that contains the link is hosted on a banned site (Figure 9-5), the link results only in a warning page (Figure 9-6)— access to the real servlet is blocked.

Figure 9-3. A page that links to the daily special servlet. This version is hosted on the desktop development server.


Figure 9-4. You can successfully follow the link from the page of Figure 9-3. The BannedAccessFilter does not prohibit access from localhost.


Figure 9-5. A page that links to the daily special servlet. This version is hosted on www.moreservlets.com.


Figure 9-6. You cannot successfully follow the link from the page of Figure 9-5. The BannedAccessFilter prohibits access from www.moreservlets.com (an unscrupulous competitor to filtersRus.com).


Listing 9.11. BannedAccessFilter.java
package moreservlets.filters; 

import java.io.*; 
import javax.servlet.*; 
import javax.servlet.http.*; 
import java.util.*; 
import java.net.*; 

/** Filter that refuses access to anyone connecting directly 
 *  from or following a link from a banned site. 
 */ 

public class BannedAccessFilter implements Filter {
  private HashSet bannedSiteTable; 
  /** Deny access if the request comes from a banned site 
   *  or is referred here by a banned site. 
   */ 

  public void doFilter(ServletRequest request, 
                       ServletResponse response, 
                       FilterChain chain) 
      throws ServletException, IOException {
    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);
						} 
  } 

  /** Create a table of banned sites based on initialization 
   *  parameters. Remember that version 2.3 of the servlet 
   *  API mandates the use of the Java 2 Platform. Thus, 
   *  it is safe to use HashSet (which determines whether 
   *  a given key exists) rather than the clumsier 
   *  Hashtable (which has a value for each key). 
   */ 

  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); 
      System.out.println("Banned " + bannedSite); 
    } 
  } 

  public void destroy() {} 

  private String getReferringHost(String refererringURLString) {
    try {
      URL referringURL = new URL(refererringURLString); 
      return(referringURL.getHost()); 
    } catch(MalformedURLException mue) { // Malformed or null 
      return(null); 
    } 
  } 
  // Replacement response that is returned to users 
  // who are from or referred here by a banned site. 

  private void showWarning(ServletResponse response,
						String bannedSite)
						throws ServletException, IOException {
						response.setContentType("text/html");
						PrintWriter out = response.getWriter();
						String docType =
						"<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 " +
						"Transitional//EN">
";
						out.println
						(docType +
						"<HTML>
" +
						"<HEAD><TITLE>Access Prohibited</TITLE></HEAD>
" +
						"<BODY BGCOLOR="WHITE">
" +
						"<H1>Access Prohibited</H1>
" +
						"Sorry, access from or via " + bannedSite + "
" +
						"is not allowed.
" +
						"</BODY></HTML>");
						} 
} 

Listing 9.12. web.xml (Excerpt for prohibited-site filter)
<?xml version="1.0" encoding="ISO-8859-1"?> 
<!DOCTYPE web-app PUBLIC 
    "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" 
    "http://java.sun.com/dtd/web-app_2_3.dtd"> 

<web-app> 
  <!-- ... --> 

  <!-- Register the name "BannedAccessFilter" for 
       moreservlets.filter.BannedAccessFilter. 
       Supply an initialization parameter: 
       bannedSites. 
  --> 
  <filter> 
    <filter-name>BannedAccessFilter</filter-name> 
    <filter-class> 
      moreservlets.filters.BannedAccessFilter 
    </filter-class> 
    <init-param>
						<param-name>bannedSites</param-name>
						<param-value>
						www.competingsite.com
						www.bettersite.com
						www.moreservlets.com
						</param-value>
						</init-param> 
  </filter> 
  <!-- ... --> 

  <!-- Apply BannedAccessFilter to the servlet named 
      "TodaysSpecial". 
  --> 
  <filter-mapping> 
    <filter-name>BannedAccessFilter</filter-name> 
    <servlet-name>TodaysSpecial</servlet-name> 
  </filter-mapping> 
  <!-- ... --> 

  <!-- Give a name to the Today's Special servlet so that filters 
       can be applied to it. 
  --> 
  <servlet> 
    <servlet-name>TodaysSpecial</servlet-name> 
    <servlet-class> 
      moreservlets.TodaysSpecialServlet 
    </servlet-class> 
  </servlet> 
  <!-- ... --> 

  <!-- Make /TodaysSpecial invoke the servlet 
       named TodaysSpecial (i.e., moreservlets.TodaysSpecial). 
  --> 
  <servlet-mapping> 
    <servlet-name>TodaysSpecial</servlet-name> 
    <url-pattern>/TodaysSpecial</url-pattern> 
  </servlet-mapping> 

  <!-- Turn off invoker. Send requests to index.jsp. --> 
  <servlet-mapping> 
    <servlet-name>Redirector</servlet-name> 
    <url-pattern>/servlet/*</url-pattern> 
  </servlet-mapping> 

  <!-- ... --> 
</web-app> 

Listing 9.13. linker.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> 
<HTML> 
<HEAD> 
<TITLE>Link to Filter Company</TITLE> 
</HEAD> 
<BODY> 
<H2 ALIGN="CENTER">Link to Filter Company</H2> 
Click <A HREF="http://localhost/filters/TodaysSpecial">here</A> 
to see the daily special at filtersRus.com. 
</BODY> 
</HTML> 

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.222.110.183