icono_twiter
Jose Manuel Sánchez Suárez

Consultor tecnológico de desarrollo de proyectos informáticos.

Puedes encontrarme en Autentia: Ofrecemos servicios de soporte a desarrollo, factoría y formación

Somos expertos en Java/J2EE

Ver todos los tutoriales del autor

Fecha de publicación del tutorial: 2007-12-10

Tutorial visitado 52.467 veces Descargar en PDF
JAAS (Java Authentication and Authorization Service)

JAAS (Java Authentication and Authorization Service) y Jboss.


0. Índice de contenidos.

1. Introducción

JAAS (Java Authentication and Authorization Service) es una interfaz que permite a las aplicaciones Java acceder a servicios de control de autenticación y acceso. Apareció como paquete opcional en la versión 1.3 y lleva siendo parte del estándar desde la versión 1.4.

Puede usarse con dos fines:

    - la autenticación de usuarios: para conocer quién está ejecutando nuestro código java,

    - la autorización de usuarios: para garantizar que quién lo ejecuta tiene los permisos necesarios para hacerlo.

En este tutorial vamos a ver un ejemplo de cómo implementar dicha interfaz desde una aplicación JEE, en la que la información sobre los usuarios y sus perfiles la mantenemos en una base de datos.

Comprobaremos que la tarea se limita a la parametrización de ficheros de configuración (*.xml): del lado del servidor de aplicaciones y del lado de nuestra aplicación web.

El objetivo es delegar el mecanismo de autenticación y autorización en el servidor de aplicaciones. En la práctica significa, que ya no será necesario implementar un filtro de autorización en todas nuestras aplicaciones web y no tendremos que copiar el LoginAction.java o el LoginBean.java de una aplicación a otra arrastrando posibles errores.

Al implementar una interfaz que forma parte del estándar, nos beneficiamos no solo del acceso a la información del usuario y su perfil a través de métodos que forman parte del mismo (del estándar), si no que, además, nos podemos beneficiar de otras implementaciones que encapsulan dichos métodos dentro de su librería de tags, como el proyecto tomahawk de apache, lo veremos en el último punto.

Por último, al tratarse de una interfaz podríamos decidir modificar la política de seguridad pasado mañana, para que vez de autenticarnos contra base de datos lo hiciésemos contra un servidor LDAP... y lo único que tendríamos que tocar es un fichero de configuración en el servidor.

2. Entorno.

El tutorial está escrito usando el siguiente entorno:
  • Hardware: Sobremesa Dell Dimension 6400, 2.13 Ghz, 2 Gb RAM
  • Sistema operativo: Windows XP Media center Edition
  • JDK 1.6.0_2
  • Eclipse 3.3.
  • Jboss 4.2.1.GA
  • MySQL 5.0

3. Creación de tablas y carga de datos en MySQL.

Si la autenticación la vamos a realizar contra base de datos, lo primero que necesitamos es crear las tablas en MySQL.

Ni el nombre de las tablas es fijo, ni el nombre de los campos de cada tabla, con lo que si ya tenemos un modelo de datos que responde a esta estructura no será necesario migrarlo. Veremos que, tanto la consulta de usuario, como la consulta de perfil se realizan a través de una sentencia sql parametrizable.

El siguiente script crea dos tablas:
  • role: con una clave única y un nombre. El campo nombre será importante a la hora de definir la autorización.
  • user: con una clave única, un login, una contraseña y una clave foránea que vincula un usuario a un rol.
El siguiente script inserta dos usuarios y dos roles:
  • usuario:"admin", con contraseña:"admin", asociado al rol "ADMINISTRATOR"
  • usuario:"user", con contraseña:"password", asociado al rol "USER"
Las contraseñas están encriptadas usando el algoritmo MD5 en Base64.

4. Definición del datasource y configuración de la política de seguridad en Jboss.

La definición de una fuente de datos en Jboss se realiza añadiendo un fichero con extensión -ds.xml en el directorio jboss-4.2.1.GA\server\default\deploy, con el siguiente contenido:
Tenemos que configurar:
  • jndi_name: con un id único para nuestro datasource, que usaremos para invocarlo desde nuestra política de seguridad (el siguiente punto),
  • connection-url: con la dirección y el nombre de nuestra base de datos MySQL
  • user-name: con el login de un usuario para acceder a la base de datos. Claro está que no se refiere a uno de los usuarios de las tablas antes creadas, sino a un usuario de MySQL con permisos de lectura para acceder a la base de datos.
  • password: con la contraseña de acceso del usuario anterior.
