3.3. 通过截获数据包来审核消息


截获进入或退出代理的数据包,以审核数据包或过滤消息。拦截器更改它们拦截器的数据包。这使得拦截器强大,但也有可能存在危险。

开发拦截器以满足您的业务需求。拦截器特定于协议,必须实施适当的接口。

拦截器必须实施 intercept () 方法,它返回一个布尔值。如果值为 true,则消息 packet 继续。如果为 false,则进程中止,则不会调用其他拦截器,并且消息数据包不会被进一步处理。

3.3.1. 创建拦截器

拦截器可以更改它们拦截器的数据包。您可以创建自己的传入和传出拦截器。所有拦截器都是特定于协议的,分别针对输入或退出服务器的任何数据包调用。这样,您可以创建拦截器来满足审计数据包等业务需求。

拦截器及其依赖项必须放在代理的 Java 类路径中。您可以使用 &lt ;broker_instance_dir> /lib 目录,因为它默认为 classpath 的一部分。

以下示例演示了如何创建一个拦截器来检查传递给它的每个数据包的大小。

注意

示例为每个协议实施特定的接口。

流程

  1. 实施适当的接口并覆盖其拦截器 () 方法。

    1. 如果使用 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;
        }
      }
      Copy to Clipboard Toggle word wrap
    2. 如果使用核心协议,您的拦截器必须实施 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;
        }
      }
      Copy to Clipboard Toggle word wrap
    3. 如果您使用 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;
        }
      }
      Copy to Clipboard Toggle word wrap
    4. 如果您使用 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;
        }
      }
      Copy to Clipboard Toggle word wrap

3.3.2. 将代理配置为使用拦截器

先决条件

  • 创建一个拦截器类,并将其(及其依赖项)添加到代理的 Java 类路径中。您可以使用 &lt ;broker_instance_dir&gt; /lib 目录,因为它默认为 classpath 的一部分。

流程

  1. Open <broker_instance_dir>/etc/broker.xml
  2. 通过在 <broker _instance_dir> /etc/broker.xml中添加配置,将代理配置为使用拦截器

    1. 如果拦截器旨在用于传入消息,请将其 class-name 添加到 remoting-incoming-interceptors 列表中。

      <configuration>
        <core>
          ...
          <remoting-incoming-interceptors>
             <class-name>org.example.MyIncomingInterceptor</class-name>
          </remoting-incoming-interceptors>
          ...
        </core>
      </configuration>
      Copy to Clipboard Toggle word wrap
    2. 如果拦截器旨在用于传出消息,请将其 class-name 添加到 remoting-outgoing-interceptors 列表中。

      <configuration>
        <core>
          ...
          <remoting-outgoing-interceptors>
             <class-name>org.example.MyOutgoingInterceptor</class-name>
          </remoting-outgoing-interceptors>
        </core>
      </configuration>
      Copy to Clipboard Toggle word wrap

3.3.3. 客户端上的拦截器

客户端可以使用拦截器将客户端发送到服务器或者服务器发送到客户端的数据包。如果代理拦截器返回 false 值,则不会调用其他拦截器,且客户端不会进一步处理数据包。除非以 阻塞 方式发送传出数据包,否则这个过程发生透明。在本例中,一个 ActiveMQException 被抛出到调用者。ActiveMQException thrown 包含返回 false 值的拦截器的名称。

在服务器上,客户端拦截器类及其依赖项必须添加到客户端的 Java 类路径中,才能正确实例化和调用。

返回顶部
Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。 了解我们当前的更新.

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

Theme

© 2025 Red Hat