Creación de un plugin de tipo hook en Liferay

En este tutorial vamos a ver la potencia de los hook plugins de Liferay para añadir funcionalidad sin recurrir al entorno de extensión (EXT).

Creación de un plugin de tipo hook en Liferay

0. Índice de
contenidos.

1. Introducción

Los plugins de tipo hook (“gancho”) se utilizan en Liferay para añadir determinada funcionalidad cuando se producen ciertos eventos. Estos eventos donde podemos enganchar funcionalidad son:

  • Application Startup Events (application.startup.events)
  • Login Events (login.events.pre, login.event.post)
  • Service Events (servlet.service.events.pre, servlet.service.events.post)

Para ilustar este tutorial vamos a utilizar “login.events.pre” con el fin de securizar el acceso a nuestro portal sólo permitiendo acceder a los usuarios de rol “Administrador” desde IPs que estén dentro de una lista de IPs permitidas. Esto es muy útil para evitar el ataque de administradores resentidos desde la privacidad de un ciber-cafe.

2. Entorno.

El tutorial está
escrito usando el siguiente entorno:

  • Hardware: Portátil Asus G50Vseries (Core Duo P8600 2.4GHz, 4GB RAM, 320 GB HD).
  • Sistema operativo: Ubuntu 9.04.
  • Liferay Plugins SDK 5.2.3
  • Liferay Portal 5.2.3

3. Manos a la obra.

Para comenzar a desarrollar un plugin antes tenemos que contar con el SDK de Liferay. Aquí tenéis un tutorial donde se habla del tema: https://adictosaltrabajo.com/tutoriales/tutoriales.php?pagina=LiferayPluginsSDK.>

Una vez cumplido este requisito, lo que tenemos que hacer es situarnos en la carpeta %LIFERAY_SDK%/hooks donde, para nuestro asombro, nos damos cuenta que a los compañeros de Liferay se les ha olvidado añadir el script create que si que cuentan el resto de plugins (ya os había dicho que estos plugins no son muy conocidos), así que habrá que hacerlo a mano.

Lo primero es crear una carpeta con el nombre de nuestro proyecto “sample-post-login-hook” dentro de %LIFERAY_SDK%/hooks. Acto seguido nos metemos dentro de esta carpeta y creamos el fichero “build.xml” con el siguiente contenido:


	

Ahora creamos la estructura de carpeta docroot/WEB-INF/src a partir de la carpeta creada en el paso anterior. Dentro de la carpeta WEB-INF creamos el fichero “liferay-hook.xml” con el siguiente contenido:



	
		com.autentia.training.SamplePostLogin
		login.events.post
	

En este fichero le indicamos el evento que tiene que esperar y la clase que va a incluir la funcionalidad cuando se produzca el evento. Ahora importamos el proyecto a un IDE como Eclipse que nos facilita la edición de la clase. Para ello abrimos Eclipse y vamos a New –> Project –> Dynamic Web Project en “Portlet Name” ponemos el nombre del proyecto y desmarcamos la casilla “Use default” con la ayuda del botón “Browser” seleccionamos la carpeta %LIFERAY_SDK%/hooks/sample-post-login-hook y pulsamos en “Next”. En la siguiente pantalla volvemos a pulsar en “Next” y en la siguiente cambiamos el “Content directory” a “docroot” en vez de “WebContent” y pulsamos en “Finish”.

Ahora, dentro de Eclipse, vamos a establecer cual va a ser la ruta de nuestros ficheros fuente, para ello pinchando con el botón derecho sobre la raíz del proyecto seleccionamos New –> Source Folder y en el campo “Folder Name” con la ayuda del botón “Browser” seleccionamos la carpeta docroot/WEB-INF/src y pulsamos en “Finish”. Lo siguiente que podemos hacer es eliminar la carpeta “src” que venía por defecto en el proyecto.

Ya tenemos todo preparado para comenzar a implementar nuestra clase a la que llamaremos “SamplePostLogin”. Para ello con el botón derecho sobre la carpeta de fuentes “docroot/WEB-INF/src” seleccionamos “New” –> “Class”. En asistente que se muestra establecemos “Name” con el texto “SamplePostLogin” y “Package” con “com.autentia.training” y pulsamos en “Finish”.

A continuación escribimos el código de nuestra funcionalidad. Para no complicar innecesariamente el ejemplo, la lista de ips permitidas se establece en el propio código. Obviamente para una solución más “real” se debería utilizar un fichero .properties, además otra buena idea es establecer rangos de Ips permitidas para no tener que poner las ips una a una. A continuación se muestra el código de la clase autocomentado:

