Cómo asegurar una web desarrollada en Java y Java Server Faces

Jesús Aureliano Esquivel Cáredenas,
Javier Ruiz Tello,
Jesús Abraham Castorena Peña,
Celia Castruita Ávila

 

Artículo PDF
CienciaCierta #39, Julio – Septiembre 2014
volver

Este documento, basado en el blog de Markus Eisele [1,] presenta una breve guía para implementar las características de seguridad en una aplicación web desarrollada en Java y Java Server Faces en el marco de Primefaces mediante un formulario de entrada para introducir la cadena de usuario y password.

De las diferentes formas que existen para lograr este objetivo, exploraremos la que está basada en dominio y que utiliza base de datos, en nuestro caso MySQL. Como encontraremos muchas referencias inglés, utilizaremos las siglas JDBC based realm para referirnos a esta técnica de seguridad. Utilizaremos el servidor de aplicaciones Glassfish 4.0. El formulario para el login está basado en Primefaces y el ejemplo que expondremos se ha desarrollado en Netbeans 7.4. Lo anterior es software libre, disponible en la web.

Para iniciar un proyecto desde Netbeans selecciona: New Project; después Java Web>Web Application y pulsa Next. Itroduce un nombre (ej. jdbcrealm) y teclea Next. Escoge como servidor Glassfish 4.0, si no se encuentra agrégalo. La versión de Java EE debe ser, al menos, la 6, pulsa Next. Verifica que esté checada la caja que selecciona al Java Server Faces y cambia al tabulador de los componentes para seleccionar Primefaces como suite prede-erminada. Pulsa Finish. Con esto termina la configuración inicial del proyecto de Netbeans.

Para crear una nueva base de datos se utilizan los siguientes comandos en SQL los cuales se pueden ejecutar desde el Netbeans o desde el Workbench de MySQL.