En nuestro caso tenemos un fichero jboss-4.2.1.GA\server\default\deploy\test-ds.xml para el acceso a la base de datos MySQL de test, con un usuario de MySQL test con contraseña test.

Jboss no viene con el driver para MySQL preinstalado, con lo que, si aún no lo tenemos, deberemos obtenerlo de la siguiente ubicación Download Connector/J 5.0: y copiar el jar, mysql-connector-java-5.0.*-bin.jar, en jboss-4.2.1.GA\server\default\lib\

En el fichero jboss-4.2.1.GA\server\default\conf\login-config.xml debemos introducir la siguiente política de seguridad:
Tenemos que configurar:
  • <application-policy name="simpleWebAuthenticationPolicy">: con un id único que identifica nuestra política de seguridad, que usaremos desde la aplicación web para enlazarla,
  • <module-option name="dsJndiName">java:simpleDS<module-option>: con el nombre del datasource que hemos definido en el punto anterior,
  • <module-option name="principalsQuery">select password from User where login=?</module-option>: con la sentencia sql para la obtención de la contraseña del usuario que recibe como parámetro. Como comentaba, si vuestro modelo de datos no se corresponde con el de este ejemplo, aquí asignaríamos la sentencia correspondiente.
  • <module-option name="rolesQuery">select r.name, 'Roles' from User u,Role r where u.roleId=r.id and login=?</module-option>: con la sentencia sql para la obtención del nombre del perfil asociado al usuario, con las mismas consideraciones que en el punto anterior,
  • <module-option name="hashAlgorithm">MD5</module-option>:indica el nombre de algoritmo que hemos usado para guardar nuestras contraseñas en la tabla de usuarios,
  • <module-option name="hashEncoding">base64</module-option>: indica el tipo de encoding que usará el algoritmo para comprobar la contraseña.
En este punto hemos configurado el módulo JAAS de Jboss para que acceda a nuestra base de datos a través de un datasource, el mismo que debería usar nuestra aplicación web.

Cambiar de base de datos, para pasar a un entorno de producción, por ejemplo, es sencillo, basta con modificar el vínculo (el nombre del datasource) entre la política de seguridad y el datasource, o lo que es más común, al tener varios datasources (uno por entorno), tendríamos varias políticas de seguridad (una por cada uno de ellos).

5. Estructura de nuestra aplicación JEE.

Crearemos un proyecto web dinámico en Eclipse, en nuestro caso con nombre SimpleWeb, con la siguiente estructura de directorios:

SimpleWeb


La idea es que:
  • el contenido del directorio /pages no sea visible si no se ha accedido a la aplicación a través de la página de login, y
  • el contenido del directorio /pages/admin no sea visible a todos los usuarios, sólo a aquellos con perfil de administración.
Veamos primero el código de nuestras páginas:

La página index.jsp, tendría el siguiente código:
03. Limpia la sesión para eliminar el login de usuario si lo hubiese.
04. Redireccióna la petición a una página que estará protegida, la que se mostrará después de un login satisfactorio.

El filtro de autorización de JAAS funciona de modo que, si se accede a una página protegida y no hay usuario en la sesión, te remite a la página de login. Teniendo en cuenta esto, lo que debe hacer nuestra página de inicio es redirigir la petición a una página protegida, para que salte la página de login y tras un login satisfactorio nos redirija a la página protegida.

Un error común es no llevar a cabo ésta primera redicción, y marcar como página de entrada el login.jsp, si hacemos esto (podemos probarlo), tras el login, nos intentará redirijir al login, apareciendo el siguiente error:
Estado HTTP 400 - Referencia directa al formulario de conexión (página de formulario de login) inválida
La página login.jsp, tendría el siguiente código:
Contiene el formulario de entrada de usuario y contraseña:
  • es obligatorio que el formulario tenga un name concreto (j_security_check) y un action concreto (j_security_check), el action invoca al filtro de autorización de JAAS,
  • el nombre del campo de entrada para el login de usuario debe llamarse j_username y el campo password j_password.

La página loginError.jsp, contiene un mensaje de error informando que el usuario y/o la contraseña introducidos no son correctos:

La página /pages/home.jsp, contiene un título y un enlace para acceder a la administración del web:

