Recipe11.6.Ensuring Security Across Your Entire Application


Recipe 11.6. Ensuring Security Across Your Entire Application

Problem

You need to verify the user is logged in and authenticated when a request is received for any URL path of your web application.

Solution

Use an authentication servlet filter, such as the one in Example 11-10, which checks for a User object in the session.

Example 11-10. A servlet filter that checks if the user is logged in
package com.oreilly.strutsckbk.ch11.ams; import java.io.IOException; 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 javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; public class AuthenticationFilter implements Filter {     private String onFailure = "logon.jsp";     private FilterConfig filterConfig;          public void init(FilterConfig filterConfig) throws ServletException {         this.filterConfig = filterConfig;         onFailure = filterConfig.getInitParameter("onFailure");     }         public void doFilter(ServletRequest request,                        ServletResponse response,                        FilterChain chain)                   throws IOException, ServletException {         HttpServletRequest req = (HttpServletRequest) request;         HttpServletResponse res = (HttpServletResponse) response;                  // if the requested page is the onFailure page continue         // down the chain to avoid an infinite redirect loop                 if (req.getServletPath( ).equals(onFailure)) {             chain.doFilter(request, response);             return;         }                  // get the session or create it         HttpSession session = req.getSession( );          User user = (User) session.getAttribute("user");         if (user == null) {             // redirect to the login page              res.sendRedirect(req.getContextPath( )+onFailure);         }         else {             chain.doFilter(request, response);         }     }     public void destroy( ) {     } }

This filter assumes that a separate Action authenticates the user and creates the User object.


Discussion

Servlet filters provide a convenient way to apply across-the-board processing of a servlet request. Servlet filters were introduced in the Servlet 2.3 specification. Most all containers support Servlet 2.3, so you can probably use them in your application. The filter looks for a User object from the HttpSession. If the object is found, then processing continues normally. If the object isn't found, then a redirect to the page specified by the onFailure initialization parameter is sent in the response.

You create a filter by implementing the Filter interface, declare the filter in your web.xml file, and map URLs to it using URL patterns (see the Sidebar 11-1). In Example 11-11, the filter is declared by the filter element. The init-param element specifies the context-relative path of the URL to redirect if authentication fails.

Example 11-11. Filter declaration and mapping (partial)
<filter>     <filter-name>AuthenticationFilter</filter-name>     <filter-class>          com.oreilly.strutsckbk.ch11.ams.AuthenticationFilter     </filter-class>     <init-param>         <param-name>onFailure</param-name>         <param-value>/logon.jsp</param-value>     </init-param> </filter> <filter-mapping>     <filter-name>AuthenticationFilter</filter-name>     <url-pattern>/reg/*</url-pattern>   </filter-mapping>

The value of the url-pattern in the filter-mapping determines the URLs to be filtered. In this case, the filter mapping indicates users must be logged in before they can access a URL that matches the url-pattern /reg/*. URLs that match this pattern include /reg/Main.do, /reg/viewReg.jsp, /reg/help.html, and /reg/sub/viewSub.jsp.

Understanding URL Patterns

URL patterns, known as URL mappings, are dictated by the Java Servlet specification. The types of patterns you can use aren't as broad as you might think. Four patterns are searched in the following order:


Explicit mappings

A complete context-relative path; no wildcards are used, for example, /add.jsp or /admin/remove.do.


Path prefix mappings

Contains a / followed by a path prefix and then /*. This pattern can be used to specify an entire sub-branch of your web applicationfor example, /admin/* or /search/company/*.


Extension mappings

A *. followed by an extension. This mapping can be used to specify all files of a certain type (e.g., *.jsp or *.do).


Default mapping

Use a slash followed by an asterisk (/*) to match all URLs for a web application.

As you can tell, these patterns can be inflexible. You can't, for example, specify a pattern of /add.*. For security-related filters, locating URLs requiring authentication in a separate subfolder(s) allows you to use path-prefix mapping. Otherwise, you would have to add an explicit mapping to the web.xml each time you added a protected action or JSP.


See Also

Recipe 11.7 shows a servlet filter that authenticates using cookies. Recipe 11.8 presents a servlet filter that can be used for authorization.

Recipe 11.10 shows how to use the open source SecurityFilter software for providing functionality similar to the filter presented in this recipe.

Java Servlet Programming by Jason Hunter (O'Reilly) covers servlet filters in-depth. Sun's Java site has a good article on the essentials of servlet filters. It can be found at http://java.sun.com/products/servlet/Filters.html.



    Jakarta Struts Cookbook
    Jakarta Struts Cookbook
    ISBN: 059600771X
    EAN: 2147483647
    Year: 2005
    Pages: 200

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