CREATE DATABASE jdbcrealmdb;
USE jdbcrealmdb;
CREATE TABLE `jdbcrealmdb“usuarios`(
`nombre`varchar(255) NOT NULL,
`password`varchar(255) DEFAULT NULL,
PRIMARY KEY (`nombre`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `jdbcrealmdb`.`grupos`
`nombre`varchar(255) NOT NULL,
`Grupo`varchar(255) DEFAULT NULL)
ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE INDEX groups_users_FK1 ON grupos(nombre ASC);

Para poder utilizar la aplicación deben intro-ducirse algunos usuarios y sus roles, éstos tomados de los valores que se introduzcan en la columna de grupo. Una vez creadas las tablas anteriores se introducen algunos usuarios mediante las siguientes instrucciones:

INSERT INTO usuarios VALUES
(‘admin’,’adminadmin’);
INSERT INTO usuarios
VALUES(‘jesus’,’jesuspwd’);
INSERT INTO grupos
VALUES(‘admin’,’admin’);
INSERT INTO grupos
VALUES(‘jesus’,’user’);

Al usuario admin le hemos asignado el password: adminadmin y se ha agregado en la tabla de grupos con el rol del mismo nombre. De igual forma, al usuario “jesus” se la ha asignado el password jesuspwd y se ha insertado en la tabla de grupos con el rol user. No hay regla para el nombre de los roles, sin embargo, usar palabras breves y concisas es una buena técnica de programación, aunque sean en inglés.

Configuración del dominio
En la ventana de Servicios en Netbeans haz clic con el botón derecho al nodo Databases en el árbol. Escoge nueva conexión y selecciona: MySQL (con el driver Connector/J). Este driver se encuentra en la dirección: %NB_HOME%/ide/modules/ext/mysqlco-nector-java-5.1.13.jar. Pulsa Next y coloca los parámetros. Aquí, no olvides seleccionar la base de datos recién creada: i.e., jdbcrealmdb. Para veri-ficar que todo esté bien debemos pulsar Test para probar nuestra conexión. La cadena formada tiene el siguiente aspecto: jdbc:mysql://localhostost:3306/jdbcrealmdb?zeroDateTimeBehavior=ConvertToNull.

El servidor, localhost, utiliza el puerto 3306; abre la base de datos jdbcrealmdb, convierte a null la fecha con valor de ceros. En esta cadena también se puede agregar el usuario y password de la base de datos mediante la concatenación de: &User=<usuario>& password=<password> a la cadena anterior. Esto se puede omitir, sin embargo, al solicitar esta conexión el sistema te los pedirá para acceder. Una vez realizada esta conexión regresas a tu aplicación en el tab de Projects, haces clic derecho y seleccionas: new>other>glassfish>JDBC connection pool puedes utilizar cualquier nombre para esta nueva conexión, ej. ConexionSeguridadPool, y utiliza la opción Extract from Existing Connection. Selecciona la selección de MySQL recién creada y pulsa Finish. Si no existía se crea un nuevo folder Server Resources con el archivo: glassfish-resources.xml Ahora debes crear un recurso, ej., jdbc/securityDatasource seleccionando new>other>glassfish>jdbcresource y apuntando al pool recién creado. Éste será adminis-trado por el Glassfish y suministrado a la aplicación cuando ésta lo solicite, para ello deberá tener acceso al driver Java de MySQL por lo que deberá copiarse el archivo: %NB_HOME%/ide/modules/ext/mysqlconnector-java-5.1.13-bin.jar al dominio del Glassfish en: %GF_HOME%/glassfish/domains/Domain1/l (Nótese que esta versión del driver puede cambiar).

Consola de administración Glassfish
Para modificar los parámetros en Glassfish debemos iniciar el servidor, después abrir un browser y visitar la página en: http://localhost:4848/ una vez ahí, seleccionamos: configuration>security>realms y hacemos clic en New. Escogemos un nombre, ej. JDBCRealm, y seleccionamos: com.sun.enterprise .Security.auth.realm.jdbc.JDBCRealm del com-bobox y llenamos los siguientes campos de texto.

El SHA-256 se utiliza actualmente por el Glassfihs para comprobar que el password no ha sido modificado comparándolo con un código hash gene-rado por el algoritmo.

Asegura tu aplicación
Una vez configurado tu entorno deberás asegurar la aplicación. Verifica qué recursos o páginas protegerás. En este proyecto crearemos dos folders en Web Pages a los que llamaremos admin y users. La idea es que los folders puedan ser accesados por usuarios que per-tenecen a los grupos apropiados. Hagamos ahora el formulario de entrada loginForm.xhtml que colocare-mos en el directorio raíz de Web Pages.

<?Xml version=’1.0’encoding=’UTF-8′ ?>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”
“Http://www.w3.org/TR/xhtml1/DTD/xhtml1
-Transitional.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml”
xmlns:p=”http://primefaces.prime.com.tr/ui”
xmlns:h=”http://java.sun.com/jsf/html”>
<h:head>
<title>Login Form</title>
</h:head>
<h:body>
<p:panel header=”Login From”>
<form method=”POST” action=”j_security_check”>
Usuario: <input type=”text” name=”j_username” />
Password: <input type=”password” name=”j_password” />
<br/>
<input type=”submit” value=”Login” />
<input type=”reset” value=”Reset” />
</form>
</p:panel>
</h:body>
</html>

El panel de Primefaces tiene un simple formulario que apunta a la acción predefenida j_security_check. Los argumentos de entrada a esta acción son: j_username y j_password. Ahora escribamos una página para el caso en que el usuario se equivoque al escribir sus credenciales. Le llamaremos login Error.xhtml y la colocaremos en la carpeta raíz de Web Pages. Para abreviar un poco el contenido sólo mostraremos la parte del cuerpo de la página. La primera parte es igual que el archivo anterior:

<h:body>
<p:panel header=”Login Error”>

Lo sentimos, no aparece en nuestros registros, intente de nuevo : <a href=”#{facesContext.externalContext.requestContextPath}/faces/loginForm.xhtml” >Login</a>
</p:panel>
</h:body>

La palabra faces puede ser cambiada por otra en cuyo contexto haya sido declarado el servlet de Java Server Faces. Si un usuario sin los derechos apro-piados trata de accesar, un folder se le presenta una página de error 403. La cual puede ser personalizada y configurada en el archivo web.xml.

<error-page>
<error-code>403</error-code>
<location>/faces/403.xhtml</location>
</error-page>

En el archivo web.xml se configura la seguridad de la aplicación. Se agregan las restricciones de segu-ridad para cada uno de los recursos protegidos. Para ello, en el archivo glassfish-web.xml, se dan de alta los roles de todos los usuarios, los grupos admin y user pueden mantener el mismo nombre en el rol o cambiarse por otros, e.g., administrador y usuario.

<Security-role-mapping>
<role-name>admin</role-name>
<group-name>administrador</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>user</role-name>
<group-name>usuario</group-name>
</security-role-mapping

Estos últimos son utilizados en web.xml en las restricciones de los recursos, los cuales se pueden sele-ccionar con un asterisco, para restringir carpetas ente-ras, ej. todos los archivos en /users se restringen mediante: <Url-pattern>/faces/users/*</url-pattern>; o bien seleccionando un archivo especí-fico, e.g.,<urlpattern>/faces/users/usuario.x
html </url-pattern>

Configuración de formularios
Una vez establecidas las restricciones debes definir cómo el Glassfish solicitará las credenciales al usua-rio.

<realm-name>JDBCRealm</realm-name>
<form-login-config>
<form-login-page>/faces/loginForm.xhtml</form-login-page>
<form-error-page>/faces/loginError.xhtml</form-error-page>
</form-login-config>
</login-config>

Si direccionas en el browser a una página dentro del folder admin, ej, Localhost:8080/jdb-crealm/
faces/admin/admin.xhtml,serás detenido por la pá-gina del login en la cual deberás teclear admin y adminadmin como como usuario y password respec-tivamente. Si deseas acceder a una página dentro de la carpeta users, ej. Localhost:8080/jdbcrealm/fac es/users/usuarios.xhtml, deberás teclear las res-pectivas credenciales para acceder a estos recursos, i.e., jesus y jesuspwd.

Conclusiones
En este trabajo se abordó el tema de la seguridad de aplicaciones web la cual tiene muchas facetas y com-plejidades que cubren las necesidades de cualquier desarrollador de software. Los conceptos estudiados aquí son de lo más común en relación a las tecnologías seleccionadas.

 

Artículo PDF
CienciaCierta #39, Julio – Septiembre 2014
volver

Referencias bibliográficas
1. Blog de Markus Eisele http://blog.eisele.net/2011/01/jdbc-security-realm-and-form-based.html . Enero 2011.
2. Antonio Concales. Beginning Java EE 6 Platform with Glassfish 3: From Novice to Profesional, 2nd Edition. Apress 2010.
3. E.Jendrock, I.Evans, D.Gollapudi, K.Haase, C.Srivathsa. The Java EE 6 Tutorial. Basic Concepts, 4th Edition. Addison-Wesley 2011.
4. Mick Knutson. Java EE 6 Cookbook for Securing, Tuning, and Extending Enterprise Applications. Packt Publishing. 2012.

Post Author: CC

Deja un comentario