Skip navigation

Tag Archives: Servlet Filter

Servlet Filter can be used to preprocess Web application requests, therefore we can used it to secure our websites. If your web application need someone to login first before he/she can browse to another page, servlet filter can be used in such cases. Below will show how to use servlet filter to secure a web application.

Servlet filter is an interface on package javax.servlet.Filter that have three methods: init, doFilter, and destroy. We have to make our own filter class and implements Filter interface. This is the filter class called HelloFilter:

(com.halimun.filter.HelloFilter.java)

package com.halimun.filter;

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.HttpSession;

public class HelloFilter implements Filter {
	private FilterConfig filterConfig;
	private String loginForm;
	
	// init
	public void init(FilterConfig filterConfig) throws ServletException {
		this.filterConfig = filterConfig;
		loginForm = this.filterConfig.getInitParameter("login_form");
	}
	
	// doFilter
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest httpRequest = (HttpServletRequest) request;
		HttpSession session = httpRequest.getSession(false);
		
		if( session != null ) {
			String currentUser = (String)session.getAttribute("user");
			if (currentUser == null) {
				System.out.println("currentUser null");
				filterConfig.getServletContext().getRequestDispatcher(loginForm).forward(request, response);
			}
		
		}
		else{
			filterConfig.getServletContext().getRequestDispatcher(loginForm).forward(request, response);
		}

		chain.doFilter(request,response);

	}

	// destroy
	public void destroy() {}

}

The UserLogin action servlet is invoke when user press submit button at login form. It’s check wether user is exist in databases and match the password. Acctually it’s only dummy database, I use HashMap to store username (as the key) and password.

(com.halimun.servlet.UserLogin)

package com.halimun.servlet;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class UserLogin extends HttpServlet {
	private static final long serialVersionUID = -3955012280873977969L;
	private static final Map<String, String> users = new HashMap<String, String>();
	
	public void init() throws ServletException {
		users.put("admin", "secret");
		users.put("david", "password");
		users.put("gardiary", "gardiary");
	}
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
		throws ServletException, IOException 
	{
		execute(request, response);
	}
	
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
		throws ServletException, IOException
	{
		execute(request, response);
	}
	
	private void execute(HttpServletRequest request, HttpServletResponse response)
		throws ServletException, IOException 
	{
		String username = request.getParameter("username");
		String password = request.getParameter("password");
		
		String userPassword = users.get(username);
		
		if(userPassword!=null && userPassword.equals(password)) {
			request.getSession().setAttribute("user", username);
			response.sendRedirect( request.getContextPath() );
		}
		else {
			request.setAttribute("message", "Invalid username or password");
			getServletContext().getRequestDispatcher("/loginForm.jsp")
				.forward(request, response);
		}
	}
}

UserLogout action servlet is for logout from the application, it’s remove the session and redirect to login form.

(com.halimun.servlet.UserLogout.java)

