Cómo programar el control de acceso de usuarios en java utilizando jsp y servlets Tutorial Java J2EE

Por descargarpseint / hace 4 meses / 0 Comentarios ».

Hoy quiero hablarte de un problema común cuando te pones a programar en aplicaciones java basadas en J2EE. Llevo muchos años desarrollando sistemas que utilizan este estándar y el control de acceso siempre ha sido uno de los asuntos que se dejaban para el final cuando era clave ya que el cliente asumía que su aplicación sería segura. Aprovechando una duda que me llegó en una clase particular que impartí el viernes, te voy a explicar que hizo mal y como le ayudé a encontrar una solución y de paso te introduciré algunos conceptos como los objetos de ámbito sesión, ámbito solicitud y cómo se puede programar un control de acceso de usuarios utilizando Java Server Pages y Servlets.

Ayer  Alejandro (un alumno) me estuvo hablando de una pequeña aplicación web que estaba desarrollando utilizando el estándar java j2ee.  A medida que me iba contando lo que quería hacer y como lo había programado me hacia mas consciente  del enorme cacao mental que tenía y la gran cantidad de detalles que hay que tener en cuenta para conseguir implementar un código que haga lo que tú quieras.

El quería controlar el acceso de los usuarios mostrando un formulario web donde el visitante tuviera que introducir su nombre de usuario y contraseña.  Para ello programó una página JSP (Java Server Page) donde introdujo el código encargado de solicitar datos al usuario y de enviar una petición al servidor para que este se encargase de comprobar si disponía de los permisos de acceso suficientes para entrar en la web o no.

<!DOCTYPE html>
<html>
 <head>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 <title>JSP Page</title>
 </head>
 <body align="center">
 <h1>Iniciar Sesión</h1>
 <form method="post" action="Servlet">
 Usuario <input name="user" type="text" /> <br />
 Contraseña <input name="password" type="password" /> <br /> <br />
 <input type="submit" value="Enviar" />
 </form> 
 </body>
</html>

¿Quién es el responsable de controlar el acceso a la web?

Alejandro optó, sabiamente, por separar la lógica de negocio (decidir si un usuario tiene acceso a la aplicación o no) de la lógica de presentación (solicitar las credenciales al usuario y mostrarle una pantalla con el resultado de la misma) y   así decidió definir un Servlet, cuya responsabilidad sería la de controlar el acceso a la parte privada de la aplicación validando las credenciales introducidas por el usuario frente a las credenciales esperadas (alojadas en el servidor).

A continuación os muestro como pensó en resolver esta situación utilizando el método doPost de la clase Servlet.

protected void doPost(HttpServletRequest request,
 HttpServletResponse response) throws ServletException, IOException {
 response.setContentType("text/html;charset=UTF-8");
 PrintWriter out = response.getWriter();
 try {
 String user, password;
 user = request.getParameter("user");
 password = request.getParameter("password");
 boolean autenticado;
 String usuario = "s";
 String contraseña ="s";
 if(usuario.equals(user) && password.equals(contraseña)){
 autenticado= true;
 }else{
 autenticado = false;
 }

if (autenticado) {
 HttpSession Session = request.getSession();

response.sendRedirect("menu.jsp");

} else {
 response.sendRedirect("index.jsp");
 }
 } catch (Exception e) {
 e.printStackTrace();
 } finally {
 out.close();
 }
 }

El quería que cuando un usuario accediese a la aplicación entonces esta comprobase si estaba registrado. En caso de estarlo debería redirigirlo a la página menu.jsp (encargada de mostrar los datos privados de la aplicación) mientras que si no era este el caso, entonces mostraría el formulario de registro para que introdujera sus credenciales.

El comenzó a realizar su batería de pruebas y para ello escribió las siguientes URLs en el navegador.

El resultado, en ambos casos, fue que el servidor mostró el formulario de registro. A partir de aquí, en función de si los datos de usuario y contraseña introducidos por el visitante eran correctos o no, el servidor mostraba la pantalla con datos sensibles (menu.jsp) o volvía a solicitar al usuario que se registrara de nuevo.

Hasta aquí todo bien, sin embargo, a continuación se le ocurrió realizar una prueba mucho mas exigente, y que por cierto, ya demuestra la pericia que tendrá en su futura carrera de programador. El caso de prueba fue el de intentar acceder directamente a la página privada escribiéndola en el navegador.

