User Authentication (Filter/Servlet)

6

Posted on October 8, 2010 by

Share it now!

Hello, how are you?

Let’s talk today about how to control user authentication manually? To do this authentication we will be using a simple but powerful Java class: “Filter”. We will be using the code developed in the others posts about Web Applications: Creating a WebServer, Handling Exceptions on a WebApp.

I will write bellow, the code that we will be using for this Filter article. The files that will be described bellow are: one Servlet, two JSPs and a “web.xml” file (we will be able to do a Hello World Filter with these files). If you have any problem running the Web Application with the codes bellow, take a look at this article (Creating a WebServer) that will help you (with these codes bellow you will be able to run your WebServer and navigate on it).
Our project name is Servlet. The web.xml file will stay inside the folder WebContent/WEB-INF

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
    <display-name>Servlet</display-name>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>  
    </welcome-file-list>
  
    <servlet>
        <servlet-name>hello</servlet-name>
        <jsp-file>/index.html</jsp-file>
    </servlet>
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
    
    <servlet>
        <servlet-name>final</servlet-name>
        <servlet-class>com.Servlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>final</servlet-name>
        <url-pattern>/mathit</url-pattern>
    </servlet-mapping>     
</web-app>

com.Servlet.java

package com;

import java.io.IOException;

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

public class Servlet extends HttpServlet {
    public void doPost(HttpServletRequest req, HttpServletResponse res)    throws ServletException, IOException {
        int value1;
        int value2;
        int total = 0;
        String name = (String) req.getParameter("name");
        String warning = "";
        
        try {
            value1 = Integer.parseInt((String) req.getParameter("value1"));
            value2 = Integer.parseInt((String) req.getParameter("value2"));
        } catch (NumberFormatException e) {
            value1 = 0;
            value2 = 0; 
            warning = "We got some bad value(blank or non numerics values, we set 0 instead";
        }
        
        req.setAttribute("name", name);
        req.setAttribute("warning", warning);
        
        total = value1 + value2;
        
        req.setAttribute("total", total);
        
        RequestDispatcher requestDispatcher = req.getRequestDispatcher("/WEB-INF/show.jsp");
        
        requestDispatcher.forward(req, res);
    }
}

File code: /WebContent/index.html

<html>
    <body>
        <form action="/Servlet/mathit" method="post">
            <h1>Hello</h1>
            Type your name: <input type="text" name="name"/> <br/><br/>
            Lets do some math?<br/>
            Type the first value to be added: <input type="text" name="value1"/> <br/>
            Type the second value to be added: <input type="text" name="value2"/> <br/><br/>
            <input type="submit" value="Do some math"/>
        </form>
    </body>
</html>

File code: /WebContent/WEB-INF/show.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <body>
        Thanks ${name} for passing by. <br/>
        The total is: ${total}. <br/>
        
        <br/>${warning}
    </body>
</html>

To access the application, start the Tomcat and access through the address http://localhost:8080/Servlet/hello.

Filter is a Java class able to intercept requests done by a client; you just have to map a request pattern (as URL, Servlet, etc). To start with it, let’s create a Filter class and put it to work.
That’s how our Filter code class will be:

package com;

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;

/**
 * Servlet Filter implementation class UserCheckFilter
 */
public class UserCheckFilter implements Filter {
    /**
     * @see Filter#init(FilterConfig)
     */
    public void init(FilterConfig fConfig) throws ServletException {
    }

    /**
     * @see Filter#destroy()
     */
    public void destroy() {
    }

    /**
     * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
     */
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

        System.out.println("Hello World");
        
        chain.doFilter(request, response);
    }
}

The init and destroy methods belongs to the Filter interface and they must be implemented. In this sample code we are just printing “Hello World”, we need to be sure that our Filter class is being invoked.

We must add some Filter tags to our web.xml file.

<filter>
    <filter-name>UserCheckFilter</filter-name>
    <filter-class>com.UserCheckFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>UserCheckFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

About the tags: “url-pattern” it tells witch url address we are mapping, and in our sample we are catching any requested url. “filter-name” defines the Filter name that will be invoked.

Start the Tomcat and access the application through the link: http://localhost:8080/Servlet/hello (If you still have some trouble accessing the first page of our tutorial, visit this link to clear your doubts: Creating a WebServer).
Look at the Console to see our message there:
Hello World Screen

With our Filter already working, let’s create a User class. A simple POJO with name and password as it attributes. Our class will be like this:

package com;

public class User {
    private String name = "UNKNOW";
    private String password = "UNKNOW";
    
    public User(String name, String password){
        this.name = name;
        this.password = password;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
}

We need a Servlet to do the user authentication, let’s create it to validate the user name and the password. We will do this validation in our Servlet and we will not worry about patterns.

package com;

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

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

public class UserValidator extends HttpServlet {
    private static final Map users = getUsers();
    
