设置可信包(ActiveMQ)
Setting Trusted Packages (ActiveMQ)
我正在尝试发送接收 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.
所以我看了邮件中的link。我试着按照说明去做。虽然我必须说它在放置配置的位置上写得不是很好。
所以我所做的是:
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
没用。
我在 win64 文件夹的 activemq.bat 中也添加了上面的行。没用。
我修改了我的订户对象创建以添加受信任的包。喜欢:
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 class 所在的 jar。谁能告诉我我做错了什么?是缺少 class 还是我配置错误的问题?任何帮助,将不胜感激。谢谢!
应用程序 运行 Tomcat 9、JAVA 1.8 和 Active MQ 5.15.11。
我认为您的问题是您正在设置特定 class 的名称,而不是 package class。 The code 查看包名称,而不是 class 名称。试试这个:
// 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
有一个很好的建议 - 为有效负载定义数据表示(JSON、protobuf、XML)并使用 TextMessage
或 BytesMessage
随身携带。
我正在尝试发送接收 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.
所以我看了邮件中的link。我试着按照说明去做。虽然我必须说它在放置配置的位置上写得不是很好。
所以我所做的是: 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
没用。
我在 win64 文件夹的 activemq.bat 中也添加了上面的行。没用。
我修改了我的订户对象创建以添加受信任的包。喜欢:
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 class 所在的 jar。谁能告诉我我做错了什么?是缺少 class 还是我配置错误的问题?任何帮助,将不胜感激。谢谢!
应用程序 运行 Tomcat 9、JAVA 1.8 和 Active MQ 5.15.11。
我认为您的问题是您正在设置特定 class 的名称,而不是 package class。 The code 查看包名称,而不是 class 名称。试试这个:
// 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
有一个很好的建议 - 为有效负载定义数据表示(JSON、protobuf、XML)并使用 TextMessage
或 BytesMessage
随身携带。