Como se hace el control de acceso de múltiples usuarios, a una webapp que utiliza Hibernate si solo se tiene una sessionFactory?

Como se hace el control de acceso de múltiples usuarios, a una aplicación web que utiliza Hibernate para conectarse a una Base de Datos MySql, si solo se tiene una sessionFactory en la aplicación...???

Hola, estoy haciendo una aplicación web utilizando NetBeans como IDE, y Tomcat 6 como Server, sin conocer Hibernate y siguiendo los manuales disponibles en la red, lo implemente en la aplicación y me sentía contento de haber logrado hacer la conexión y las consultas, pero como es muy común en este trabajo, salimos de un problema para entrar a otro.

Tratare de explicar claramente el problema que a mi entender estoy teniendo y no encuentro como resolverlo:

Lógicamente tratamos de acceder a la aplicación desde un cliente, en mi caso Internet Explorer, en la primera página de la aplicación se solicita usuario y clave para acceder a la aplicación, este usuario y clave los paso como parámetros para iniciar la fábrica de sesiones de la siguiente forma:

annConfig = new AnnotationConfiguration().configure();
annConfig.setProperty("hibernate.connection.username", user);
annConfig.setProperty("hibernate.connection.password", passwrd);
sessionFactory = annConfig.buildSessionFactory();

aquí reviso si el usuario sessionFactory ha logrado conectarse a la BD con ese usuario y password.

una vez que la fábrica de sesiones a logrado hacer la conexión correctamente
podemos solicitar sesiones y transacciones a la fábrica de sesiones, (en todos los ejemplos de los manuales que revise, se hace una sola fabrica de sesiones por BD, como yo solo tengo una BD MySQL, solo creó una sessionFactory para toda la aplicación) y podemos hacer las consultas y etc con HQL.

Pero si una vez que la aplicación ya tiene construida su sessionFactory, desde otro cliente accedemos a la aplicación, este nuevo usuario solamente solicitara una sesión a la fábrica de sesiones, y la sesión entregada hace uso de los permisos del usuario que construyo la fábrica de sesiones, no de quien está solicitando la sesión, así que si quien está solicitando la sesión no tiene permisos ni siquiera de conexión, no se revisa. La pregunta es,

Como le hago para que el usuario y contraseña de quien está solicitando una sesión para hacer una transacción, sea validado por la sessionFactory para que se le permitan hacer las operaciones a las cuales tiene permisos en la BD, o sea, como se hace el manejo de múltiples usuarios de una BD por medio de una sola sessionFactory utilizando Hibernate...???

o acaso hay que construir una sessionFactory por cada usuario que quiera conectarse a la aplicación...??? seguro hay otra solución... les agradeceré mucho su ayuda.

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de ezamudio

Alternativas

La respuesta simple a tu pregunta Como le hago para que el usuario y contraseña de quien está solicitando una sesión para hacer una transacción, sea validado por la sessionFactory para que se le permitan hacer las operaciones a las cuales tiene permisos en la BD, o sea, como se hace el manejo de múltiples usuarios de una BD por medio de una sola sessionFactory utilizando Hibernate...??? es: no se puede.

Al parecer tienes una aplicación donde cada usuario tiene una cuenta en la base de datos. Supongo que entonces es una intranet o algo así, con un número reducido de usuarios. Si bien las bases de datos contienen lo necesario para llevar algo de seguridad como permisos de lectura y modificación sobre tablas para los distintos usuarios, así como el acceso a distintas bases de datos, etc, no creo que sea recomendable usarlo como infraestructura de seguridad en una aplicación que va a estar abierta a muchos usuarios.

Si realmente va a ser para pocos usuarios y la manera en que quieren controlar el acceso es por medio del usuario y password en la base de datos, entonces cada sesión en la aplicación debe tener su propio SessionFactory con su propio DataSource debajo, porque cada DataSource necesita conectarse a la base de datos con los datos del usuario dueño de la sesión.

Si en cambio estás pensando en una aplicación como este sitio, donde puede haber una gran cantidad de usuarios, lo recomendable es que tengas una sola SessionFactory conectada a la base de datos con un usuario y password que tiene acceso a todo lo que necesita la aplicación para funcionar. El usuario de base de datos corresponde a la aplicación, no a un usuario de la aplicación. Y como parte de la aplicación deberás tener un esquema de seguridad basado en Acegi o la seguridad que maneje el contenedor o Spring Security o tu propio esquema de seguridad con tu tabla de usuarios donde buscas si el usuario existe y validas que su password sea correcto, etc. Esto es lo que normalmente se maneja en aplicaciones web.

