Archive for June, 2010


When creating a Java web application that requires access restrictions on some pages, one way to do it is to include user authentication logic within each JSP, or perhaps in a JSP fragment that is included in all of these JSPs. In that code perform a redirect or forward to an access denied page.

req.getRequestDispatcher("/accessDenied.html").forward(request, response);

However, a Java web container is multi-threaded, and this merely spawns a new thread, and the server processes both the JSP and the page that has been forwarded to simultaneously. If one looks at the logging output from the server, or intercepts the HTTP traffic, using, for example, a packet sniffer (which are commonplace enough to exist as Firefox extensions), one can see this happening live. This method therefore, clearly raises some nasty security concerns.

Furthermore, from a software engineering or architectural design point of view, using a JSP as a filter violates MVC design principles, as doing so would make the JSP act as a controller as well as a view at the same time.

The proper way to go about implementing restricted access to certain pages is to use filters from the Servlet API, and then configuring the web application to map select pages to these filters. This method utilises additional capability provided by web container that runs on the server. The web container constructs filter chains based on the filter mappings defined. Most crucially, these filters allow the authentication logic and consequent branching to be executed prior to the JSP being called;

Create an abstract class `LoginFilter`.

    public abstract class LoginFilter implements javax.servlet.Filter {
        protected ServletContext servletContext
    
        public void init(FilterConfig filterConfig) {
            servletContext = filterConfig.getServletContext();
        }
    
        public void doFilter(
            ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
            HttpServletRequest req = (HttpServletRequest)request;
            HttpServletResponse resp = (HttpServletResponse)response;
        
            if (!isAuth()) {
                resp.sendError(HttpServletResponse.SC_UNAUTHORIZED);
                return; //break filter chain, requested JSP/servlet will not be executed
            }
        
            //propagate to next element in the filter chain, ultimately JSP/ servlet gets executed
            chain.doFilter(request, response);        
        }
    
        /**
         * logic to accept or reject access to the page, check log in status
         * @return true when authentication is deemed valid
         */
        protected abstract boolean isAuth();
    
    }

Subclass the `LoginFilter` as a concrete class, `MemberLoginFilter`, by implementing the `isAuth` method. In this case add logic that determines whether a user is currently logged in. This post does not cover how this is done; in a nutshell, this would typically involve retrieving objects from the current HTTP session, and determining whether a user has logged in during the current session by comparing the values or states of these objects.

Now edit the `web.xml` configuration for the web application archive (WAR), to make the web app aware of the filter and what pages it should map to.

<filter>
    <description>Requires user to log in as a member</description>
    <filter-name>MemberLoginFilter</filter-name>
    <filter-class>some.package.MemberLoginFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>MemberLoginFilter</filter-name>
    <url-pattern>/someRestrictedPage.jsp</url-pattern>
</filter-mapping>

Add as many filter mappings as necessary for each page that needs to have access to it restricted to logged-in members only; use file name globs to match multiple files.

Also, still editing `web.xml` configuration, tell the web app how to handle access denied error messages in a more user friendly way, by adding the following node to the settings:

<error-page>
    <error-code>401</error-code>
    <location>/accessDenied.html</location>
</error-page>

The HTTP 401 error code referenced here corresponds to `HttpServletResponse.SC_UNAUTHORIZED` in `LoginFilter.doFilter(..)`.
This completes the loop: when the filter chain is broken because `LoginFilter.isAuth()` returns false, instead of getting a garish HTTP 401, the user will see an access denied page instead, which you can edit to inlcude a user friendly message.

If `LoginFilter.isAuth()` returns true, the filter chain continues execution, and assuming that there are no more filters in the filter chain, or all of the downstream filters in the filter chain pass, the requested JSP or servlet gets displayed.

Advertisements

Picked up a couple of handy command line tricks at work this week, and frankly I wish I had done so much earlier. I thought, what better way to commit them to permanent memory than to post it here, so here they are.

Subversion diff ignoring whitespace

svn diff --diff-cmd /usr/bin/diff -x -bBw -r9999 > r9999.diff

Compares the local copy with a particular revision; and uses the local diff command instead of the one built into the Subversion client.

The `-x` flags that the following option (in this case `-bBw`) is for the local diff command, instead of the Subversion command.

Find files containing a particular string recursively in a directory

find . -name \*.java -exec grep -n "searchstringregex" {} /dev/null \;

Lists all files within the current directory (recursively) which match a file glob pattern, and contain at least one line that matches a regular expression. Special characters in the file glob need to be escaped (e.g. `\*.java`), and the regex should be quoted.

The purpose of including `/dev/null` is to give the `grep` command more than one input file (per iteration), to force grep to output not just the matching string, but also the file name. This would be redundant if we are lookign at just one file, however it is quite useful, and necessary, here since we are grep’ping many files at once.

find . -name \*.java -exec grep -c "searchstringregex" {} /dev/null \; | grep -v :0$

A very slight variation on the previous command, this time with the number of occurrences of the regex in each file (`-c`) instead of the contents of each matching line. The output is filtered by piping it through another `grep` to remove items with a count of zero.

Here are the resources I find most useful for Oracle SQL query optimisartion, ordered from basic to advanced.

Guide to understanding the basics of indexing and the various merges in line with their effects on execution plans

How-to manual from Oracle themselves on how to use autotrace in SQLPlus

The most complete reference on Oracle hints I’ve come across

A collection of specific, and advanced, query tuning techniques

Also, here is the 1979 seminal paper from P. Selinger of IBM, which forms the roots of access plan optimisation in most current day databases; and addresses the basic concepts that need to be taken into account when optimising queries.
Access path selection in a relational database management system


EDIT

This one here does not have anything to do directly with query optimisation, but I found that attempting to optimise queries without first understanding the algorithms behind them is a fool’s errand. So here is a great post on the basic algorithms behind nested loop join, merge join and hash join (code in C#).