package com.halimun.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class UserLogout extends HttpServlet {
	private static final long serialVersionUID = 5073946739765619794L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
	throws ServletException, IOException 
	{
		execute(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
	throws ServletException, IOException
	{
		execute(request, response);
	}

	private void execute(HttpServletRequest request, HttpServletResponse response)
	throws ServletException, IOException 
	{
		request.getSession().invalidate();
		response.sendRedirect( request.getContextPath() );
	}
}

Here is login form using JSP. We can see that the form action is “userlogin.action” which is a UserLogin action servlet.

(loginForm.jsp)

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link href="css/format.css" rel=stylesheet type="text/css">
<title>Login Form</title>
</head>
<body>
<form method="POST" action="userlogin.action">
	<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse">
		<tr>
			<td>Username :</td>
			<td><input type="text" name="username"></td>
		</tr>
		<tr>
			<td>Password :</td>
			<td><input type="password" name="password"></td>
		</tr>
		<tr>
			<td>&nbsp</td>
			<td><b>
				<%= (request.getAttribute("message")==null ? "&nbsp" : request.getAttribute("message")) %>
			</b></td>
		</tr>
		<tr>
			<td colspan="2" align="center">
				<input type="submit" value="Login">
				<input type="reset" value="Cancel">
			</td>
		</tr>
   </table>
</form>
<br>
<a href="index.jsp">index page</a> - <a href="error.jsp">error page</a> - 
<a href="dummy.jsp">dummy page</a>
</body>
</html>

Index.jsp is default page after user has succeed login. You can make another pages to check if the security is working.

(index.jsp)

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link href="css/format.css" rel=stylesheet type="text/css">
<title>Index Page</title>
</head>
<body>
	<h2>Heloooo <%= session.getAttribute("user") %>...</h2>
	<br>
	<a href="error.jsp">error page</a> - <a href="dummy.jsp">dummy page</a> - 
	<a href="loginForm.jsp">login form</a>- <a href="userlogout.action">logout</a>
</body>
</html>

And here is the web.xml:

<?xml version="1.0" encoding="UTF-8"?>

<web-app>
	<description>Web Application Security</description>
	<display-name>Web Application Security</display-name>

	<filter>
		<filter-name>HelloFilter</filter-name>
		<filter-class>com.halimun.filter.HelloFilter</filter-class>
		<description>
			This Is Hello Filter
		</description>
		<init-param>
			<param-name>login_form</param-name>
			<param-value>/loginForm.jsp</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>HelloFilter</filter-name>
		<url-pattern>*.jsp</url-pattern>
	</filter-mapping>
	
	<servlet>
		<servlet-name>userlogin</servlet-name>
		<description>User Login Controller</description>
		<servlet-class>com.halimun.servlet.UserLogin</servlet-class>
	</servlet>
	<servlet>
		<servlet-name>userlogout</servlet-name>
		<description>User Logout Controller</description>
		<servlet-class>com.halimun.servlet.UserLogout</servlet-class>
	</servlet>
	
	<servlet-mapping>
		<servlet-name>userlogin</servlet-name>
		<url-pattern>/userlogin.action</url-pattern>
	</servlet-mapping>
	<servlet-mapping>
		<servlet-name>userlogout</servlet-name>
		<url-pattern>/userlogout.action</url-pattern>
	</servlet-mapping>
	
	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>
</web-app>

<filter-mapping>
   <filter-name>HelloFilter</filter-name>
   <url-pattern>*.jsp</url-pattern>
</filter-mapping>

This mapping means that request to every JSP file will be filtered first, in this case will invoke HelloFilter filter. HelloFilter filter will be processes before and after run the JSP’s files.
Acctually we can mapped filter to every requests by specifying “/*” in url-pattern of filter-mapping. In that case, every request to every resources (such as *.action, *,css, *.js, etc) will also invoke the filter.

<servlet-mapping>
   <servlet-name>userlogin</servlet-name>
   <url-pattern>/userlogin.action</url-pattern>
</servlet-mapping>
<servlet-mapping>
   <servlet-name>userlogout</servlet-name>
   <url-pattern>/userlogout.action</url-pattern>
</servlet-mapping>

In this servlet mappings, we mapped UserLogin action servlet with url-pattern “/userlogin.action” and UserLogout action servlet with url-pattern “/userlogout.action“.

Summary

So the web application structure will look like this:

[ContextRoot]\index.jsp
[ContextRoot]\loginForm.jsp
[ContextRoot]\error.jsp
[ContextRoot]\dummy.jsp
[ContextRoot]\css\format.css
[ContextRoot]\WEB-INF
[ContextRoot]\WEB-INF\classes\com\halimun\filter\HelloFilter.class
[ContextRoot]\WEB-INF\classes\com\halimun\servlet\UserLogin.class
[ContextRoot]\WEB-INF\classes\com\halimun\servlet\UserLogout.class

Complete source code is this, change the extention to .war (coz free wordpress doesnt support WAR files 😦 ), then deploy in your favorite application server. Try to access error page or dummy page without entering username/password in login form. For login account, you can use admin/secret, david/password, or gardiary/gardiary.

Advertisements