Restricting Access with Filters


Filters give you control both before and after a user accesses a Web resource on Java-enabled servers. Usually, you get a direct connection between the browser and a Web resource such as an HTML page, Java servlet, or JSP page:

  --------------          -------------- |              |        |   Web        | |              |------->|   resource   | |    browser   |        |   (HTML page,| |              |<-------|   servlet,   | |              |        |   JSP, etc.) |  --------------          --------------

However, filters you install get control before and after the Web resource gets a chance to respond:

  --------------          --------------          -------------- |              |        |              |        |   Web        | |              |------->|              |------->|   resource   | |    browser   |        |   filter     |        |   (HTML page,| |              |<-------|              |<-------|   servlet,   | |              |        |              |        |   JSP, etc.) |  --------------          --------------          --------------

That makes filters very useful in restricting access to Web resources in Ajax applications. Here’s an example, password.html, which restricts access based on a password. This application starts by displaying a password field and asking users to enter their password-note that the button passes the name of the JSP page to call, password.jsp, to the getData function:

 <body>   <H1>Using a filter for authentication</H1>   <form>     Enter your password:     <input type = "password" name="password">     <br>     <br>     <input type = "button" value = "Get the message"       onclick = "getData('password.jsp', 'targetDiv')">   </form>   <div >     <p>The fetched message will appear here.</p>   </div> </body>

The getData function uses the POST method to access password.jsp, sending the password to the server as the parameter named password:

 <html>    <head>      <title>Using a filter for authentication</title>      <script language = "javascript">       var XMLHttpRequestObject = false;        if (window.XMLHttpRequest) {         XMLHttpRequestObject = new XMLHttpRequest();       } else if (window.ActiveXObject) {         XMLHttpRequestObject = new            ActiveXObject("Microsoft.XMLHTTP");       }       function getData(dataSource, divID)        {          if(XMLHttpRequestObject) {           var obj = document.getElementById(divID);            XMLHttpRequestObject.open("POST", dataSource);            XMLHttpRequestObject.setRequestHeader('Content-Type',              'application/x-www-form-urlencoded');            XMLHttpRequestObject.onreadystatechange = function()            {              if (XMLHttpRequestObject.readyState == 4 &&                XMLHttpRequestObject.status == 200) {                  obj.innerHTML =                     XMLHttpRequestObject.responseText;              }            }            XMLHttpRequestObject.send("password=" +              document.getElementById("password").value);          }       }     </script>   </head> 

The password.jsp file is a simple one, simply displaying a welcoming message:

 <html>     <head>         <title>Filters And User Authentication</title>     </head>     <body>         Congratulations, you're in!         <br>     </body> </html>

If this were all there were to the story, users would get in every time, no matter what password they entered:

  --------------          -------------- |              |        |              | |              |------->|              | |    browser   |        | password.jsp | |              |<-------|              | |              |        |              |  --------------          --------------

This is where the filter, named PasswordFilter here, comes in, because it’s inserted between the browser and password.jsp:

  --------------          --------------          -------------- |              |        |              |        |              | |              |------->|              |------->|              | |    browser   |        |PasswordFilter|        | password.jsp | |              |<-------|              |<-------|              | |              |        |              |        |              |  --------------          --------------          --------------

The PasswordFilter filter is supported with a Java file, PasswordFilter.java, which starts by importing the Java packages it’s going to use:

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

To create a Java-enabled filter class, you must implement the Filter interface:

 import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public final class PasswordFilter implements Filter {     .     .     . } 

To implement the Filter interface, you must add three methods: doFilter, init, and destroy:

 import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public final class PasswordFilter implements Filter  {   public void doFilter(ServletRequest request, ServletResponse      response,     FilterChain chain)     throws IOException, ServletException    {         .         .         .   }   public void destroy()    {    }   public void init(FilterConfig filterConfig)    {   } }

In the doFilter method, you need to check the password before letting the user access pass-word.jsp. You can get the password this way, using the request object’s getParameter method:

 import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public final class PasswordFilter implements Filter {   public void doFilter(ServletRequest request, ServletResponse     response,     FilterChain chain)     throws IOException, ServletException   {     String password = ((HttpServletRequest)       request).getParameter("password");         .         .         .   }   public void destroy()   {   }   public void init(FilterConfig filterConfig)   {   } }

If the password is correct-say, opensesame-then you can pass control on to password.jsp, which returns the welcome message that the Ajax application displays.

You can pass control on to password.jsp by connecting the filter to that JSP page in the web.xml file, which is in the Tomcat WEB-INF directory. This directory is a subdirectory of the chap16 directory, which itself is in the Tomcat webapps directory:

 webapps   |   |__chap16        |        |__WEB-INF            |  |            |  |__web.xml            |            |__classes            |            |__lib

Here’s what web.xml looks like now:

 <?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/j2ee/dtds/web-app_2_3.dtd"> <web-app> </web-app>

The goal is to connect the compiled PasswordFilter.java file, which is named PasswordFilter.class, to password.jsp. You start by giving the new filter a name, like Authentication, and connecting it to the .class file PasswordFilter.class:

 <?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/j2ee/dtds/web-app_2_3.dtd"> <web-app>   <filter>     <filter-name>Authentication</filter-name>     <filter-class>PasswordFilter</filter-class>   </filter>         .         .         . </web-app> 

