DZone's Guide to

CloudAMQP Audit Message Processor for Liferay 7/DXP

In this post, we look at how to use this tool to create a layer of security around a message-oriented middleware system. Read on for more!

· Security Zone
Free Resource

Learning by doing is more effective than learning by watching - that’s why Codebashing offers a hands-on interactive training platform in 10 major programming languages. Learn more about AppSec training for enterprise developers.

A few days ago I published the article Liferay Portal Security Audit with the aim of explaining what the system is and how it works of Liferay's Security Audit, and to understand how to extend its functionality. As an ultra-bonus, all the source code developed is publicly available on my GitHub repository, liferay-portal-security-audit.

Figure 1 shows the macro-architecture of Liferay Portal Security Audit. In the article, we discussed how to implement the two components at the base of the framework: the Audit Router and the Audit Message Processors.

In this article, I would like to show you how simple it is to create a new Audit Message Processor component that receives audit messages and forwards them (possibly after processing) to a message-oriented middleware system.

Figure 1 - Liferay Portal Security Audit Architecture Macroe

Figure 1 - Liferay Portal Security Audit Architecture Macro

I decided to use AMQP as a communication protocol between client and broker. The Advanced Message Queuing Protocol (AMQP) protocol was developed to solve interoperability problems between different messaging-oriented middleware products.

AMQP (international standard approved by ISO and IEC as ISO/IEC 19464: 2014) is an efficient and reliable wire-level messaging protocol that can be used to create multi-platform and reliable messaging applications.

This protocol serves a simple purpose: to define the mechanisms for the secure, reliable, and efficient transmission of messages between two parties. The messages themselves are encoded using a portable data representation that allows heterogeneous senders and recipients to exchange structured business messages with absolute fidelity.

The new Audit Message Processor we are going to implement will use AMQP as a protocol for sending audit messages to a specific queue hosted by a messaging broker that supports this type of protocol. The broker I have decided to use for this example is RabbitMQ. In Figure 2 the case described above is illustrated.

Figure 2 - Audit Message Processor that processes and sends audit messages to an AMQP message broker

Figure 2 - Audit Message Processor that processes and sends audit messages to an AMQP message broker

RabbitMQ is the most widespread open source message broker that implements the AMQP protocol. Here, for convenience purposes we will use CloudAMQP, RabbitMQ servers managed in the cloud. Figure 3 shows the flow of the publication of audit messages from the Liferay Portal to the CloudAMQP message broker. The messages in the queue can then be consumed.

Figure 3 - Sending messages via AMQP using the CloudAMQP service

Figure 3 - Sending messages via AMQP using the CloudAMQP service

1. How to Implement the Audit Message Processor

In the Audit Service ecosystem, the Audit Message Processor is the component responsible for processing the audit messages received by the Audit Router.

We remind you that the Audit Service system can have one or more Audit Message Processors (but also zero, as in the case of the Community Edition of Liferay). It is possible to configure two types of message processors: global processors and processors for certain types of events; in this way, we are in a position to differentiate the place where to store the actions according to their type.

Our Audit Message Processor we are going to implement will be an OSGi component that we will call CloudAMQP Audit Message Processor and which will have to implement the Audit Message Processor interface.

This interface declares the only method: void process (AuditMessagge auditMessage), called by the Audit Router.

Before going to implement the new Audit Message Processor, let's see what the features are:

Table 1 shows the main characteristics of the message processor we are going to implement. The OSGi configuration associated with the new component is defined via the CloudAMQPAuditMessageProcessorConfiguration interface available as the source code of the liferay-portal-security-audit project on GitHub.

Feature/OSGi configuration

Description
Tipo Globale

Global Audit Message Processor. All audit messages pass through this message processor.

Enabled

Allows you to enable or disable the message processor. The default value is set to false.

Server Address

IP address or FQDN of the CloudAMQP server.

User Name

Username to access CloudAMQP services.

Password

Password to access CloudAMQP services.

Queue Name

Name of the queue defined in CloudAMQP.

Table 1 - Characteristics of the CloudAMQP Message Processor

In order to send the audit messages to the message broker through the AMQP protocol, we need a library that facilitates the task. RabbitMQ offers the most disparate platforms, languages, and libraries that implement the client that speaks in AMQP. Among the supported languages there is also Java, moreover, the latest versions are also OSGi compliant.

The steps necessary to complete the implementation of the message processor are:

Code 1 shows part of the build.gradle file to include the AMQP client dependency. In this case, the dependency must also be included in the final bundle, here is the reason for using compileInclude in Gradle dependencies.

dependencies {
   compileInclude group: "com.rabbitmq", name: "amqp-client", version: "5.1.2"
   ...
}

Code 1 - Inclusion of the AMQP client dependency

Instead, Code 2 shows the core part of the implementation of the process method. The complete code of the CloudAMQPAuditMessageProcessor is available as the source code of the liferay-portal-security-audit project on GitHub.

