libreria jtls funciones ejemplos curso jsp authentication servlets login servlet-filters

jsp - jtls - Autenticando el nombre de usuario, contraseña usando filtros en Java(contactando con la base de datos)



jtls java (4)

Antes que nada, debería usar consultas parametrizadas para esto. Si el usuario ingresa ''";DROP TABLE reg; como nombre de usuario estará en un gran problema.

Además, ¿estás seguro de que el nombre de usuario y la contraseña son correctos? ¿Qué hay de capitalización?

La siguiente es la parte del código de Java utilizando filtros que muestran la página de error en todo momento si el nombre de usuario y la contraseña también son correctos. Por favor, ayúdenme, no tengo mucho conocimiento sobre este concepto.

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);


Use una declaración preparada, su código es una invitación abierta para una inyección 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(); }

Ahora para su pregunta, por favor verifique:

  • que los nombres de tabla y columna son los correctos (¿no tienes una columna de "inicio de sesión" y una columna de "nombre de usuario"?)
  • que los valores son realmente correctos (prueba la consulta en sqldevelopper, por ejemplo)
  • que funciona con una contraseña y un nombre de usuario de ascii-7 (podría ser un problema de codificación)
  • que la columna de contraseña contiene la contraseña real y no un hash de ella

String sql = "select * from reg where username = ''" + user + "'' y pass = ''" + pwd + "''";

Esta es una práctica extremadamente mala. Este enfoque requiere que tanto el nombre de usuario como la contraseña se transmitan a través de las solicitudes simples. Además, tienes un agujero de ataque de inyección SQL.

Haga uso de las sesiones, en JSP / Servlet para el que tiene HttpSession . En realidad, tampoco es necesario pulsar DB una y otra vez en cada solicitud utilizando un Filter . Eso es innecesariamente caro. Simplemente ponga al User en sesión usando un Servlet y use el Filter para verificar su presencia en cada solicitud.

Comience con un /login.jsp :

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

Luego, cree un LoginServlet que esté mapeado en url-pattern of /login y tenga doPost() implementado de la siguiente manera:

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. }

Luego, cree un LoginFilter que esté mapeado en url-pattern de /secured/* (puede elegir el suyo propio, por ejemplo, /protected/* , /restricted/* , /users/* , etc., pero al menos debe cubrir todos páginas seguras, también debe colocar las JSP en la carpeta apropiada en WebContent) y tiene doFilter() implementado de la siguiente manera:

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. }

Eso debería ser. Espero que esto ayude.

Para tener una idea de cómo se UserDAO un UserDAO , puede encontrar este artículo útil. También cubre cómo usar PreparedStatement para guardar su aplicación web de ataques de inyección SQL.

Ver también:


Tantas cosas mal con esto ...: - /

  1. El más grande: Inyección SQL . No escriba otra línea de SQL en su código hasta que lo comprenda. Y eso no es una exageración para el efecto; El código escrito sin entender esto probablemente le otorgue a un atacante acceso arbitrario a su base de datos.
  2. No debería poder emitir una consulta como esta porque nunca debe almacenar contraseñas en texto sin formato. En su lugar, debe calcular y almacenar algún tipo de hash (preferiblemente salado) de la contraseña, y luego hash la contraseña enviada y compararla. Consulte, por ejemplo, Cómo guardar mejor el nombre de usuario y la contraseña, y Saltear su contraseña aquí en SO. Esto es especialmente malo dada su vulnerabilidad de inyección SQL.
  3. select * from reg es innecesario dado que solo quiere saber si existe una fila. Si utilizó select 1 en su lugar, la base de datos no tendría que inspeccionar el contenido de la fila y podría servir los resultados de la consulta solo del índice. Si esperaba que hubiera muchas filas, select 1 where exists ... sería más rápido ya que esto le permitiría al DB cortocircuitar la consulta después de encontrar al menos una fila.
  4. No estás cerrando la declaración y el conjunto de resultados en los bloques finally . Esto significa que no está garantizado que siempre se desechen (por ejemplo, si hay una SQLException arrojada) que conduce a pérdidas de recursos y conexiones.