【问题标题】:Setting Trusted Packages (ActiveMQ)设置可信包 (ActiveMQ)
【发布时间】:2020-03-19 23:30:59
【问题描述】:

我正在尝试发送接收 ActiveMQ 消息。但我看到这些消息在其中包含此消息。

JMSException in onMessage(): javax.jms.JMSException: Failed to build body from content. Serializable class not available to broker. Reason: java.lang.ClassNotFoundException: Forbidden class com.logicalprovisioning.common.gtc.shared.GTCMessage! This class is not trusted to be serialized as ObjectMessage payload. Please take a look at http://activemq.apache.org/objectmessage.html for more information on how to configure trusted classes.

所以我阅读了消息中的链接。我试图按照说明进行操作。虽然我必须说它没有很好地写在哪里放置配置。

所以我所做的是: 1.我将bin文件夹中activemq.bat文件中的ACTIVEMQ_OPTS行编辑为

if "%ACTIVEMQ_OPTS%" == "" set ACTIVEMQ_OPTS=-Xms1G -Xmx1G -Djava.util.logging.config.file=logging.properties -Djava.security.auth.login.config="%ACTIVEMQ_CONF%\login.config" -Dorg.apache.activemq.SERIALIZABLE_PACKAGES=com.logicalprovisioning.common.gtc.shared.GTCMessage

没用。

  1. 我也在win64文件夹的activemq.bat中添加了上面的行。没用。

  2. 我修改了我的订阅者对象创建以添加受信任的包。喜欢:

    String providerEndpoints = "tcp://" + host + ":" + port + "?wireFormat.maxInactivityDuration=7200000";
    
    // Set the trusted packages/classes to move back and forth on the ActiveMQ JMS service.
    ArrayList<String> trustedClasses = new ArrayList<String>();
    
    trustedClasses.add("com.logicalprovisioning.common.gtc.shared.GTCMessage");
    
    // Obtain the factory
    ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory();
    
    activeMQConnectionFactory.setBrokerURL(providerEndpoints);
    
    // Add the trusted packages/classes to the ActiveMQ consumer.
    activeMQConnectionFactory.setTrustedPackages(trustedClasses);
    
    //Create the connection
    setConnection(activeMQConnectionFactory.createQueueConnection());
    getConnection().setClientID(this.getName());
    
    // Make a session
    setSession(getConnection().createQueueSession(false, Session.AUTO_ACKNOWLEDGE));
    
    getSession().createQueue(jmsDestination);
    
    // Create the destination
    Destination destination = getSession().createQueue(jmsDestination);
    
    String selector = "JMSCorrelationID = '" + getActionRequest().getOriginId() + "_" + getActionRequest().getRequestId() + "'" ;
    
    setConsumer(getSession().createConsumer(destination, selector));
    getConsumer().setMessageListener(new DefaultMessageListener(this));
    
    // Start ...
    gtcMessages = new GTCMessageQueue<GTCMessage>();  // We'll need a message store now
    getConnection().start();
    

我也在我的制片人中添加了类似的东西,以作为一个很好的衡量标准:

    Context initialContext = new InitialContext();
        Context environmentContext = (Context) initialContext.lookup("java:comp/env");

        String queueConnectionFactoryNameLookup = PalInit.getProperty("jms.queue.connection.factory");

        // Set the trusted packages/classes to move back and forth on the ActiveMQ JMS service.
        ArrayList<String> trustedClasses = new ArrayList<String>();

        trustedClasses.add("com.logicalprovisioning.common.gtc.shared.GTCMessage");

        ActiveMQConnectionFactory activeMQConnectionFactory = (ActiveMQConnectionFactory) environmentContext.lookup(queueConnectionFactoryNameLookup);

        activeMQConnectionFactory.setTrustedPackages(trustedClasses);
        // Create connection
        QueueConnection queueConnection = activeMQConnectionFactory.createQueueConnection();
        queueConnection.start();

        // Create session and producer
        setSession(queueConnection.createSession(false, Session.AUTO_ACKNOWLEDGE));

        String queueName = PalInit.getProperty("jms.destination");
        Queue jmsQueue = getSession().createQueue(queueName);

        setProducer(getSession().createProducer(jmsQueue));
        setQueueConnection(queueConnection);

        // Set Message "Time to Live" to the request timeout plus 10 minutes
        getProducer().setTimeToLive(getTimeout() + (10 * 60 * 1000L));

但似乎没有任何效果。我在 Tomcat 的 lib 文件夹中有 ActiveMQ-All jar,GTCMessage 类所在的 jar 也是如此。谁能告诉我我做错了什么?是缺课的问题还是我的配置不好?任何帮助,将不胜感激。谢谢!

应用程序在 Tomcat 9、JAVA 1.8 和 Active MQ 5.15.11 上运行。

【问题讨论】:

  • 补充一点,我可以让应用程序与 setTrustedPackages(true) 一起工作。但我不想让应用程序“裸露”!
  • 最好的选择,不要使用 ObjectMessage,当他们将它添加到规范时这是一个可怕的想法,现在它是一个可怕的想法。

标签: java tomcat jms activemq


【解决方案1】:

我认为您的问题是您正在设置特定 class 的名称,而不是该类的 package。 The code 查看包名,而不是类名。试试这个:

// Set the trusted packages to move back and forth on the ActiveMQ JMS service.
ArrayList<String> trustedPackages = new ArrayList<String>();
trustedPackages.add("com.logicalprovisioning.common.gtc.shared");
ActiveMQConnectionFactory activeMQConnectionFactory = (ActiveMQConnectionFactory) environmentContext.lookup(queueConnectionFactoryNameLookup);
activeMQConnectionFactory.setTrustedPackages(trustedPackages);        

我认为您不需要在代理本身上进行设置。

除此之外,我强烈建议您不要使用 JMS ObjectMessage。它们依靠 Java 序列化来编组和解组其对象有效负载。这个过程通常被认为是不安全的,因为恶意负载可以利用主机系统。 Lots of CVEs 已为此创建,这就是为什么大多数 JMS 提供商强制用户将可以使用 ObjectMessage 消息交换的包显式列入白名单的原因。

使用 JMS ObjectMessage 还存在许多其他与安全无关的问题,您应该 read about。这篇文章对如何替换ObjectMessage有一个很好的建议——为payload(JSON、protobuf、XML)定义一个数据表示,并使用TextMessage或BytesMessage来携带。

【讨论】:

  • 感谢您的帮助!很有帮助!
猜你喜欢
  • 2016-08-05
  • 1970-01-01
  • 2012-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-10
  • 2019-03-27
相关资源
最近更新 更多