首页 > 解决方案 > How to block a user for specific time after 3 attempts?

问题描述

I've created a simple login servlet in which the user enters his email and password and it checks if he's a registered user then it logs him in , if he's not it says login fail,the credentials are stored in a text file , I can't use a database,the code works perfect. Now the only problem is that I'm trying to block a registered user after 3 attempts for a specific period of time , let's say 30 mins , how can that be done ?

The format of the text file is as follows :

The email and password are seperated by a ','

CODE :

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

import jakarta.servlet.RequestDispatcher;
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;
import jakarta.servlet.http.HttpSession;

@WebServlet("/HelloServlet")
public class HelloServlet extends HttpServlet {
//int attempts = 3;
/**
 *
 */
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, ServletException {
    /**
     * 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;
        }
    }
    HttpSession session = request.getSession();
        if (isValidUser) {
            //HttpSession session = request.getSession();
            session.setAttribute("email", userEmail);
            
  request.getRequestDispatcher("welcome.jsp").include(request, 
  response);
            //response.sendRedirect("welcome.jsp");
        }
        else {
            int loginAttempt;
            if (session.getAttribute("loginCount") == null)
            {
                session.setAttribute("loginCount", 0);
                loginAttempt = 0;
            }
            else
            {
                loginAttempt = (Integer) 
   session.getAttribute("loginCount");
            }

            //this is 3 attempt counting from 0,1,2
            if (loginAttempt >= 2 )
            {
                long lastAccessedTime = 
    session.getLastAccessedTime();
                Date date = new Date();
                long currentTime = date.getTime();
                long timeDiff = currentTime - lastAccessedTime;
                // 20 minutes in milliseconds
                if (timeDiff >= 1200000)
                {
                    //invalidate user session, so they can try 
    again
                    session.invalidate();
                }
                else
                {
                    // Error message
                    session.setAttribute("message","You have 
             exceeded the 3 failed login attempt. Please try loggin 
             in in 20 minutes.");
                }

            }
            else
            {
                loginAttempt++;
                int allowLogin = 3-loginAttempt;
                session.setAttribute("message","loginAttempt= 
      "+loginAttempt+". Invalid username or password. You have 
    "+allowLogin+" attempts remaining. Please try again! <br>Not a 
    registered cusomer? Please <a 
  href=\"register.jsp\">register</a>!");
            }
            session.setAttribute("loginCount",loginAttempt);
        }
    RequestDispatcher dispatcher = 
    getServletContext().getRequestDispatcher("index.jsp");
    dispatcher.forward(request, response);
  }

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

标签: javaservletsjava-ee-6

解决方案


您应该在 credentialsPairs 中再添加一个属性,例如,然后在检查密码时还要检查登录时间以阻止用户


推荐阅读