Extending Servlet Code

Servlet Filters in the VSM

Access Control Filter

The Virtual Shopping Mall (VSM) controls access to application features by displaying user interfaces based on user roles. For example, shop owners can access pages that enable them to upload files, but mall customers cannot. The VSM applies a filter to process user requests and return the appropriate pages. Using filters, you can add this kind of access control to a JSP-based application without touching the existing code.

This filter-based access control model is flexible, too, because the data that maps user roles to specific JSPs is stored in a text file. As a result, you can modify mappings and leave the application in place—there's no need to recompile or redeploy. The listing below shows the contents of uiaccesscontroller.properties, the text file that maps user roles to JSPs for the VSM.

# Home page URI for each role
admin.HOME=/adminMainPage
owner.HOME=/ownerMainPage
user.HOME=/main
DEFAULT.LOGIN=/vsmlogin # Header/footers JSP for each role
admin.HEADER=../misc/adminHeader.jsp
owner.HEADER=../misc/ownerHeader.jsp
DEFAULT.HEADER=../misc/userHeader.jsp
user.HEADER=../misc/userHeader.jsp
admin.FOOTER=../misc/adminFooter.jsp
owner.FOOTER=../misc/adminFooter.jsp
DEFAULT.FOOTER=../misc/commonFooter.jsp
user.FOOTER=../misc/commonFooter.jsp # Navigation JSP for each role
admin.NAVIGATION=../mallAdmin/leftNavigation.jsp
owner.NAVIGATION=../shopOwner/leftNavigation.jsp

The VSM reads from the mapping file when the Access Control filter is initialized, and uses helper classes UIController and URIMapping to access the data (you can view the source code online). Here is a portion of the Java code for the AccessControlFilter class. The init method gets an instance of the UIController class, and the doFilter method calls an internal method named checkPrivileges (a listing follows) to do the main processing for the filter.

...
  // Interface to the uiaccesscontroller.properties file
private UIController uiController = null; ...
public void init( FilterConfig config )
throws ServletException {
this.filterConfig = config;
this.uiController = UIController.getInstance();
} ...
public void doFilter( ServletRequest request,
ServletResponse response,
FilterChain chain )
throws IOException, ServletException {
try {
// checkPrivileges also uses the uiController attribute // initialized in the init method. checkPrivileges( request, response, chain );
} catch( Exception ex ) {
throw new ServletException("Error in the doFilter method of "+
"AccessControlFilter class of given status"+
ex.getMessage() );
}
}
...

Here is the Java code for AccessControlFilter.checkPrivileges. This method does the "heavy lifting" for the filter. After getting the user's role and the URL of the requested page, then checks these values against the mapping data. If the requested page is appropriate for the user's role, the code calls chain.doFilter to invoke the page and continue with normal processing. Otherwise, the code displays an alternate JSP (for example, to prompt the user to log in), then returns. The code does not call chain.doFilter in such cases, because the user does not have sufficient privileges to view the requested JSP.

...
 /**
* Private helper method to check the access controls
* @param <b>request</b> The servlet request object
* @param <b>response</b> The servlet response object
* @param <b>chain</b> Object representing the chain of all filters
* @throws <b>Exception</b> If there was an error while checking the
* role privileges
*/
private void checkPrivileges( ServletRequest request,
ServletResponse res,
FilterChain chain )
throws Exception {
HttpServletRequest req = (HttpServletRequest)request;
// Get the session object from the request
HttpSession session = req.getSession();
// Get the uri information from the request
String uri = req.getPathInfo();
// Get the role of the user
String role = (String)session.getAttribute( "role" );
if( role == null ) {
role = "DEFAULT";
}
// Set the header and footer for default user
req.setAttribute( "Header", uiController.getUI( role, "HEADER" ) );
req.setAttribute( "Footer", uiController.getUI( role, "FOOTER" ) );
try {
req.setAttribute( "Navigation", uiController.getUI( role, "NAVIGATION" ) );
} catch( Exception ex ) {
// If no navigation for this role, skip it
}
URIMapping info = RequestMap.getInstance().getURIMapping( uri );
// The URI is protected because it has a set of roles associated with it
if( info.getRoles() != null && info.getRoles().length > 0 ) {
// New session so not logged in yet. Redirect to login page
if( session.isNew() ) {
Hashtable data = new Hashtable( req.getParameterMap() );
// Set the attribute for session and request
session.setAttribute( "_userData", data );
req.setAttribute( "Originator", uri );
// Create the RequestDispatcher
RequestDispatcher rd = filterConfig.getServletContext().
getRequestDispatcher( "/" + RequestMap.
getInstance().getJsp(
uiController.getUI( role, "LOGIN" ) ) );
rd.forward( req, res );
return ;
} else {
// If not valid, redirect to login page
if( !info.isValidRole( role ) ) {
Hashtable data = new Hashtable( req.getParameterMap() );
// Set the attribute for session and request
session.setAttribute( "_userData", data );
req.setAttribute( "Originator", uri );
// Create the RequestDispatcher
RequestDispatcher rd = filterConfig.getServletContext().
getRequestDispatcher( "/" + RequestMap.
getInstance().getJsp(
uiController.getUI( "DEFAULT", "LOGIN" ) ) );
rd.forward( req, res );
return ;

}
}
}
// The privileges are sufficient to invoke this URI,
// continue normal processing of the request.
chain.doFilter( req, res );

}...

Conclusion

By adding servlet filters to your bag of developer tricks, you can customize, enhance, and extend Web applications without modifying existing code. The VSM sample application shows just a few of the ways you can implement and use filters. Other possibilities include logging and auditing, image conversion, data compression, localization, and XSL transformations of XML documents.

To learn more about the VSM, see Design Patterns in the VSM.

< Back to Introduction

Questions or comments? Post a message in the OTN Sample Code discussion forum or send email to the author.

Extending Servlet Code: Servlet Filters in the VSM
Author: Robert Hall, Oracle Corporation
Date: June 2002

This document is provided for information purposes only and the information herein is subject to change without notice. Please report any errors herein to Oracle Corporation. Oracle Corporation does not provide any warranties covering and specifically disclaims any liability in connection with this document.
Oracle is a registered trademark and Enabling the Information Age is a trademark or registered trademark of Oracle Corporation. All other company and product names mentioned are used for identification purposes only and may be trademarks of their respective owners.

Oracle

Oracle Corporation
World Headquarters
500 Oracle Parkway
Redwood Shores, CA 94065
U.S.A.

Worldwide Inquiries:
+1.650.506.7200


E-mail this page
Printer View Printer View
Oracle Is The Information Company About Oracle | Oracle RSS Feeds | Careers | Contact Us | Site Maps | Legal Notices | Terms of Use | Privacy