Gracias por la respuesta, en

Gracias por la respuesta, en realidad soy nuevo en la programación web, y la ayuda y comentarios de personas que saben del tema ayudan a retomar el camino correcto, porque ya me estaba desviando mucho buscando alternativas. El numero de usuarios sera de 100 para arriba, entonces yo puedo poner un esquema de seguridad en la propia aplicación, pero esto significa que los permisos que tienen los diferentes usuarios a distintas tablas de la base de datos se tienen que manejar también desde la aplicación…???

Y otra cosa, tendrás a la mano un buen link para conocer acerca de “Acegi”, porque de verdad que ni siquiera había oído mencionarlo…???

Tampoco estoy usando “Spring Security”, debería usarlo...???

En realidad las paginas las estoy haciendo con simples JSP’s, como decía, soy nuevo en la programación web, y no quiero revolver los temas, pero he visto apenas que existe JSF como frame, esto me ayudaría también al control de accesos o ya es otro tema…???

Te agradezco mucho la respuesta….

Imagen de ezamudio

GIYF

Con más de 100 usuarios, se va a volver una pesadilla manejar los permisos de los usuarios en la base de datos. Además, si tienen muchos perfiles distintos y cada uno tiene que realizar solamente ciertas acciones, es mejor que manejes todo ese control de accesos a nivel aplicación; de otra forma, en la aplicación todo mundo puede intentar hacer lo que sea y hasta que tu código intercepte una SQLException la vas a tener que interpretar muy bien para ver si fue problema de que no hay conexión a la base de datos, de que se violó una regla de integridad (columnas nulas en un insert/update, delete de un maestro sin cascada a los detalles, etc) o si es un problema de que el usuario no tiene permiso para realizar la acción. En cambio si manejas los permisos a nivel aplicación, puedes ocultar o mostrar ciertos elementos de la interfaz (ligas, botones, campos de texto, etc) dependiendo de lo que el usuario pueda hacer.

Google Is Your Friend. Busca Acegi; el primer resultado es este. Actualmente ya Acegi y Spring Security son la misma cosa. Echale un ojo y decide si te conviene usarlo. Yo no puedo contestarte esa pregunta porque depende de varios factores en tu proyecto que yo no conozco (ni quiero conocer), como el número de personas desarrollándolo, planes a largo plazo para mantenerlo, actualizarlo, si va a ir por fases o no, etc.

La ayuda proporcionada es

La ayuda proporcionada es suficiente. Muchas gracias y felicidades por el foro....

Re: GIYF

Advertencia: mi sugerencia es que hagas lo que dice ezamudio. Ahora sí, la contrapropuesta:

Con más de 100 usuarios, se va a volver una pesadilla manejar los permisos de los usuarios en la base de datos.

Como dicen en mi pueblo, "antes al contrario". Una base de datos decente ya tiene todo lo necesario para manejar usuarios, roles, permisos sobre tablas, bitácora, es seguridad a la que no se le puede dar la vuelta. Si la seguridad se pone fuera de la base de datos, entonces tiene que programarse aplicación por aplicación, y si una aplicación no la implementa... o si alguien abre una terminal directo a la BD... En fin, es una línea de pensamiento a contrapelo de la práctica común en Java.

Para quien quiera asomarse a una perspectiva distinta acerca de por qué es buena idea implementar la seguridad a nivel base de datos, esta discusión es reveladora:

Los que usen WebLogic y WebSphere, estos servidores de aplicaciones *ya incluyen* su propio framework de seguridad. El de WebLogic inclusive se integra con Acegi.

Saludos

Javier Castañón

Imagen de ezamudio

pero mira quien habla...

y no me refiero a ti Javier, sino al tal Tom. En un sitio de Oracle, sugieren que uses la seguridad de Oracle? quién lo iba a pensar? y que te amarres a ese mecanismo completamente dependiente de la base de datos, para que ya nunca puedas migrar a ninguna otra cosa tu sistema, porque resulta que en otro RDBMS es muy distinto el rollo de los usuarios y permisos y ya toda tu app está hecha para manejar los roles de Oracle? wow. Impensable...

En cuanto a lo que mencionas de que se tiene que poner aplicación por aplicación la seguridad... si sabes que vas a hacer más de una aplicación (aunque no de entrada, con que exista la remota posibilidad de que en el futuro agreguen aplicaciones) es suficiente razón para que desde el principio diseñen la seguridad pensando en que los componentes deben utilizar algun tipo de framework que trascienda las apps para que se use lo mismo en todas.