package com.autentia.training;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.liferay.portal.kernel.events.Action;
import com.liferay.portal.kernel.events.ActionException;
import com.liferay.portal.model.Role;
import com.liferay.portal.service.RoleLocalServiceUtil;
import com.liferay.portal.service.UserLocalServiceUtil;
import com.liferay.portal.util.PortalUtil;

public class SamplePostLogin extends Action {
	private final String ADMINISTRATOR = "Administrator";
	private List ipsValidas = new ArrayList(); 

	public void run(HttpServletRequest request, HttpServletResponse response)
	throws ActionException {

		try {
			//Inicializamos la lista de ips validas
			ipsValidas.add("127.0.0.1");
			ipsValidas.add("192.0.0.1");
			//Recuperamos la sesión del usuario
			HttpSession session = request.getSession();

			//Recupero la dirección IP del usuario
			String remoteAddr = request.getRemoteAddr();

			//Recupero los ids de compañia y usuario
			long companyId = PortalUtil.getCompanyId(request);
			long userId = PortalUtil.getUserId(request);
			//Recupero el id del rol Administrador
			Role roleAdministrator = RoleLocalServiceUtil.getRole(companyId, ADMINISTRATOR);
			//Compruebo si se trata de un administrador
			boolean isAdmin = UserLocalServiceUtil.hasRoleUser(roleAdministrator.getRoleId(), userId);
			if (isAdmin){
				//Si lo es, compruebo que su IP está dentro de las permitidas
				//en caso de que no este dentro de la lista permitida invalido la sesión
				if (!ipsValidas.contains(remoteAddr)){
					session.invalidate();
				}
			}
		} catch (Exception e) {
			throw new ActionException(e);
		}
	}
}

Sólo nos falta un pequeño detalle. Dentro de la carpeta WEB-INF creamos el fichero “liferay-plugin-package.properties” donde vamos establecer la versión del plugin con la siguiente línea:

module-incremental-version=1

Ahora abrimos un terminal, nos situamos en la carpeta %LIFERAY_SDK%/hooks/sample-post-login-hook y tecleamos “ant deploy”. Esto también se puede hacer desde el propio Eclipse arrastrando el fichero build.xml a la vista de “Ant”.

Si todo ha ido bien y tenemos Liferay arrancado podremos ver el despliegue en caliente. Ahora comprobamos que la funcionalidad realmente se produce como nosotros queremos, es decir, que el portal sólo nos deja logarnos como administradores si nuestra IP es una de la permitadas, en caso contrario no debería logarnos como administradores.

4. Conclusiones.

Esta es una técnica más que Liferay ofrece para poder añadir más funcionalidad al portal sorteando al tan temido (por lo menos por mi) entorno EXT que no hace más que complicar los desarrollos y sobre todo las migraciones. Como veis Liferay es una caja llena de sorpresas que desde Autentia estamos encantados de descubrir para ir mejorando nuestros cursos de formación.

Dudas o sugerencias de nuevos tutoriales en la zona de comentarios.

Saludos

Comentarios

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

He leído y acepto la política de privacidad

Información básica acerca de la protección de datos

  • Responsable: IZERTIS S.A.
  • Finalidad: Envío información de carácter administrativa, técnica, organizativa y/o comercial sobre los productos y servicios sobre los que se nos consulta.
  • Legitimación: Consentimiento del interesado
  • Destinatarios: Otras empresas del Grupo IZERTIS. Encargados del tratamiento.
  • Derechos: Acceso, rectificación, supresión, cancelación, limitación y portabilidad de los datos.
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad

Consultor tecnológico de desarrollo de proyectos informáticos.
Ingeniero en Informática, especialidad en Ingeniería del Software.

¿Quieres publicar en Adictos al trabajo?

Te puede interesar

22/06/2026

Juan Antonio Jiménez Torres

Vamos a instrumentalizar un SDD para un microservicio bancario. En este artículo sobre SDD - Spec Driven Development, instrumentalizado sobre OpenSpec vamos a construir una PoC de algo más serio que una tabla periódica. Un microservicio bancario muy simplificado que gestione cuentas y permita hacer transferencias

16/06/2026

Juan Antonio Jiménez Torres

Este es el segundo artículo sobre SDD, Spec Driven Development, instrumentalizado sobre OpenSpec. Pero esta vez nos acercaremos usando softwere gratuito. Por un lado OpenCode en lugar de ClaudeCode y usando el modelo gratuito Gemma4 de Google en lugar de otros de pago.

08/06/2026

Juan Antonio Jiménez Torres

Aprenderemos sobre SDD – Spec Driven Development instrumentalizado sobre OpenSpec. Haremos un primer acercamiento usando ClaudeCode con Sonnet, para luego, en un artículo posterior pasarnos a la versión gratuita de OpenCode con Gemma4