Аутентификация имени пользователя, пароля с помощью фильтров в Java (связь с базой данных) - PullRequest
10 голосов
/ 22 декабря 2009

Ниже приведен фрагмент кода Java с использованием фильтров, которые каждый раз показывают страницу ошибки, если имя пользователя и пароль также верны Пожалуйста, помогите мне, я не очень разбираюсь в этой концепции.

String sql="select * from reg where username='"+user+"' and pass='"+pwd+"'";
rs=st.executeQuery(sql);
if(rs.next())
{
    chain.doFilter(request,response);
}
else
    sc.getRequestDispatcher("/error.html").forward(request,response);

Ответы [ 4 ]

31 голосов
/ 22 декабря 2009

String sql = "select * from reg, где username = '" + user + "' и pass = '" + pwd + "'";

Это крайне плохая практика. Этот подход требует, чтобы как имя пользователя, так и пароль передавались по простой ванили через запросы. Более того, у вас есть дыра для атаки SQL-инъекцией.

Используйте сеансы, в JSP / Servlet у вас есть HttpSession для. На самом деле также нет необходимости снова и снова нажимать на БД при каждом запросе, используя Filter. Это излишне дорого. Просто введите User в сеанс, используя Servlet и используйте Filter для проверки его присутствия при каждом запросе.

Начните с /login.jsp:

<form action="login" method="post">
    <input type="text" name="username">
    <input type="password" name="password">
    <input type="submit"> ${error}
</form>

Затем создайте LoginServlet, который сопоставлен с url-pattern из /login и имеет doPost(), реализованный следующим образом:

String username = request.getParameter("username");
String password = request.getParameter("password");
User user = userDAO.find(username, password);

if (user != null) {
    request.getSession().setAttribute("user", user); // Put user in session.
    response.sendRedirect("/secured/home.jsp"); // Go to some start page.
} else {
    request.setAttribute("error", "Unknown login, try again"); // Set error msg for ${error}
    request.getRequestDispatcher("/login.jsp").forward(request, response); // Go back to login page.
}

Затем создайте LoginFilter, который сопоставляется с url-pattern из /secured/* (однако вы можете выбрать свой собственный, например, /protected/*, /restricted/*, /users/* и т. Д., Но это должно как минимум охватывать все защищенные страницы, вам также нужно поместить JSP в соответствующую папку в WebContent), и doFilter() реализован следующим образом:

HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
HttpSession session = request.getSession(false);
String loginURI = request.getContextPath() + "/login.jsp";

boolean loggedIn = session != null && session.getAttribute("user") != null;
boolean loginRequest = request.getRequestURI().equals(loginURI);

if (loggedIn || loginRequest) {
    chain.doFilter(request, response); // User is logged in, just continue request.
} else {
    response.sendRedirect(loginURI); // Not logged in, show login page.
}

Так и должно быть. Надеюсь это поможет.

Чтобы понять, как будет выглядеть UserDAO, вам может пригодиться эта статья . В нем также рассказывается, как использовать PreparedStatement для защиты вашего веб-приложения от атак SQL-инъекций.

Смотри также:

3 голосов
/ 22 декабря 2009

Используйте подготовленное утверждение, ваш код является открытым приглашением для SQL-инъекции .

Connection con = getMyConnection();
        try {
                //no string concatenation, we use ? instead:
                PreparedStatement ps = con.prepareStatement("select * from reg where username=? and pass=?");
                try {
                        //actual value for parameters are set here:
                        ps.setString(1, user);
                        ps.setString(2, pwd);
                        ResultSet rs = ps.executeQuery();
                        if(rs.next()) {
                                chain.doFilter(request,response);
                        } else {
                                sc.getRequestDispatcher("/error.html").forward(request,response);
                        }

                } finally {
                        ps.close();
                }
        } finally {
                con.close();
        }

Теперь по вашему вопросу, пожалуйста, проверьте:

  • что имена таблиц и столбцов правильные (разве у вас нет столбца 'login' и 'username'?)
  • что значения действительно правильные (например, попробуйте выполнить запрос в sqldevelopper)
  • что он работает с паролем и именем пользователя ascii-7 (это может быть проблемой кодировки)
  • что столбец пароля содержит реальный пароль, а не его хеш
2 голосов
/ 22 декабря 2009

Так много всего плохого в этом ...: - /

  1. Большой - SQL-инъекция . Не пишите еще одну строчку SQL в своем коде, пока не поймете это. И это не преувеличение для эффекта; код, написанный без понимания этого, может дать злоумышленнику произвольный доступ к вашей базе данных.
  2. Вы не должны иметь возможность отправлять подобные запросы, потому что вы никогда не должны хранить пароли в открытом тексте. Вместо этого вы должны рассчитать и сохранить какой-то (желательно соленый) хэш пароля, а затем хешировать представленный пароль и сравнить его. См., Например, Как лучше всего хранить логин и пароль пользователя и Salting your password здесь, на SO. Это особенно плохо, учитывая вашу уязвимость SQL-инъекции.
  3. select * from reg не требуется, если вы просто хотите узнать, существует ли строка. Если бы вы использовали select 1, вместо этого базе данных не пришлось бы проверять содержимое строки, и она могла бы обслуживать результаты запроса только из индекса. Если вы ожидаете, что будет много строк, select 1 where exists ... будет быстрее, поскольку это позволит БД выполнить короткое замыкание запроса после нахождения хотя бы одной строки.
  4. Вы не закрываете оператор и набор результатов в finally блоках. Это означает, что они не всегда удаляются (например, если выброшено SQLException), что приводит к утечке ресурсов и соединения.
1 голос
/ 22 декабря 2009

Прежде всего, вы действительно должны использовать для этого параметризованные запросы. Если пользователь введет '";DROP TABLE reg; в качестве имени пользователя, у вас будут большие проблемы.

Кроме того, вы уверены, что имя пользователя и пароль верны? Как насчет заглавных букв?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...