3.3. 通过截获数据包来审核消息
截获进入或退出代理的数据包,以审核数据包或过滤消息。拦截器更改它们拦截器的数据包。这使得拦截器强大,但也有可能存在危险。
开发拦截器以满足您的业务需求。拦截器特定于协议,必须实施适当的接口。
拦截器必须实施 intercept ()
方法,它返回一个布尔值。如果值为 true
,则消息 packet 继续。如果为 false
,则进程中止,则不会调用其他拦截器,并且消息数据包不会被进一步处理。
3.3.1. 创建拦截器
拦截器可以更改它们拦截器的数据包。您可以创建自己的传入和传出拦截器。所有拦截器都是特定于协议的,分别针对输入或退出服务器的任何数据包调用。这样,您可以创建拦截器来满足审计数据包等业务需求。
拦截器及其依赖项必须放在代理的 Java 类路径中。您可以使用 < ;broker_instance_dir> /lib
目录,因为它默认为 classpath 的一部分。
以下示例演示了如何创建一个拦截器来检查传递给它的每个数据包的大小。
示例为每个协议实施特定的接口。
流程
实施适当的接口并覆盖其拦截器
()
方法。如果使用 AMQP 协议,请实施
org.apache.activemq.artemis.protocol.amqp.broker.AmqpInterceptor
接口。package com.example; import org.apache.activemq.artemis.protocol.amqp.broker.AMQPMessage; import org.apache.activemq.artemis.protocol.amqp.broker.AmqpInterceptor; import org.apache.activemq.artemis.spi.core.protocol.RemotingConnection; public class MyInterceptor implements AmqpInterceptor { private final int ACCEPTABLE_SIZE = 1024; @Override public boolean intercept(final AMQPMessage message, RemotingConnection connection) { int size = message.getEncodeSize(); if (size <= ACCEPTABLE_SIZE) { System.out.println("This AMQPMessage has an acceptable size."); return true; } return false; } }
如果使用核心协议,您的拦截器必须实施
org.apache.artemis.activemq.api.core.Interceptor
接口。package com.example; import org.apache.artemis.activemq.api.core.Interceptor; import org.apache.activemq.artemis.core.protocol.core.Packet; import org.apache.activemq.artemis.spi.core.protocol.RemotingConnection; public class MyInterceptor implements Interceptor { private final int ACCEPTABLE_SIZE = 1024; @Override boolean intercept(Packet packet, RemotingConnection connection) throws ActiveMQException { int size = packet.getPacketSize(); if (size <= ACCEPTABLE_SIZE) { System.out.println("This Packet has an acceptable size."); return true; } return false; } }
如果您使用 mq 协议,请实施
org.apache.activemq.artemis.core.protocol.mqtt.mqInterceptor
接口。package com.example; import org.apache.activemq.artemis.core.protocol.mqtt.MQTTInterceptor; import io.netty.handler.codec.mqtt.MqttMessage; import org.apache.activemq.artemis.spi.core.protocol.RemotingConnection; public class MyInterceptor implements Interceptor { private final int ACCEPTABLE_SIZE = 1024; @Override boolean intercept(MqttMessage mqttMessage, RemotingConnection connection) throws ActiveMQException { byte[] msg = (mqttMessage.toString()).getBytes(); int size = msg.length; if (size <= ACCEPTABLE_SIZE) { System.out.println("This MqttMessage has an acceptable size."); return true; } return false; } }
如果您使用 STOMP 协议,请实施
org.apache.activemq.artemis.core.protocol.stomp.StompFrameInterceptor
接口。package com.example; import org.apache.activemq.artemis.core.protocol.stomp.StompFrameInterceptor; import org.apache.activemq.artemis.core.protocol.stomp.StompFrame; import org.apache.activemq.artemis.spi.core.protocol.RemotingConnection; public class MyInterceptor implements Interceptor { private final int ACCEPTABLE_SIZE = 1024; @Override boolean intercept(StompFrame stompFrame, RemotingConnection connection) throws ActiveMQException { int size = stompFrame.getEncodedSize(); if (size <= ACCEPTABLE_SIZE) { System.out.println("This StompFrame has an acceptable size."); return true; } return false; } }
3.3.2. 将代理配置为使用拦截器
先决条件
-
创建一个拦截器类,并将其(及其依赖项)添加到代理的 Java 类路径中。您可以使用 <
;broker_instance_dir> /lib
目录,因为它默认为 classpath 的一部分。
流程
-
Open
<broker_instance_dir>/etc/broker.xml
通过在 <broker
_instance_dir> /etc/broker.xml
中添加配置,将代理配置为使用拦截器如果拦截器旨在用于传入消息,请将其
class-name
添加到remoting-incoming-interceptors
列表中。<configuration> <core> ... <remoting-incoming-interceptors> <class-name>org.example.MyIncomingInterceptor</class-name> </remoting-incoming-interceptors> ... </core> </configuration>
如果拦截器旨在用于传出消息,请将其
class-name
添加到remoting-outgoing-interceptors
列表中。<configuration> <core> ... <remoting-outgoing-interceptors> <class-name>org.example.MyOutgoingInterceptor</class-name> </remoting-outgoing-interceptors> </core> </configuration>
3.3.3. 客户端上的拦截器
客户端可以使用拦截器将客户端发送到服务器或者服务器发送到客户端的数据包。如果代理拦截器返回 false
值,则不会调用其他拦截器,且客户端不会进一步处理数据包。除非以 阻塞
方式发送传出数据包,否则这个过程发生透明。在本例中,一个 ActiveMQException
被抛出到调用者。ActiveMQException
thrown 包含返回 false
值的拦截器的名称。
在服务器上,客户端拦截器类及其依赖项必须添加到客户端的 Java 类路径中,才能正确实例化和调用。