Then you connect that new filter to password.jsp:

 <?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/j2ee/dtds/web-app_2_3.dtd"> <web-app>   <filter>     <filter-name>Authentication</filter-name>     <filter-class>PasswordFilter</filter-class>   </filter>   <filter-mapping>     <filter-name>Authentication</filter-name>     <url-pattern>/password.jsp</url-pattern>   </filter-mapping> </web-app>

That inserts PasswordFilter as a filter on password.jsp, which means that in PasswordFilter.java, you can pass control on to password.jsp by calling the doFilter method of the chain object, passed to the doFilter method in PasswordFilter.java:

 import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public final class PasswordFilter implements Filter {   public void doFilter(ServletRequest request, ServletResponse     response,     FilterChain chain)     throws IOException, ServletException   {     String password = ((HttpServletRequest)       request).getParameter("password");     if(password.equals("opensesame")) {         chain.doFilter(request, response);     }         .         .         .   }   public void destroy()   {   }   public void init(FilterConfig filterConfig)   {   } }

On the other hand, if the password was not correct, you need some way of sending an error message back to the browser. You start that process by setting the response object’s content type header to text/html-the response object is what will be sent back to the browser, so this tells the browser you’re sending back a text-based response. You can also get a PrintWriter object, out, which is what you’ll use to place text in the response object:

 import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public final class PasswordFilter implements Filter {   public void doFilter(ServletRequest request, ServletResponse     response,     FilterChain chain)     throws IOException, ServletException   {     String password = ((HttpServletRequest)       request).getParameter("password");     if(password.equals("opensesame")) {         chain.doFilter(request, response);     }     else {         response.setContentType("text/html");         PrintWriter out = response.getWriter();         .         .         .     }   }   public void destroy()   {   }   public void init(FilterConfig filterConfig)   {   } }

Now you can use the out object’s println method to display HTML in the browser indicating that the password was incorrect:

  import java.io.*;  import javax.servlet.*;  import javax.servlet.http.*;  public final class PasswordFilter implements Filter  {    public void doFilter(ServletRequest request, ServletResponse      response,      FilterChain chain)      throws IOException, ServletException    {      String password = ((HttpServletRequest)        request).getParameter("password");      if(password.equals("opensesame")) {          chain.doFilter(request, response);      }      else {          response.setContentType("text/html");          PrintWriter out = response.getWriter();          out.println("<html>");          out.println("<head>");          out.println("<title>");          out.println("Incorrect Password");          out.println("</title>");          out.println("</head>");          out.println("<body>");          out.println("<H1>Incorrect Password</H1>");          out.println("Sorry, that password was incorrect.");          out.println("</body>");          out.println("</html>");      }    }    public void destroy()    {    }    public void init(FilterConfig filterConfig)    {    }  }

To compile PasswordFilter.java, you need to make either servlet.jar or servlet-api.jar, depending on your version of Tomcat, accessible to Java. You’ll find this .jar file-either servlet.jar or servlet-api.jar-in Tomcat’s common\lib directory. You can copy that .jar file to the directory in which you’re copying PasswordFilter.java and add the .jar file to the classpath environment variable. That works like this in Windows:

 set classpath=servlet.jar

If you don’t want to copy the .jar file to the directory in which you’re compiling PasswordFilter.java, you can give the fill path to the .jar file like this:

 set classpath=C:\[Tomcat path including version]\coom\lib\servlet.jar

Next, you compile PasswordFilter.java using the Java compiler tool, javac:

 javac PasswordFilter.java

If javac is not in your path, you have to give the path to it, something like this in Windows (change this path to match your Java installation-the javac tool is in the Java installation’s bin directory):

 C:\jdk\bin\javac PasswordFilter.java

That compiles PasswordFilter.java and creates PasswordFilter.class, which is what you want.

The PasswordFilter.class file should be placed in the webapps\chap16\WEB-INF\classes directory, like this, to make it accessible to the server:

 webapps   |   |__chap16        |        |__WEB-INF            |  |            |  |__web.xml            |            |__classes            |  |            |  |__PasswordFilter.class            |            |__lib

That sets up the application. Now you should restart Tomcat if you’re working with a local installation of that server (you should restart Tomcat if you’ve changed an XML file and/or added a .class file-you can configure Tomcat to notice if you’ve made such changes, but it doesn’t do so by default).

The password.html page is shown in Figure 16.1.

image from book
Figure 16.1: The password.html page

If you enter the wrong password, it’s sent to password.jsp using Ajax techniques. But the filter, PasswordFilter, intercepts that password and returns an error message, as shown in Figure 16.2.

image from book
Figure 16.2: An incorrect password

On the other hand, if you enter the right password, a welcoming message appears, as shown in Figure 16.3.

image from book
Figure 16.3: Using the right password

As you can see, filters work even when you’re using an XMLHttpRequest object.



Ajax Bible
Ajax Bible
ISBN: 0470102632
EAN: 2147483647
Year: 2004
Pages: 169

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net