Tuesday, April 21, 2009

Protecting your pages using servlet filtering

At some point in your web application development you will need to restrict access to certain pages based on login. In other words if a user goes to a protected page without logging in he/she needs to be redirected to the login page and thus enforcing security. This can be achieved using servlet filters. A servlet filter gets executed first before any JSP page is rendered and so we can check for a value of a session variable in this filter. The value is set in the login action so if a user skips login this value will not be set and so the servlet filter will throw them back to the login page. With this basic idea the implementation will be as follows.

Step1 Create a java class which implements javax.servlet.Filter


class SecurityCheckFilter implements Filter {
{
private final static String FILTER_APPLIED = "_security_filter_applied";
private List nonRestrictedPages;

/**
* This method returns true if the page is not restricted like the landing page
*/
public boolean isNonRestrictedPage(String page){
Iterator it = nonRestrictedPages.iterator();
boolean result = false;
while (it.hasNext()) {
String nonrestrictedPage = (String)it.next();
if (page.endsWith(nonrestrictedPage)) {
result = true;
break;
}
}
return result;
}

public void init(FilterConfig conf) throws ServletException {
nonRestrictedPages = new ArrayList();
// index.jsp is the landing page of the application
// and needs no logging in
nonRestrictedPages.add("index.jsp");
}
/**
* This method gets called for every jsp page before the page gets rendered
*/
public void doFilter(ServletRequest request,
ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest hreq = (HttpServletRequest)request;
HttpServletResponse hres = (HttpServletResponse)response;
HttpSession session = hreq.getSession();
String requestedSession = hreq.getRequestedSessionId();
String currentWebSession = hreq.getSession().getId();
String currentpage = hreq.getPathTranslated();

// if currentpage is null or is not a jsp page don't do any filtering
if (currentpage == null || !(currentpage.endsWith(".jsp")) ) {
if (chain != null) chain.doFilter(request, response);
return;
}

// if the page is restricted and this filter is not
// already applied do this block
if ((isNonRestrictedPage(currentpage)==false) &&
(request.getAttribute(FILTER_APPLIED) == null){

request.setAttribute(FILTER_APPLIED, Boolean.TRUE);
//If the session bean is not null get the session bean property username.
String user=null;
// This LoggedInBean is has the login information
if(((LoggedInBean)session.getAttribute("backing_loggedin_bean"))!=null) {
user = ((LoggedInBean)session.getAttribute("backing_loggedin_bean")).getUserName();
}
// if the user is not set and the current page is not
// the login page then redirect back to login page
if (user==null && (!currentpage.endsWith("login.jsp")))
{
hres.sendRedirect("login.jsp");
return;
}
}

//deliver request to next filter
if (chain!=null)
chain.doFilter(request, response);

}
}


Step2 Register your custom servlet filter class in the web.xml



<filter>
<filter-name>Security Page Filter</filter-name>
<filter-class>SecurityCheckFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Security Page Filter</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>