try {
      if (_log.isDebugEnabled()) {
         _log.debug("Try to connect " + _buildAMQPURI() + "...");
      }

      ConnectionFactory factory = new ConnectionFactory();

      factory.setUri(_buildAMQPURI());

      Connection connection = factory.newConnection();

      Channel channel = connection.createChannel();

      channel.queueDeclare(
         _cloudAMQPAuditMessageProcessorConfiguration.queueName(),
         durable, exclusive, autoDelete, null);

      channel.basicPublish("",
         _cloudAMQPAuditMessageProcessorConfiguration.queueName(),
         null,
         auditMessage.toJSONObject().toString().getBytes("UTF-8"));

      channel.close();
      connection.close();
   }
   catch (Exception e) {
      if (_log.isWarnEnabled()) {
         _log.warn(
            "Send Message Audit to Cloud AMQP Queue failed.", e);
      }
   }
}

Code 2 - Implementation of the process method

2. Deploy of the Audit Message Processor

The Liferay Portal Security Audit project is organized as shown in Table 2.

Name of the module Description of the module
portal-security-audit-capture-events

This module contains components that capture portal events such as AuthFailure. These components trace events by sending them to message processors through the Audit Router.

portal-security-audit-router

This module contains the Standard Audit router component that implements the Audit Router interface.

portal-security-message-processor

This module contains the message processors: Dummy Audit Message Processor, Login Failure Message Processor, and CloudAMQP Audit Message Processor.

Table 2 - New modules added to the Liferay Portal Security Audit system

The CloudAMQP Audit Message Processor is part of the portal-security-message-processor module that can be installed on both the Community Edition and the Liferay DXP. In the case of installation on the DXP, you only need to install the portal-security-message-processor bundle (in.dontesta.labs.liferay.portal.security.audit.message.processor.jar), on the contrary, on the Community Edition, you need to install the three bundles of the three modules.

To proceed with the deployment, follow the steps indicated below:

$ git clone https://github.com/amusarra/liferay-portal-security-audit.git
$ cd liferay-portal-security-audit
$ ./gradlew clean deploy
$ cp ../bundles/osgi/modules/*.jar $LIFERAY_HOME/deploy/

In the my case, $LIFERAY_HOME is set on this directory: /opt/liferay-ce-portal-7.0-ga5

Verify the correct deployment of the three bundles via the Liferay log file or through the Gogo Shell using the lb command, making sure that the status is Active.

$ telnet localhost 11311

g! lb|grep Audit
  342|Active     |   10|Liferay Portal Security Audit API (2.0.2)
  343|Active     |   10|Liferay Portal Security Audit Wiring (2.0.4)
  584|Active     |   10|Liferay Portal Security Audit Capture Events (1.0.0)
  586|Active     |   10|Liferay Portal Security Audit Message Processor (1.0.0)
  587|Active     |   10|Liferay Portal Security Audit Router (1.0.0)

3. Configuration of the Audit Message Processor

Once the CloudAMQP Audit Message Processor bundle has been installed, you must configure the connection parameters to your CloudAMQP instance. Figure 4 shows an example of the configuration.

Figure 4 - Configuration of the CloudAMQP Audit Message Processor

Figure 4 - Configuration of the CloudAMQP Audit Message Processor

Remember that in order for the message processor to work (capture audit messages), the Audit system (also from the Control Panel) must be enabled, as well as itself.

4. The CloudAMQP Audit Message Processor in Action

At this point, we need to test the new Audit Message Processor. When checking the events of LOGIN, LOGIN_FAILURE, etc., on the Liferay log we can verify entries that indicate that the audit messages have been published to CloudAMQP.

18:52:10,827 INFO  [liferay/audit-1][CloudAMQPAuditMessageProcessor:125] Message Audit processed and published on liferay_audit_queue Cloud AMQP queue. 
Details {{product=RabbitMQ, copyright=Copyright (c) 2007-2017 
Pivotal Software, Inc., 
capabilities={exchange_exchange_bindings=true, connection.blocked=true, 
authentication_failure_close=true, basic.nack=true, 
publisher_confirms=true, consumer_cancel_notify=true}, 
information=Licensed under the MPL. See http://www.rabbitmq.com/, 
version=5.1.2, platform=Java}}

It is possible to verify the correct publication of the audit messages by consulting the CloudAMQP console. The following figures show a series of screenshots that show the correct functioning of the Audit Message Processor.

Figure 5 - Global status of the code

Figure 5 - Global status of the code

Figure 6 - List and details of the queues

Figure 6 - List and details of the queues

Figure 7 - Reading messages from the queue

Figure 7 - Reading messages from the queue

Summary

With this article, I tried to explain with simplicity how, thanks to the Liferay framework Security Audit, it is easy to create an Audit Message Processor that publishes the audit messages to a message broker using the AMQP protocol. Moreover, with this article, we have seen how it is also easy to integrate Liferay with a messaging system based on the AMQP protocol.

I hope I was clear in the show and that it captured your interest in the subject; if so, you could return the favor by sharing the article on social network channels or others, what I wrote could also be useful to other people.

Feel free to contact me if you have any questions or need help. I'm @antonio_musarra on Twitter and amusarra on LinkedIn. I'll even wait for you on my Antonio Musarra's Blog.

Find out how CxSAST can help you scan uncompiled and unbuilt code while identifying hundreds of security vulnerabilities in the most prevalent coding languages.

Opinions expressed by DZone contributors are their own.