Autenticacion de usuarios en Java con MySQL || (Entrega 1)
6 junio 2013 28 comentarios
Dividi este articulo en varias partes debido al tamaño del ejemplo, espero que si te interesa sigas visitandome para motivarme a seguir escribiendo la siguiente parte pues en la ultima entrega de este articulo podrás solicitar todos los archivos fuente.
Introduccion
Cuando hablamos de autenticacion de usuarios, es común abordar el tema de Roles de usuario. Un Rol es una clasificación mediante la cual se definen distintos privilegios de operación para los usuarios del sistema, de tal forma que cada usuario tiene asignado un rol (conjunto de operaciones que puede realizar). Los Roles se encuentran predefinidos en el sistema, cada sistema en particular define los permisos que tiene cada Rol, es en la parte de diseño cuando al personal de desarollo del proyecto se le dan las especificaciones de cada Rol.
Por ejemplo, si se esta diseñando un sistema para una cadena de tiendas el cual llevara el control de ventas, empleados, pedidos, etc. es el dueño de la cadena de tiendas (o un delegado) el que le indica al equipo de desarollo lo que cada empleado puede realizar y quienes tendrán una credencial de acceso.
En este ejemplo se han creado 3 roles: Administrador, Supervisor y Operador. Los permisos que incluye cada rol serán descritos cuando se este diseñando la base de datos.
Sin mas preámbulos a continuacion empezare a describir el ejemplo, pero como dijo Jack el destripador, vayamos por partes…
Herramientas necesarias
Para realizar y probar este ejemplo necesitas de algunas herramientas de software, a continuacion voi a listarlas por lo que de aqui en adelante dare por hecho que ya las tienes instaladas y configuradas en tu lap o computadora de escritorio:
- MySQL 5 o superior
- Una JVM (jdk 5 o superior)
- J/Connector de MySQL
Para no desviarme del tema central (autenticar usuarios) no voi a detenerme a explicar como se instalan o configuran, ademas de que me llevaria mucho tiempo explicar cada una. Supongo que si estas leyendo esto es porque ya los tienes o al menos tienes una idea vaga de para que sirven o como instalarlas.
Configuracion de la aplicacion
Los desarrolladores pueden utilizar uno o varios archivos de texto para establecer directivas que afectan el
funcionamiento de la aplicacion. En vez de usar archivos se pueden utilizar tablas de la base de datos.
Al conjunto de todas estas directivas en el archivo(s) o tabla(s) se le llama configuracion de la aplicacion.
Algunas de las configuraciones que se pueden guardar son:
- Maximo numero de veces que un usuario puede intentar hacer login.
- Tiempo que debe pasar para que la contraseña de los usuarios caduque y deje de ser valida.
- Maximo numero de sesiones activas por usuario.
- Tiempo maximo que una sesion puede estar inactiva sin cerrarse automaticamente.
- Tiempo que debe ser bloqueado un usuario por exceder el maximo de intento fallidos.
- Etc.
En este ejemplo de autenticacion usare una tabla para guardar toda la configuracion de la aplicacion. Se pueden crear el numero de directivas que sea, por lo general esto esta en funcion de los requerimientos de cada aplicacion. En mi caso esta en funcion de mi imaginacion pues este es un ejemplo ficticio :D.
En este ejemplo muchas de las directivas sera usadas en el proceso de Login.
Diseño de la Base de Datos
A continuacion copio y pego las sentencias SQL para recrear las tablas que se usaran el ejemplo:
create table cat_TiposUsuario( id_TipoUsuario integer auto_increment not null , tx_TipoUsuario char(60), primary key(id_TipoUsuario) ); insert into cat_TiposUsuario(tx_TipoUsuario) values ('Administrador'); insert into cat_TiposUsuario(tx_TipoUsuario) values ('Supervisor'); insert into cat_TiposUsuario(tx_TipoUsuario) values ('Operador'); insert into cat_TiposUsuario(tx_TipoUsuario) values ('Otro'); create table cat_StatusUsuario( id_StatusUsuario integer auto_increment not null , tx_StatusUsuario char(60), primary key(id_StatusUsuario) ); insert into cat_StatusUsuario(tx_StatusUsuario) values ('Activo'); insert into cat_StatusUsuario(tx_StatusUsuario) values ('Bloqueado'); insert into cat_StatusUsuario(tx_StatusUsuario) values ('Eliminado'); create table cat_TiposBloqueo( id_TipoBloqueo integer auto_increment not null , tx_TipoBloqueo char(60), primary key(id_TipoBloqueo) ); insert into cat_TiposBloqueo(tx_TipoBloqueo) values ('Bloqueo Permanente'); insert into cat_TiposBloqueo(tx_TipoBloqueo) values ('Bloqueo Temporal'); create table tbl_Usuarios( id_Usuario integer auto_increment not null , tx_username char(30), tx_password char(50), tx_Nombre char(50), tx_ApellidoPaterno char(50), tx_ApellidoMaterno char(50), tx_Email char(50), id_TipoUsuario int, id_StatusUsuario int, id_UsuarioAlta int, dt_FechaRegistro datetime, dt_UltimaModificacionUsuario datetime, dt_UltimaModificacionPw datetime, primary key(id_usuario), foreign key(id_TipoUsuario) references cat_TiposUsuario(id_TipoUsuario), foreign key(id_StatusUsuario) references cat_StatusUsuario(id_StatusUsuario) ); insert into tbl_Usuarios( tx_username ,tx_password,tx_Nombre, tx_ApellidoPaterno,tx_ApellidoMaterno,tx_Email,id_TipoUsuario, id_StatusUsuario,id_UsuarioAlta,dt_FechaRegistro,dt_UltimaModificacionUsuario,dt_UltimaModificacionPw ) values ( 'gonzasilve','cc03e747a6afbbcbf8be7668acfebee5', 'Gonzalo','Silverio','Silverio','gonzasilve@gmail.com',1, 1,1, NOW() , NOW() , NOW() ); insert into tbl_Usuarios( tx_username ,tx_password,tx_Nombre, tx_ApellidoPaterno,tx_ApellidoMaterno,tx_Email,id_TipoUsuario, id_StatusUsuario,id_UsuarioAlta,dt_FechaRegistro,dt_UltimaModificacionUsuario,dt_UltimaModificacionPw ) values ( 'xavier_byte','cc03e747a6afbbcbf8be7668acfebee5', 'Xavier','Silverio','Blake','xavier_byte@hotmail.com',1, 2,3, NOW() , NOW() , NOW() ); create table tbl_LogsSesiones( id_logsesion integer auto_increment not null , tx_username char(50), tx_password char(50), tx_ClaveSesion char(50), tx_StatusIntento char(50), i_IntentoFallido int, dt_FechaRegistro datetime, primary key(id_logsesion) ); create table tmp_SesionesActivas( id_sesion integer auto_increment not null , id_Usuario int, tx_ClaveSesion char(50), dt_FechaRegistro datetime, dt_UltimaActividad datetime, primary key(id_sesion), foreign key(id_Usuario) references tbl_Usuarios(id_usuario) ); create table cat_Secciones( id_seccion integer auto_increment not null , tx_NombreSeccion char(100), i_activa int, primary key(id_seccion) ); insert into cat_Secciones(tx_NombreSeccion,i_activa) values ( 'Administracion de usuarios',1 ); insert into cat_Secciones(tx_NombreSeccion,i_activa) values ( 'Conciliaciones',0 ); insert into cat_Secciones(tx_NombreSeccion,i_activa) values ( 'Crear reportes',1 ); insert into cat_Secciones(tx_NombreSeccion,i_activa) values ( 'Reportes de desempeño',1 ); insert into cat_Secciones(tx_NombreSeccion,i_activa) values ( 'Reportes generales',1 ); create table cat_AccionesSecciones( id_AccionSeccion integer auto_increment not null , tx_NombreAccion char(200), i_activa int, id_Seccion int, primary key(id_AccionSeccion), foreign key(id_Seccion) references cat_Secciones(id_Seccion) ); insert into cat_AccionesSecciones(tx_NombreAccion,id_Seccion,i_activa) values ( 'Modificar datos de otro usuario',1,1 ); insert into cat_AccionesSecciones(tx_NombreAccion,id_Seccion,i_activa) values ( 'Modificar sus datos personales',1,1 ); insert into cat_AccionesSecciones(tx_NombreAccion,id_Seccion,i_activa) values ( 'Ver bitacora de sesiones de otro usuario',1,1 ); insert into cat_AccionesSecciones(tx_NombreAccion,id_Seccion,i_activa) values ( 'Ver su bitacora de sesiones',1,1 ); insert into cat_AccionesSecciones(tx_NombreAccion,id_Seccion,i_activa) values ( 'Modificar password de otro usuario',1,1 ); insert into cat_AccionesSecciones(tx_NombreAccion,id_Seccion,i_activa) values ( 'Modificar su propio password',1,1 ); insert into cat_AccionesSecciones(tx_NombreAccion,id_Seccion,i_activa) values ( 'Cambiar el rol de otro usuario',1,1 ); insert into cat_AccionesSecciones(tx_NombreAccion,id_Seccion,i_activa) values ( 'Cambiar su propio rol de usuario',1,1 ); insert into cat_AccionesSecciones(tx_NombreAccion,id_Seccion,i_activa) values ( 'Cambiar el status de otro usuario',1,1 ); insert into cat_AccionesSecciones(tx_NombreAccion,id_Seccion,i_activa) values ( 'Cambiar su status de usuario',1,1 ); insert into cat_AccionesSecciones(tx_NombreAccion,id_Seccion,i_activa) values ( 'Dar de alta a nuevos usuario',1,1 ); insert into cat_AccionesSecciones(tx_NombreAccion,id_Seccion,i_activa) values ( 'Eliminar usuarios',1,1 ); insert into cat_AccionesSecciones(tx_NombreAccion,id_Seccion,i_activa) values ( 'Entrar a seccion',3,1 ); insert into cat_AccionesSecciones(tx_NombreAccion,id_Seccion,i_activa) values ( 'Entrar a seccion',4,1 ); insert into cat_AccionesSecciones(tx_NombreAccion,id_Seccion,i_activa) values ( 'Entrar a seccion',5,1 ); create table tbl_PermisosUsuarios( id_PermisoUsuario integer auto_increment not null , id_Usuario int, id_Seccion int, id_AccionSeccion int null default null, i_permiso int, id_UsuarioAsignacion int, dt_FechaAsignacion datetime, primary key(id_PermisoUsuario), foreign key(id_Usuario) references tbl_Usuarios(id_Usuario), foreign key(id_Seccion) references cat_Secciones(id_Seccion), foreign key(id_AccionSeccion) references cat_AccionesSecciones(id_AccionSeccion) ); insert into tbl_PermisosUsuarios (id_Usuario,id_Seccion,id_AccionSeccion,i_permiso,id_UsuarioAsignacion,dt_FechaAsignacion ) values(1,1,1,1,1,NOW()); insert into tbl_PermisosUsuarios (id_Usuario,id_Seccion,id_AccionSeccion,i_permiso,id_UsuarioAsignacion,dt_FechaAsignacion ) values(1,1,2,1,1,NOW()); insert into tbl_PermisosUsuarios (id_Usuario,id_Seccion,id_AccionSeccion,i_permiso,id_UsuarioAsignacion,dt_FechaAsignacion ) values(1,1,3,1,1,NOW()); insert into tbl_PermisosUsuarios (id_Usuario,id_Seccion,id_AccionSeccion,i_permiso,id_UsuarioAsignacion,dt_FechaAsignacion ) values(1,1,4,1,1,NOW()); insert into tbl_PermisosUsuarios (id_Usuario,id_Seccion,id_AccionSeccion,i_permiso,id_UsuarioAsignacion,dt_FechaAsignacion ) values(1,1,5,1,1,NOW()); insert into tbl_PermisosUsuarios (id_Usuario,id_Seccion,id_AccionSeccion,i_permiso,id_UsuarioAsignacion,dt_FechaAsignacion ) values(1,1,6,1,1,NOW()); insert into tbl_PermisosUsuarios (id_Usuario,id_Seccion,id_AccionSeccion,i_permiso,id_UsuarioAsignacion,dt_FechaAsignacion ) values(1,1,7,1,1,NOW()); insert into tbl_PermisosUsuarios (id_Usuario,id_Seccion,id_AccionSeccion,i_permiso,id_UsuarioAsignacion,dt_FechaAsignacion ) values(1,1,8,1,1,NOW()); insert into tbl_PermisosUsuarios (id_Usuario,id_Seccion,id_AccionSeccion,i_permiso,id_UsuarioAsignacion,dt_FechaAsignacion ) values(1,1,9,1,1,NOW()); insert into tbl_PermisosUsuarios (id_Usuario,id_Seccion,id_AccionSeccion,i_permiso,id_UsuarioAsignacion,dt_FechaAsignacion ) values(1,1,10,1,1,NOW()); insert into tbl_PermisosUsuarios (id_Usuario,id_Seccion,id_AccionSeccion,i_permiso,id_UsuarioAsignacion,dt_FechaAsignacion ) values(1,1,11,1,1,NOW()); insert into tbl_PermisosUsuarios (id_Usuario,id_Seccion,id_AccionSeccion,i_permiso,id_UsuarioAsignacion,dt_FechaAsignacion ) values(1,1,12,1,1,NOW()); insert into tbl_PermisosUsuarios (id_Usuario,id_Seccion,id_AccionSeccion,i_permiso,id_UsuarioAsignacion,dt_FechaAsignacion ) values(1,3,13,1,1,NOW()); insert into tbl_PermisosUsuarios (id_Usuario,id_Seccion,id_AccionSeccion,i_permiso,id_UsuarioAsignacion,dt_FechaAsignacion ) values(1,4,14,1,1,NOW()); insert into tbl_PermisosUsuarios (id_Usuario,id_Seccion,id_AccionSeccion,i_permiso,id_UsuarioAsignacion,dt_FechaAsignacion ) values(1,5,15,1,1,NOW()); create table tmp_UsuariosBloqueados( id_UsuarioBloqueado integer auto_increment not null , id_Usuario int null, tx_username char(50), id_TipoBloqueo int, tiempo int, tx_TipoTiempo char(5), dt_FechaRegistro datetime, primary key(id_UsuarioBloqueado), foreign key(id_TipoBloqueo) references cat_TiposBloqueo(id_TipoBloqueo) ); create table tbl_ConfiguracionApp( id_ConfiguracionApp integer auto_increment not null , tx_ConfiguracionNombre char(50), tx_ConfiguracionDescripcion char(250), ConfiguracionValor int, tx_TipoValor char(5), i_Activo int, dt_FechaRegistro datetime, primary key(id_ConfiguracionApp) ); insert into tbl_ConfiguracionApp( tx_ConfiguracionNombre,tx_ConfiguracionDescripcion,ConfiguracionValor,tx_TipoValor,dt_FechaRegistro,i_Activo ) values ( 'Maximo Intentos Login','Maximo numero de veces que un usuario puede intentar hacer login en los ultimos 30 minutos.',5,'num',NOW(),1 ); insert into tbl_ConfiguracionApp( tx_ConfiguracionNombre,tx_ConfiguracionDescripcion,ConfiguracionValor,tx_TipoValor,dt_FechaRegistro,i_Activo ) values ( 'Caducidad Password','Tiempo que debe pasar para que la contraseña del usuario caduque y deje de ser valida.',1,'meses',NOW(),1 ); insert into tbl_ConfiguracionApp( tx_ConfiguracionNombre,tx_ConfiguracionDescripcion,ConfiguracionValor,tx_TipoValor,dt_FechaRegistro,i_Activo ) values ( 'Tiempo Notificar Password','Tiempo previo a la caducidad de la contraseña para empezar a notificar al usuario que debe cambiarla.',15,'dias',NOW(),1 ); insert into tbl_ConfiguracionApp( tx_ConfiguracionNombre,tx_ConfiguracionDescripcion,ConfiguracionValor,tx_TipoValor,dt_FechaRegistro,i_Activo ) values ( 'Maximo Sesiones Activas','Maximo numero de sesiones activas por usuario.',3,'num',NOW(),1 ); insert into tbl_ConfiguracionApp( tx_ConfiguracionNombre,tx_ConfiguracionDescripcion,ConfiguracionValor,tx_TipoValor,dt_FechaRegistro,i_Activo ) values ( 'Bloquear Usuarios Password Caducada','Al intentar hacer login ¿Se debe bloquear a los usuarios con contraseña caducada?.',1,'bool',NOW(),1 ); insert into tbl_ConfiguracionApp( tx_ConfiguracionNombre,tx_ConfiguracionDescripcion,ConfiguracionValor,tx_TipoValor,dt_FechaRegistro,i_Activo ) values ( 'Id Super Usuario','Id del usuario administrador. Sirve para tomar datos de ese usuario y enviar notificaciones de la aplicacion.',1,'num',NOW(),1 ); insert into tbl_ConfiguracionApp( tx_ConfiguracionNombre,tx_ConfiguracionDescripcion,ConfiguracionValor,tx_TipoValor,dt_FechaRegistro,i_Activo ) values ( 'Tiempo Bloqueo Intentos','Tiempo que debe ser bloqueado un usuario por exceder el maximo de intento fallidos.',1,'hrs',NOW(),1 ); insert into tbl_ConfiguracionApp( tx_ConfiguracionNombre,tx_ConfiguracionDescripcion,ConfiguracionValor,tx_TipoValor,dt_FechaRegistro,i_Activo ) values ( 'Maxima Actividad Sesiones','Tiempo maximo que una sesion puede estar activa.',1,'dias',NOW(),1 ); insert into tbl_ConfiguracionApp( tx_ConfiguracionNombre,tx_ConfiguracionDescripcion,ConfiguracionValor,tx_TipoValor,dt_FechaRegistro,i_Activo ) values ( 'Maxima Inactividad Sesiones','Tiempo maximo que una sesion puede estar inactiva sin cerrarse automaticamente.',20,'min',NOW(),1 );
Ahora explicare brevemente para que se utiliza cada una de las tablas anteriores:
cat_TiposUsuario
Aqui se registran los diferentes tipos de usuarios del sistema, es decir, los Roles de los usuarios. Un Rol es una clasificación mediante la cual se definen distintos privilegios de operación para los usuarios del sistema. Los Roles se encuentran predefinidos en el sistema, como ejemplo se han creado 3 roles y se detallan a continuación:
Administrador
Este rol es el que mas permisos tiene. Tiene permiso para entrar, crear, modificar o eliminar cualquier cosa dentro del sistema. Por ejemplo puede dar de alta otros usuarios (de todo tipo), eliminar usuarios, modificarles el password, dar de altanuevas secciones, ver todos los tipos de reportes, modificar la configuracion de la aplicacion, etc.
Supervisor
Puede: dar de alta a nuevos operadores pero no eliminarlos, Modificar datos personales de operadores, ver todos los reportes, modificar sus datos personales y su password. No puede: eliminar operadores que el no haya dado de alta, crear nuevas secciones, crear supervisores ni administradores
Operador
Puede: modificar sus datos personales y password, ver los reportes de desempeño.
Otro
Este rol es para dar permisos especificos a un usuario; solo los administradores pueden hacer esto.
…En esta tabla pueden darse de alta los roles que se deseen como Manager, Analista, etc.
cat_StatusUsuario
Aqui se registran los diferentes tipos de estados en los que pueden estar los usuarios.
Activo: El usuario puede iniciar sesion.
Bloqueado: El usuario ha sido bloqueado para iniciar sesion, cuando un usuario tiene este estatus entonces éste usuario tiene un registro asociado en la tmp_UsuariosBloqueados en donde se indica el tipo de bloqueo.
Eliminado: Cuando un usuario tenga este estatus no podra iniciar nunca una sesion.
cat_TiposBloqueo
Aqui se indican los tipos de bloqueos que puede tener un usuario. Cuando un usuario tiene estatus ‘Bloqueado’ entonces tiene un registro asociado en la tmp_UsuariosBloqueados, en dicha tabla se indica el tipo de bloqueo (campo id_TipoBloqueo) y pueden ser:
Bloqueo permanente: Por ejemplo, un usuario puede ser bloqueado permanentemente por un administrador o cuando tiene password caducada.
Bloqueo temporal: El usuario no podra iniciar sesion hasta que transcurra el tiempo indicado en la tabla tmp_UsuariosBloqueados->tiempo. Por ejemplo, si un usuario que intenta iniciar sesion muchas veces y excede el maximo de intentos ocurre un bloqueo temporal.
tbl_Usuarios
Aqui se guardan todos los datos personales del usuario, su password (encriptado en md5), su estatus, el usuario que lo dio de alta, La fecha en que se registro y la fecha en que se modifico, etc.
tbl_LogsSesiones
Aqui se guardan los logs de intentos de sesion. Cada vez que un usuario intenta iniciar sesion; independientemente si tuvo exito o no, se guarda un registro en esta tabla.
tmp_SesionesActivas
Aqui se guardan los id de usuarios que tienen un sesion iniciada, igualmente la fecha de inicio de sesion y la ultima vez que tuvo actividad: Ejemplo cuando cambio de una seccion a otra.
cat_Secciones
Aqui se registran todas las secciones que tiene el sistema y si estan activas o no.
cat_AccionesSecciones
Aqui se definen las acciones que se pueden realizar en cada seccion y si estan activas o no.
tbl_PermisosUsuarios
Aqui es donde se le otorgan permisos a los usuarios. Los diferentes tipos de usuarios tienen permisos diferentes dependiendo de su rol (Tipo de usuario en la tabla cat_TiposUsuario).
tmp_UsuariosBloqueados
Aqui es donde se bloquean a los usuarios, cuando un usuario se bloquea permanentemente o temporalmente se registra aqui, igualmente cuando un usuario se marca como eliminado se registra en esta tabla.
tbl_ConfiguracionApp
Aqui se guardan todas las directivas o parametros de configuracion de la aplicacion. Solo el equipo de desarrollo puede dar de alta nuevos parametros e implementarlos para que funcionen (mediante programacion). No importa si se dan de alta nuevas directivas si el equipo de desarrollo no las implementa no sirven para nada.
hasta aqui dejamos esta parte ya en la proxima entrega explicare la logica del proceso de login…
Espero que te haya gustado, te invito a dejarme un comentario con tu opinion o sugerencia.
Hasta pronto,
Saludos
Comentarios recientes