-2

I'm working on a simple login servlet in which the user enters his email and password which are stored in a text file(I can't use a database) ,if the credentials are correct then the user will be redirected to a weclome jsp page if not correct then to a fail login jsp page , the problem that I'm facing is that I'm always getting redirected to the login fail page even though I'm checking if the email and password are in the text file and are correct

I'm using Tomcat 10

So the text file looks like this :

  • example1@gmail.com,awesome100
  • example2@hotmail.hotmail.com,cool009

the email and password are seperated by a ','

Here's the Code :

package com.example.try8;

import java.io.*;
import java.security.Principal;
import java.util.HashMap;
import java.util.Map;

import jakarta.servlet.ServletConfig;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

@WebServlet("/HelloServlet")
public class HelloServlet extends HttpServlet {

/**
 *
 */
private static final long serialVersionUID = -5498866193863633001L;

/**
 * HashMap to store all users credentials
 */
private final Map<String, String> credentialsPairs = new HashMap<> 
();

@Override
public void init(ServletConfig config) throws ServletException {
    String delimiter = ",";
    String line = "";

    /**
     * Credentials file will be there in WEB-INF directory as it 
provide secured
     * access only.
     */
    String credentialFile = "/WEB-INF/accounts.txt";

    /**
     * Read the file and prepare Map with username as key and 
    password as value We
     * have put this code in init method as it is called once only 
    that will avoid
     * overhead of iterating values from file for each request
     */
    InputStream is = null;
    InputStreamReader isr = null;
    BufferedReader br = null;

    ServletContext context = config.getServletContext();

    try {
        /**
         * Open stream of file
         */
        is = context.getResourceAsStream(credentialFile);
        if (is != null) {
            /**
             * Read the file line by line and store email as a key 
      and password as value
             */
            isr = new InputStreamReader(is);
            br = new BufferedReader(isr);
            while ((line = br.readLine()) != null) {
                String[] credentials = line.split(delimiter);
                // credentials[0] is email and credentials[1] is 
          password
                credentialsPairs.put(credentials[0], 
       credentials[1]);
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            if (br != null) {
                br.close();
            }
            if (isr != null) {
                isr.close();
            }
            if (is != null) {
                is.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    }

public void doGet(HttpServletRequest request, HttpServletResponse 
  response) throws IOException {
    /**
     * Get user entered credentials
     */
    String userEmail = request.getParameter("email");
    String userPassword = request.getParameter("password");
    PrintWriter out = response.getWriter();

    boolean isValidUser = false;

    /**
     * Get value from Map for user entered email address.
     */
    String password = credentialsPairs.get(userEmail);

    /**
     * If User with entered email address found then we will get  
     password for that
     * user
     */
    if (password != null) {
        /**
         * Compare password entered by user with one that is 
    retrieved from file
         */
        if (password.equals(userPassword)) {
            isValidUser = true;
        } else {
            // Please enter correct password
            out.println("Please enter correct password");
        }
    } else {
        // User does not exists
        out.println("User does not exist");
    }

    if (isValidUser) {
        response.sendRedirect("welcome.jsp");
    } else {
        response.sendRedirect("fail.jsp");
    }

}

public void destroy() {
    /**
     * Free up the map
     */
    credentialsPairs.clear();
}
}

The index.jsp :

<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF- 
 8" %>
<!DOCTYPE html>
<html>
<head>
<title>JSP - Hello World</title>
</head>
<body>
<div align="center">
<h1>
    Sign-In
</h1>
<form action="login" method="get">
    <table>
        <tr> <td>E-mail : <input type="email" name="email"></td> 
</tr>
        <tr> <td>Password : <input type="password" name="password"> 
</td></tr>
        <tr> <td><input type="submit" value="Login"></td></tr>
    </table>
</form>
</div>
</body>
</html>

The web.xml :

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee 
https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
     version="5.0">

<servlet>
    <servlet-name>lgn</servlet-name>
    <servlet-class>com.example.try8.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>lgn</servlet-name>
    <url-pattern>/login</url-pattern>
</servlet-mapping>
</web-app>
  • 1
    Have you already checked with your debugger where the problem is: is the email/password combination correctly detected as valid or not ? – Robin Oct 16 '21 at 19:04
  • 1
    1) Put an URL, you are using to call the servlet. 2) JOptionPane is a Swing class. I don't think, it does something useful inside a servlet. – 30thh Oct 16 '21 at 19:13
  • 1
    It is a wrong way to do authentication. The bad guy can open "welcome.jsp" directly without entering a password. You need to store the password in a user session and validate on every page it using filter. – 30thh Oct 16 '21 at 19:19
  • @Robin it's reading from the text file the email and the password also is being read but with a '\r" , if the email and password are not equal for some reason it's not reading the other email and password from the text to check them – Mohammed Hamdoon Oct 16 '21 at 20:55

1 Answers1

2

Hello @Mohammed Hamdoon

You can find below code. That serves your objective and eliminate costly over head of iterating over file each time to match email and password. Here I can login successfully with the credentials given in accounts.txt file.

Please read my comments in servlet file for further explanations.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

import jakarta.servlet.ServletConfig;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

@WebServlet("/HelloServlet")
public class HelloServlet extends HttpServlet {

    /**
     * 
     */
    private static final long serialVersionUID = -5498866193863633001L;

    /**
     * HashMap to store all users credentials
     */
    private final Map<String, String> credentialsPairs = new HashMap<>();

    @Override
    public void init(ServletConfig config) throws ServletException {
        String delimiter = ",";
        String line = "";

        /**
         * Credentials file will be there in WEB-INF directory as it provide secured
         * access only.
         */
        String credentialFile = "/WEB-INF/accounts.txt";

        /**
         * Read the file and prepare Map with username as key and password as value We
         * have put this code in init method as it is called once only that will avoid
         * overhead of iterating values from file for each request
         */
        InputStream is = null;
        InputStreamReader isr = null;
        BufferedReader br = null;

        ServletContext context = config.getServletContext();

        try {
            /**
             * Open stream of file
             */
            is = context.getResourceAsStream(credentialFile);
            if (is != null) {
                /**
                 * Read the file line by line and store email as a key and password as value
                 */
                isr = new InputStreamReader(is);
                br = new BufferedReader(isr);
                while ((line = br.readLine()) != null) {
                    String[] credentials = line.split(delimiter);
                    // credentials[0] is email and credentials[1] is password
                    credentialsPairs.put(credentials[0], credentials[1]);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (br != null) {
                    br.close();
                }
                if (isr != null) {
                    isr.close();
                }
                if (is != null) {
                    is.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
        /**
         * Get user entered credentials
         */
        String userEmail = request.getParameter("email");
        String userPassword = request.getParameter("password");

        boolean isValidUser = false;

        /**
         * Get value from Map for user entered email address.
         */
        String password = credentialsPairs.get(userEmail);

        /**
         * If User with entered email address found then we will get password for that
         * user
         */
        if (password != null) {
            /**
             * Compare password entered by user with one that is retrieved from file
             */
            if (password.equals(userPassword)) {
                isValidUser = true;
            } else {
                // Please enter correct password
            }
        } else {
            // User does not exists
        }

        if (isValidUser) {
            response.sendRedirect("welcome.jsp");
        } else {
            response.sendRedirect("fail.jsp");
        }

    }

    public void destroy() {
        /**
         * Free up the map
         */
        credentialsPairs.clear();
    }
}

Please share your comments, if you have any question on above.

  • I'm checking the code , when I enter the email and password it's always giving me fail.jsp is not found even if I enter them correct, I tried to debug and it's giving me that the value of password is NULL , why is that ? – Mohammed Hamdoon Oct 20 '21 at 20:30
  • In your login page (JSP file) you will have something like below html for password field `` And in your Servlet you will be getting that parameter with as such below code `String userPassword = request.getParameter("**password**");` So you will receive password null only if paramter name in JSP does not match with name used in your servlet like request.getParameter("password"); – kody-technolab Oct 21 '21 at 12:09
  • Then please share all the files here, so reason can be identified. – kody-technolab Oct 21 '21 at 14:04
  • I have edited the question – Mohammed Hamdoon Oct 21 '21 at 14:20
  • For some odd reason it's working now , but I can't get the "Please enter correct password" and "User does not exist" to work – Mohammed Hamdoon Oct 21 '21 at 15:41
  • They are just comments. These comments are added there if you wish to handle those scenarios later on otherwise we can ignore it or can remove else part where these comments are written. – kody-technolab Oct 22 '21 at 04:54
  • @mohammed, the messages are not showing because you are printing them in the current response. But later, when you do a redirect, is like you redirect to a new page, and so all printing you did in the previous response is gone. By the way, authentication should be done on Filters, not servlet, this way you can secure a pattern of paths. – gmanjon Nov 02 '21 at 17:47