    /**
     * Creates valid users 
     * 
     * This User Map could be users returned from a database
     * or a simple select with the user.name
     * 
     * @return a Map of valid users
     */
    private static Map getUsers() {
        Map users = new HashMap();
        
        User userOne = new User("one","one");
        User userTwo = new User("two","TWO");
        
        users.put(userOne.getName(), userOne);
        users.put(userTwo.getName(), userTwo);
        
        return users;
    }

    public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
        doPost(req, res);
    }

    public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
        RequestDispatcher rd;
        String name = req.getParameter("name");
        String password = req.getParameter("password");
    
        User user = validateLogin(name, password);
        
        if (user == null){
            rd = req.getRequestDispatcher("/loginError.jsp");
        }
        else{
            HttpSession session = req.getSession();
            session.setAttribute("user", user);
            rd = req.getRequestDispatcher("/loginSuccess.jsp");
        }
        
        rd.forward(req, res);
    }

    /**
     * Validate the entered data
     * 
     * If there is no valid data, the method will return null
     * 
     * @param name given at the jsp
     * @param password given at the jsp
     * @return a user if one was found and validated
     */
    private User validateLogin(String name, String password) {
        // All parameters must be valid
        if (name == null || password == null){
            return null;
        }
        
        // Get a user by key
        User user = users.get(name);
        
        if (user == null){
            return null;
        }
        
        // Check if the password is valid
        if (!user.getPassword().equals(password.trim())){
            return null;
        }
        
        return user;
    }
}

The map “users” and the method “getUsers” exists only to create valid users. If our user is not validated the method “validateLogin” will return a null value. If the user entered a valid data, he will be redirected to a login success page otherwise he will be redirected to an error page.

We need to edit the “web.xml” file and add the Servlet mapping that we just created:

<servlet>
    <servlet-name>userValidator</servlet-name>
    <servlet-class>com.UserValidator</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>userValidator</servlet-name>
    <url-pattern>/userValidator</url-pattern>
</servlet-mapping>

We have to create three JSP files: login, login error and login success.
/WebContent/login.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
        <title>Login</title>
    </head>
    <body>
        <form action="/Servlet/userValidator" method="post">
            Name: <input type="text" name="name"/>
            Password: <input type="password" name="password"/>
            <input type="submit" value="LogIn"/>
        </form>
    </body>
</html>

/WebContent/loginError.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
        <title>Error</title>
    </head>
    <body>
        Wrong user/password
    </body>
</html>

/WebContent/loginSuccess.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
        <title>Success</title>
    </head>
    <body>
        You have loged in.
    </body>
</html>

Let’s change our Filter file. This change will be very delicate, this code change will be responsible to determine if our user will be able to keep on in his request or not.

package com;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

/**
 * Servlet Filter implementation class UserCheckFilter
 */
public class UserCheckFilter implements Filter {
    private String LOGIN_ACTION_URI;
    
    /**
     * @see Filter#init(FilterConfig)
     */
    public void init(FilterConfig fConfig) throws ServletException {
        LOGIN_ACTION_URI = fConfig.getInitParameter("loginActionURI");
    }

    /**
     * @see Filter#destroy()
     */
    public void destroy() {
    }

    /**
     * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
     */
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpSession session = req.getSession();
        User user = (User) session.getAttribute("user");
        
        if (user == null && !LOGIN_ACTION_URI.equals(req.getRequestURI())){
            RequestDispatcher rd = req.getRequestDispatcher("/login.jsp");
            rd.forward(request, response);
            return;
        }
        
        chain.doFilter(request, response);
    }
}

Some details about the code above: “req.getSession()” – returns the user session, if there is no session the container will be responsible to create one. We get inside the session a User object, remember that in our Servlet when the user does the login we insert into the session a User object. If there is no User object in the session, the returned value will be null, and we redirect the user to the login jsp. We have in the code above too an attribute named LOGIN_ACTION_URI. This value is returned from the filter configurations, it will be configured in the web.xml very soon. We created the LOGIN_ACTION_URI just to be sure that if the user is trying to validate its login, he does not get stuck in the login jsp.

Now we just have to edit the “web.xml” and add our filter attribute there:

<filter>
    <filter-name>UserCheckFilter</filter-name>
    <filter-class>com.UserCheckFilter</filter-class>
    <init-param>
        <param-name>loginActionURI</param-name>
        <param-value>/Servlet/userValidator</param-value>
    </init-param>
</filter>

When we access the link http://localhost:8080/Servlet/hello, the user will be redirected to the login page. After the user type a valid name/password, it will have the session validated. It will be no longer needed to do this validation.

If you have any doubt, or question just post it.
See you soon.

Response to User Authentication (Filter/Servlet)

    • uaihebert Post author

      Hello Madhava,

      If you follow all the steps of this post, you will be able to run it.

      I do not have the project file, this post was written a long time ago. [=

      Thanks for passing by.

Leave a Reply

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Current day month ye@r *