La página /pages/admin/home.jsp, contiene un título informando que estamos en la administración del web:
Si arrancamos el servidor y accedemos a la aplicación en éste punto del tutorial accediendo a al siguiente url: http://localhost:8080/SimpleWeb/ veremos que:
  • tenemos acceso al home (pages/home.jsp) de nuestro web a través de la página de inicio, sin necesidad de introducir el usuario y contraseña, y
  • desde la home tenemos acceso a la administración pulsando sobre el enlace.

6. Securizando nuestra aplicación.

En el fichero WebContent/WEB-INF/web.xml añadiremos las siguientes restricciones de seguridad:
El contenido del directorio /pages/* (06. <url-pattern>/pages/*</url-pattern>) será visible a todos los usuarios, independientemente de su perfil (09. <role-name>*</role-name>).

El contenido del directorio /pages/admin/* (16. <url-pattern>/pages/admin/*</url-pattern>) será visible solo para los usuarios con un perfil de administrador (19. <role-name>ADMINISTRATOR</role-name>), donde ADMINISTRATOR es el nombre del perfil en base de datos. Que debe corresponderse con el resultado de la sentencia sql definida en el parámetro rolesQuery del fichero login-config.xml.

En el mismo fichero WebContent/WEB-INF/web.xml añadiremos la definición de los 2 roles que tenemos:
El contenido de los campos <role-name> se corresponde con el nombre de los perfiles en base de datos.

Por último, en el mismo fichero WebContent/WEB-INF/web.xml añadiremos la definición del formulario de entrada de login y contraseña:
Definimos el método de autenticación (a través de formulario), la página de login y la página que aparecerá tras un error en el login.

El método de autenticación puede ser también un diálogo de sistema con <auth-method>BASIC</auth-method>.

Para enlazar el filtro JAAS con el módulo de autenticación de jboss, crearemos un fichero WebContent/WEB-INF/jboss-web.xml con el siguiente contenido:
El nombre de la política de seguridad (simpleWebAuthenticationPolicy) es el definido en el campo <application-policy name=""> del fichero login-config.xml.

Si probamos de nuevo la aplicación veremos como "salta" la página de login al acceder al index:
  • si accedemos con el usuario admin:admin, veremos como tenemos acceso a la página de login y pulsando sobre el enlace accedemos a la página de administración
  • si accedemos con el usuario user:password, veremos como tenemos acceso a la página de login y pulsando sobre el enlace aparecerá un error de autorización, porque no forma parte del perfil de administradores.
      Estado HTTP 403 - El acceso al recurso pedido ha sido denegado
      

7. Obtención el usuario y su perfil asociado.

La interfaz HttpServletRequest nos proporciona dos métodos para acceder a información sobre el usuario autenticado:
  • getUserPrincipal: devuelve el usuario conectado,
  • isUserInRole: recibe como parámetro un string y devuelve un boolean, true si el usuario pertenece al rol que se pasa como parámetro,
Vamos a modificar la página pages/home.jsp para ocultar el enlace hacía la administración si el usuario no tiene un perfil de administrador, y para mostrar el name del usuario.

8. Integración en la librería de componentes jsf de Apache Tomahawk.

Si estamos trabajando con la implementación de jsf de myfaces y añadimos a nuestra librería de tags la extensión de Apache Tomahawk, podremos comprobar como uno de los atributos de los tags es visibleOnUseRole.

Vamos a modificar la página pages/home.jsp:. El atributo visibleOnUserRole puede recibir varios perfiles separador por comas.

9. Conclusiones.

¿Para qué vamos a implementar un mecanismo de autenticación y/o autorización propio, si tenemos uno dentro del estándar JEE?. Si además, es relativamente fácil de configurar...

Para ampliar información sobre éste tutorial consultad el Capítulo 8 (Seguridad) del manual de Jboss:
  • buscar org.jboss.security.auth.spi.LdapLoginModule: para ver cómo configurar la seguridad contra un servidor LDAP,
  • buscar org.jboss.security.auth.spi.UsersRolesLoginModule: para ver cómo configurar la seguridad a través de ficheros de propiedades.
También podéis revisar éste tutorial de Roberto Canales sobre Seguridad en Tomcat.

Una reflexión para terminar: "Para entrar en casa ajena puedes, echar la puerta abajo a patadas (con más o menos perseverancia) o, simplemente mirar debajo del felpudo para ver si el dueño deja ahí una copia de sus llaves".

Un saludo.

Jose

A continuación puedes evaluarlo:

Regístrate para evaluarlo

Por favor, vota +1 o compártelo si te pareció interesante

Share |
Anímate y coméntanos lo que pienses sobre este TUTORIAL:

Fecha publicación: 2013-09-26-23:17:14

Autor: ingwilliam1

Hola que tal muy bien tutorial solo que tengo un problema al securizar la aplicacion, me logueo y me aparece la leyenda usuario o contrasena incorrecta, alguien tendra de casualidad el codigo fuente que me pudiera facilitar ya revise todo y sigue sin funcionar saludos...

Fecha publicación: 2013-03-31-18:03:49

Autor: lflores

Hola cómo estás, excelente tutorial, justamente ahora estoy tratando de implementar la seguridad en Java EE y me viene muy bien. Tengo una duda bien grande, estoy haciendo una aplicación en donde los roles se deben crear desde la misma aplicación, así como también los permisos que se asignen deben ser desde la misma aplicación. Es decir, no sólo debo contar con dos roles y permisos predefinidos, sino que estos deben ser dinámicos y el que use el sistema debe elegir qué roles hay y qué permisos asignarles. Cómo haría esto con JAAS, es posible, me pueden dar alguna idea. Recalco que estoy empezando en esto y tengo muchas dudas, me pueden ayudar...necesito implementar la seguridad de forma dinámica para mi tesis, ayúdenmen con sus ideas.

Fecha publicación: 2011-12-07-16:54:16

Autor: jcarmonaloeches

Un tutorial muy bueno y práctico. Muchas gracias

Fecha publicación: 2011-05-26-18:41:04

Autor: ecalle

UN MOMENTO AVER UNA PREGUNTA PREVIA DIGANME EL TUTO FUNCIONARA BIEN BAJO EL NETBEANS 6.9.1 Y GLASSFISH 3.1

Fecha publicación: 2011-04-26-11:50:06

Autor: leobenitez

Hola de nuevo!
sigo con el problema con imagenes y css.

Mi estructura es la siguiente:

web
-css/
--style.css
-images/
--logo.jpg
-protected/
--home.jsp
-login.jsp
-error.jsp
-index.jsp

También he probado metiendo los directorios de imagenes y css dentro de la carpeta protected y tampoco me funciona.

¿Alguna sugerencia? ¿Qué estoy haciendo mal?

Gracias!!!

Fecha publicación: 2011-04-22-00:47:49

Autor: jmsanchez

Muchas gracias por todos los comentarios.

Efectivamente, hay que tener cuidado con el nombre de los roles.

En cuanto a la personalización de los estilos de la página, sí se pueden personalizar, será un problema tuyo con las rutas relativas a los ficheros de recursos (css e imágenes).

Un saludo.

Jose.

Fecha publicación: 2011-04-20-14:01:34

Autor: leobenitez

Hola!
Gran tuto pero tengo una duda:

¿No se puede personalizar el fichero login.jsp con algun css y usar imagenes?

Utilizo imagenes y no las carga y tampoco me carga los estilos que tengo en el fichero css.

Fecha publicación: 2011-04-05-01:02:58

Autor: yernikx

Excelente tuto gracias, les dejo una observación:

En la política definen el rol ADMINISTRATOR:

<auth-constraint>
<role-name>ADMINISTRATOR</role-name>
</auth-constraint>

Mientras que en la BD, definieron el rol ADMINISTRADOR ;)

Fecha publicación: 2009-08-31-08:18:13

Autor:

[Gomer] Muy bueno el tutorial, felicitaciones... :D

Fecha publicación: 2009-08-11-08:57:36

Autor:

[Armando ] Es muy Bueno, detallado... me sirvio de mucho

Fecha publicación: 2009-08-03-05:23:42

Autor:

[Mauricio] Estuve una semana buscando un material asi , es unico en la red Muchisimas gracias al autor de este documento.

Fecha publicación: 2009-07-27-10:14:06

Autor:

[Karen Martelo] Un excelente recurso.... comprendido y aplicado!

Fecha publicación: 2008-06-21-11:37:34

Autor:

[macauli] el mejor que hay en la red (incluyendo inglés, español y demás idiomas) gracias al autor

Fecha publicación: 2008-04-16-02:56:51

Autor:

[Juan] Muchas gracias, el material es muy práctico.