Auditando Liferay DXP: ¿Quién ha hecho qué y cuándo?

Notice: This blog post is in Spanish. Click here to read it in English


Son varias las ocasiones en las que algún cliente nos ha preguntado, una vez sucedida una acción en el Portal (más o menos drámatica), cómo poder ver cuándo se realizó dicha acción y sobre todo, quién la realizó.

Para ayudarnos ante estos escenarios, Liferay DXP nos aporta Audit.

 

¿Qué es Audit?

Audit es una feature disponible dentro de Liferay DXP mediante la cual podremos registrar eventos realizados sobre las entidades en Liferay. Éstas pueden ser propias del producto o bien custom (empleando Service Builder para su desarrollo).

 

¿Qué tipo de acciones nos permite auditar?

Podremos auditar cualquier tipo de acción que se realice sobre las entidades de nuestra instancia de Liferay DXP, como por ejemplo acciones de añadido, actualización, borrado, login… De dichas acciones podremos obtener el usuario que la realizó, el recurso sobre el que se realizó la acción, el tipo de acción, IP, fecha de realización, sessionId, entre otros. 

¿En qué parte de Liferay DXP se utiliza?

Audit se utiliza en el propio producto Liferay DXP 7.2 OOTB para auditar las entidades User, UserGroup, entre otras.

Con una instalación por defecto de Liferay DXP 7.2, accediendo a Panel de Control > Configuración > Audit, podrás ver los acciones auditadas.

Dispondremos de una búsqueda avanzada para poder filtrar nuestros resultados:


¿Cómo funciona?

El punto de enganche entre Audit y las entidades que queremos que sean auditadas se realiza a través de la implementación de un ModelListener de la interfaz que modela la misma entidad, donde se implementan los métodos onBefore<Acción> y onAfter<Acción> que son disparados antes/después de la llamada a la capa de persistencia. Es en la implementación de estos métodos donde haremos uso de la API de Audit, donde construiremos un mensaje y lo enrutaremos. Para enrutar estos mensajes, por defecto, disponemos de un enrutador denominado DefaultAuditRouter que implementa la interfaz AuditRouter, el cual nos realiza el volcado a ficheros de log los eventos o bien nos persiste en base de datos estos eventos auditados. Tanto el volcado a ficheros de log, como la salida por consola o persistencia en base de datos es configurable desde el Panel de Control en la sección Audit. Como todo en el Mundo Liferay, esto es completamente adaptable y extensible, por lo que podremos crear nuestros propios procesadores y enrutador con el fin de adaptarlo a necesidades más exigentes.
 

¿Qué ejemplos podemos ver que pueda tener sentido auditar?

Un caso muy común es el auditado del borrado de páginas en un sitio web. Por ejemplo, podríamos utilizar Audit para registrar quién y cuándo ha borrado una página Home (o principal) de un sitio web, notificándonos por email la acción y guardando ese registro de evidencia en base de datos, además de volcarlo a un fichero de log que incluso luego podamos indexar utilizando ElasticSearch y manejar desde Kibana. Para este caso, he desarrollado el siguiente módulo OSGi que auditará el añadidoactualización y borrado de las páginas de un sitio web.

Cuando se añade una página, se registran todas las propiedades de un evento (cuándo se ha añadido, quién lo ha añadido), los indicados en la construcción del mensaje y una serie de campos que he decidido relevantes para auditar: groupNamegroupIdnamefriendlyURL y layoutId.

Cuando se actualiza una página, se registran todas las propiedades de un evento (registra cuándo se ha realizado la acción y quién la ha realizado), los indicados en la construcción del mensaje pero esta vez he decidido sólamente que se registre dicha actualización cuando una de las siguientes propiedades se ha modificado: name y friendlyURL. Por tanto, si se modifica una página, añadiendo por ejemplo alguna propiedad de SEO, esta acción no será registrada como una actualización en Audit.

Cuando se realiza el borrado de una página, se registra el borrado de la misma y de las propiedades que he decidido relevante auditar de la entidad. Además, si la página es Home (o principal) de un sitio web, se enviará un correo de notificación de la acción.

Otro caso podría ser el de auditar el borrado de los Contenidos Web. Estos tienen implementado, por defecto, un completo sistema de versionado, además del uso del framework de la papelera de reciclaje para revertir acciones de borrado. Pero si queremos tener ese registro exhaustivo de, quién borró definitivamente esos contenidos web y cuándo, ésta sería una posible forma de realizarlo. Para este caso he desarrollado el siguiente componente OSGi que auditará la acción de mover a la papelera de reciclaje los contenidos web, además del borrado de los mismos.

