¿Cómo auditar usuarios en registros con Spring Security?
En el mundo del desarrollo de software, auditar cambios en bases de datos es crucial para garantizar la integridad y seguridad de la información. Anteriormente, en Platzi, aprendimos a auditar fechas de creación y modificación en nuestras aplicaciones con Spring Data JPA. Ahora, gracias al curso de Spring Security, daremos un paso más allá, implementando una auditoría más detallada que incluye el usuario que realiza cambios en los registros de nuestra base de datos.
¿Cómo se configura la entidad para auditar usuarios?
Para poder auditar no solo la fecha de creación y modificación, sino también el usuario, debes realizar algunos ajustes en tu entidad. Aquí te explicamos cómo hacerlo utilizando una entidad llamada PizzaEntity.
Anotaciones y Extensiones:
Asegúrate de que PizzaEntity tenga la anotación @EntityListener. Esta debe incluir dos listeners:
AuditPizzaListener: Tu propia implementación de auditoría.
AuditingEntityListener: Proporcionada por Spring para la auditoría estándar.
Asegúrate de validar si la autenticación es nula o si no está autenticado antes de capturar el usuario.
¿Cómo se prueba la auditoría de usuario?
Luego de implementar estos cambios, es vital verificar que todo funcione correctamente:
Generación de JSON Web Token:
Usa una herramienta como Postman para generar un JSON Web Token (JWT) con credenciales válidas.
Pruebas de Creación y Modificación:
Realiza operaciones en la base de datos autenticándote con el token generado.
Prueba la creación de un nuevo registro y verifica que CreatedBy contenga el usuario correcto.
Realiza una modificación y comprueba que ModifiedBy se actualice correctamente.
Verificación en MySQL:
Ejecuta consultas en tu base de datos MySQL para comprobar que los cambios se reflejan correctamente en los registros.
¿Por qué es importante una auditoría detallada?
Implementar una auditoría que incluye usuarios no solo aporta un plus de seguridad a tu aplicación, sino que también permite rastrear acciones específicas en caso de errores o accesos no deseados. Incrementa la transparencia y la confiabilidad del sistema, aspectos esenciales en entornos de producción. Además, optimiza el monitoreo de actividades y facilita la identificación de patrones inusuales o potencialmente peligrosos. ¿Te animas a implementarlo? ¡Asegúrate de probar y depurar tu código a fondo!
¡Sigue adelante con este conocimiento y aplica estas técnicas para mejorar la seguridad y robustez de tus proyectos con Spring!
Hola alejando.. gracias por tu curso, tengo otra pregunta, tengo un proyecto que ya tiene su base de datos y esta siendo utilizada por un proyecto viejo el cual esta en producción, por lo tanto no puedo hacer demasiadas modificaciones en la DB, la pregunta es, al crear mi clase AuditableEntity, como hago para aplicarla en cada entidad en razón a que cada una ya tiene previamente creadas estas columnas?, es decir si extiendo mi clase auditable en cada entidad no quedarian repetidas las columnas dos veces? (createdDate, modifiedDate, createdBy, modifiedBy)
Hola Alejandro espero estés muy bien, genial el curso y esta es la segunda vez que lo veo.. tengo un dilema, estoy migrando un software a nuevas tecnologías y quiero implementar esta auditoria, pero las tablas cuando las crearon les incluyeron por defecto estos campos, es decir ya lo tiene la entidad, y segundo, algunas tablas las crearon con el nombre en inglés y otras con el nombre en español, la pregunta es en ese caso tendria que hacer dos veces cada clase de auditoria una en ingles y otra en español, y lo mejor sería hablar con el cliente para ver si las puedo estandarizar todas?
Gracias
yo te recomiendo manejar todo en inglés, y crea una clase AuditableEntity, ahí ya colocas lo que necesites, como el createdBy, createdAt, updatedBy, updatedAt, etc.
así cuando arranques el programa crearás los campos de auditoria según el entity personalizado que creaste, peeero si la quires en español, crea los atributos de AuditableEntity en español y listo
Auditusername
package com.luigi.pizza.persistence.audit;import org.springframework.data.domain.AuditorAware;import org.springframework.security.core.Authentication;import org.springframework.security.core.context.SecurityContextHolder;import org.springframework.stereotype.Service;import java.util.Optional;@ServicepublicclassAuditUsernameimplementsAuditorAware<String>{ @OverridepublicOptional<String>getCurrentAuditor(){Authentication authentication =SecurityContextHolder.getContext().getAuthentication();if(authentication ==null||!authentication.isAuthenticated()){returnOptional.empty();// Mejor que devolver null}returnOptional.ofNullable(authentication.getName());// Mejor usar .getName()}}
Hola Alejandro ¿cómo estás?
He estado construyendo mi api de base de datos de películas y aún me falta terminar el módulo de seguridad, me he centrado por el momento en terminar los CRUD. He querido aplicar lo visto desde el primer curso que tienes, pero me han resultado errores con el Mapstruct, cuando hago uso del resto de los Mapstructs ya hechos, y me sale por ejemplo:
Cannot invoke "com.movie.moviedb.persistence.mapper.GenreMapper.toGenre(com.movie.moviedb.persistence.entity.GenreEntity)" because "this.genreMapper" is null
Al parecer no encuentra la instancia, pero no hallo más forma de hacer que entre al contexto de la App. Hasta le he colocado @Component, y nada.
Se me repitió el código del MovieMapper, disculpas por eso.
Buenos dias con todos no se si alguien me puede orientar para poder enviar el token generado pero en el body mas no en el header de antemano agradezco su comprension que tengan un buen dia
Podrías llamar desde el controller el servicio que genera el token y crear un objeto que responda con el nuevo token.
Normalmente los controller llaman los componentes de tipo servicio entonces no abría problema
Porque cuando da 403 0 401 no muestra error, sino que la respuesta de la peticion solo está vacia? Hay alguna forma para amanejar esas excepciones?
Porque si hago un update de una pizza que tiene un usuario que la creo este no persiste, igualmente pasa con las fechas de creación y de actualización, se borran y quedan en null y solo quedan los datos de actualización.
Hola Ricardo, a mi me funcionó poner el campo de la fecha de creación como updatable=false, con eso tiene, puedes hacer lo mismo en el de usuario, los datos de actualización si deben ser actualizables.