¿Qué pensáis que ocurrió?. Me gustaría que te tomaras unos minutos para reflexionar sobre el código y la problemática que te acabo de plantear. Si estás leyendo estas líneas es porque te gustaría aprender programación web utilizando java j2ee. Me parece fantástico y estás en el lugar indicado, sin embargo, no todo es teoría, búsqueda de soluciones por la web y el famoso y asentado copia y pega.

Si ya estás listo para continuar te voy a presentar la causa de este comportamiento inesperado por parte de la aplicación y algunos conceptos teóricos sobre el Protocolo HTTP, la sesión del navegador y como gestiona Java todo esto desde el servidor.

El Ámbito Sesión y el Ámbito Petición no son lo mismo.

Cuando abrimos un navegador e introducimos una dirección que comienza por http:// lo que estamos haciendo es decirle al navegador que utilice este protocolo para comunicarse con el servidor destino, es decir, algo así es justo lo que has hecho cuando has introducido por teclado la dirección de Programar En Java.

Este protocolo nació con la finalidad de transferir archivos de texto junto a contenidos multimedia. Su creador pensó en un sistema de comunicación donde las peticiones serían autosuficientes, es decir, que cuando un cliente realizase una petición de información, entonces, su solicitud podría ser atendida completamente con un mensaje de respuesta. Es decir, que el protocolo nació con la filosofía de petición/respuesta, sin existir relación alguna entre 2 peticiones consecutivas realizadas desde el mismo cliente.

Después apareció el concepto de sesión, donde un mismo usuario, desde un mismo navegador realizaba peticiones consecutivas y donde el resultado esperado por este dependía del flujo completo de acciones realizadas por el. Para ello era necesario mantener una relación entre el navegador web y servidor de aplicaciones.

Como los Objetos HttpServletRequest, HttpServletResponse y HttpSession guardan la sesión del usuario.

Volviendo al control de acceso del usuario, cuando este escribe una dirección en su navegador entonces este último envía una solicitud http al servidor de aplicaciones (Tomcat en este caso) éste construye un objeto java HttpServletRequest que encapsula todos los datos procedentes de la petición. Además instancia un objeto HttpServletResponse donde el servidor (en el ejemplo a través del Servlet definido por Alejandro) escribirá la respuesta que terminará siendo enviada (a través del protocolo http) al navegador que inició la solicitud.

Te acabo de describir como java gestiona una petición web y todos los objetos que he descrito tienen un ámbito de petición, es decir, que nacen cuando la solicitud empieza, se mantienen vivos en memoria durante el transcurso de la misma y mueren (son eliminados por el recolector de basura) cuando el servidor devuelve la respuesta.

Si vuelves al código que te presenté anteriormente sobre como el servlet estaba controlando el acceso podrás ver que definía las credenciales dentro del método doPost, es decir, el ámbito de la variable autenticado es a nivel de método. Lo que significa que tras realizar la validación y redirigir a la vista adecuada, la información de esta variable desaparece con ella.

Este fue el error que el cometió. Esta aprendiendo y aún desconoce como funcionan los diferentes ámbitos, pero si una información deseas que siga viva entre diferentes peticiones de un usuario, entonces tienes que olvidarte del ámbito de petición y pensar en el ámbito de sesión.

En la solución que te presentaré en la segunda parte de este manual java utilizaré la sesión, y mas concretamente, el objeto HttpSession para guardar el estado de validación del usuario y así poder controlar su acceso desde cualquier petición que pueda llegar. Además te ofreceré una solución profesional (que he visto, utilizado y programado en muchos proyectos) y te explicaré que ventajas/desventajas tiene respecto a otras soluciones mas estándar que aprovechan toda la potencia de J2EE.

Para explicar el problema del control de acceso de usuarios he necesitado introducir muchos conceptos (web y java) que quizás no comprendas bien y aunque he intentado buscar y dejar enlaces que puedan ayudarte en su comprensión, quiero comentarte que estoy aquí para ayudarte y para completar este artículo con nueva información (de mi cosecha) pensada para responder a tus dudas. Sin embargo, necesito de tu ayuda y tu participación para poder detectar esos temas que hayan podido quedar mas confusos. Anímate y participa o escríbeme!!!

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *