3.5. 通过截获数据包来审计消息


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

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

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

3.5.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;
        }
      }
    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;
        }
      }
    3. 如果您使用 MQTT 协议,请实施 org.apache.activemq.artemis.core.protocol.mqtt.MQTTInterceptor 接口。

      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;
        }
      }
    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;
        }
      }

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

先决条件

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

流程

  1. Open <broker_instance_dir>/etc/broker.xml
  2. 通过将配置添加到 <broker _instance_dir&gt; /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>
    2. 如果拦截器用于传出消息,请将其 class-name 添加到 remoting-outgoing-interceptors 列表中。

      <configuration>
        <core>
          ...
          <remoting-outgoing-interceptors>
             <class-name>org.example.MyOutgoingInterceptor</class-name>
          </remoting-outgoing-interceptors>
        </core>
      </configuration>

3.5.3. 客户端上的拦截器

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

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

Red Hat logoGithubRedditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

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

让开源更具包容性

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

關於紅帽

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

© 2024 Red Hat, Inc.