Al igual que los Contenidos Web, los documentos creados desde la Document Library disponen de un control de versiones y papelera de reciclaje, pero podría ser interesante realizar el auditado de acciones de borrado sobre un tipo concreto de documento. Para ello, he desarrollado el siguiente módulo OSGi donde en el caso de mandar a la papelera de reciclaje o borrar definitivamente un documento de tipo myCustomDLEntryType, se registre tal acción usando Audit.


¿Dónde configuro Audit?

Accediendo al Panel de Control > Configuration > System Settings > Audit podremos configurar todo lo relacionado con Audit: activarlo/desactivarlo, configuración relacionada con el LoggingProcessor y formatter utilizado (CSV o JSON), qué columnas queremos volcar, imprimirlo también por consola, persistir los eventos en base de datos, etc.

En mi caso, he configurado Audit, con persistencia en base de datos además de volcado en log con formato CSV, sin salida por consola:

Pero además he configurado Log4j para volcar las trazas INFO al log [LIFERAY_HOME]/logs/audit.yyyy-MM-dd.log bajo la clase com.liferay.portal.security.audit.router.internal.LoggingAuditMessageProcessor

Para ello he creado el siguiente xml en [LIFERAY_HOME]/tomcat-[version]/webapps/ROOT/WEB-INF/classes/META-INF/portal-log4j-ext.xml

Seguidamente, he configurado el stack ELK (ElasticSearch, Logstash y Kibana) con el fin de indexar y consultar los logs volcados a [LIFERAY_HOME]/logs/audit.* .De este modo puedo auditar el sistema desde fuera de Liferay DXP y crear un histórico de la monitorización, gráficos, etc.


Es interesante, pero… todo con control mejor

En el caso de disponer de la persistencia en base de datos activada, el auditado de eventos sobre nuestras entidades puede acabar generando una tabla AuditEvent en Liferay de tamaño inmanejable, por lo que es recomendable poner un control sobre la misma. El cómo mantener los registros en la misma, será una decisión a evaluar para cada caso concreto, dependiendo del volumen que pueda alcanzar y del interés que pueda haber de almacenar esos registros en base de datos.

Como solución al mantener la tabla de eventos auditados, podría usarse un scheduler el cual vaya vaciando periódicamente la tabla según unos criterios de fecha de creación de los mismos. Para este caso concreto, he desarrollado el siguiente scheduler que se ejecuta cada 3 meses y borrará los registros con fecha de creación anterior a 3 meses, dejando siempre un historial de los últimos 3 meses con el fin de poder consultar un histórico reciente.

En el caso de mantener el volcado a log, es recomendable mantener un sistema de rotación de logs adecuado con el que mantener el espacio en disco. Además si se opta por la opción de indexarlos en ElasticSearch, es recomendable mantener con control un histórico de estos índices. Para ello podemos apoyarnos en el uso de la utilidad ElasticSearch-Curator con el fin de realizar el borrado de índices de un determinado patrón y ejecutar ese borrado mediante un crontab adecuado al histórico que queramos mantener.

 

Todo tiene un precio: rendimiento

El sistema de auditado no deja de ser persistencia sobre la base de datos y acceso + escritura a ficheros de log, con el consumo de recursos que en líneas generales estas acciones acarrean.

Aunque puede realizarse tanto el volcado a log como la persistencia en base de datos de los eventos auditados al mismo tiempo, suele ser recomendable realizar uno de los dos mecanismos, con el fin de consumir menos recursos. Además es recomendable realizar pruebas de rendimiento con vistas a comprobar que el Sistema no sufre un degradado de rendimiento excesivo a causa de un auditado descontrolado.

Al igual que los procesadores llamados por el enrutador que incluye Liferay DXP 7.2 por defecto, LoggingAuditMessageProcessor y PersistentAuditMessageProcessor, son configurables desde el Panel de Control, tanto para su activación/desactivación como para configurar sus propiedades, es recomendable aplicar mecanismos de activación/desactivación a nuestros MessageProcessor o incluso a las acciones que se puedan desencadenar desde el Listener con el fin de poder activar/desactivar los procedimientos de auditoría si fuese preciso.

En el caso del desarrollo realizado para auditar las páginas, he implementado un mecanismo de activación/desactivación con el fin de poder deshabilitar por completo el auditado que realiza el Listener, desactivando incluso el envío por correo y el volcado a log/persistencia en base de datos (independientemente de si está habilitada la opción para cada uno de ellos en el Panel de Control)


Conclusión

Liferay DXP nos otorga OOTB la potente funcionalidad para poder registrar todas las acciones sobre las entidades, tanto de producto como a medida.

La forma de auditar nuestras entidades, además del procesamiento de los mensajes de auditoría, dependerán mucho de cada caso, pero teniendo en cuenta estas bases, será ágilmente implementable prácticamente cualquier solución.