En lo que creo (o al menos espero) que todos estamos de acuerdo es que la seguridad debe ser parte del diseño de la aplicación desde el principio; si se agrega después resulta muy engorroso y por lo general termina siendo ineficiente y muy vulnerable.

Re: pero mira quien habla...

Edit: La independencia respecto de la base de datos no debe verse como un principio universal de diseño/implementación, sino como la respuesta a un requerimiento denominado "portabilidad".

En un sitio de Oracle, sugieren que uses la seguridad de Oracle? quién lo iba a pensar? y que te amarres a ese mecanismo completamente dependiente de la base de datos, para que ya nunca puedas migrar a ninguna otra cosa tu sistema, porque resulta que en otro RDBMS es muy distinto el rollo de los usuarios y permisos y ya toda tu app está hecha para manejar los roles de Oracle?

Je, je. Buena observación, pero no nos desviemos de mi comentario original, donde llamé a ver las cosas desde una perspectiva distinta, a pensar fuera de la caja diseñada por Sun hace años:

  1. No niego que hay casos específicos donde es deseable o hasta necesaria la independencia de la base de datos. Apuesto que es en la minoría de los casos.
  2. Estoy convencido que el que usa una base de datos como Oracle, DB2, MS SQL, Firebird, PostgreSQL, etc. y no le saca provecho a sus características propietarias es un muppet :-) Deje de pagar licencias y/o complicarse la vida, use algo más sencillito como MySQL, Derby, o SQLite. Esas cosas adicionales como roles, logging, definición de dominios, tipos definidos por el usuario, etc. ¡son superfluos! Les juro que en casos extremos me he encontrado con consultores Java que recomendaron no utilizar integridad referencial. Es un caso extremo, pero lo he visto.
  3. De verdad, en serio, ¿cuántos que no sean un ISV necesitan codificar una aplicación independiente de la base de datos? Me parece absurdo usar bases de datos relacionales como si fueran archivos ISAM con una interfaz SQL (MySQL anyone?) Un Independent Software Vendor (ISV), por ejemplo, alguien que desarrolla y comercializa un sistema de nómina le conviene la independencia de la BD porque abre su mercado.
  4. ¿Un framework de seguridad común? Me gustaría verlo, sería independiente de la base de datos pero ¿dependiente del lenguaje de programación? ¿dependiente de Java? Interesante compromiso, funcionará siempre que use sólo Java, o sólo PHP para acceder a la base de datos ;-) Además, nunca falta quien abra una sesión por medio de una terminal directamente a la BD: encueradita, sin seguridad. ¡Bien!
  5. He podido atestiguar más cambios de frameworks web, DAOs, ORMs, etc. que de bases de datos. Las bases de datos por lo general duran mucho más años que las aplicaciones que las accesan: aplicaciones van, aplicaciones vienen, los datos generalmente permanecen en la misma base de datos.

Por lo tanto, yo, Javier Castañón declaro hoy 13 de noviembre de 2009, día de la dependencia de la base de datos (aplican condiciones)

Edit: Hay quienes por defecto siempre ponen en su lista de requerimientos "portabilidad", así sin más ni más, convirtiéndola precisamente en un principio universal de diseño/implementación.

Saludos

Javier
Resident Dinosaur
PD Por favor, los principiantes, hagan la seguridad como dice ezamudio, en la aplicación Java.

Seguridad de datos vs. seguridad de funcionalidad

En cuanto a lo que mencionas de que se tiene que poner aplicación por aplicación la seguridad... si sabes que vas a hacer más de una aplicación

Mmmhh, pasé por alto que esto se desviaba también de la idea original (mi culpa) y confunde gimnasia con magnesia. Sorry. Una base de datos tiene todo el alambrado necesario para manejar usuarios y roles y así proteger los *datos* y en ese sentido no tiene por qué volverse una monserga manejar cientos o miles de usuarios. El tema de Tom Kyte es mantener usuarios para realizar autenticación además de la protección de los datos. Esto no me parece que sea demasiado intrusivo en el código de la aplicación. La seguridad de la *funcionalidad* (que no de los datos), por supuesto debe programarse en la propia aplicación.

Pero podríamos seguir con el tema de si es anatema o no amarrarse a una base de datos, ¿no? ;-)

Saludos

Javier