Spring Boot下ActiveMQConnectionFactory可信包配置不生效问题咨询
问题根因排查
- 可信包校验触发时机错误:ActiveMQ的
setTrustedPackages配置的反序列化可信包规则,默认仅在消费端解析ObjectMessage、执行反序列化操作时才会触发校验,生产端发送消息时仅执行对象序列化,不会校验类所属包是否在可信列表中,所以发送非java.lang包对象不会抛出异常。 - 连接工厂配置可能被覆盖:如果项目引入了
spring-boot-starter-activemq启动器,Spring Boot默认会自动注册内置的ActiveMQConnectionFactory,若未配置优先级,可能出现JmsTemplate绑定的是系统默认连接工厂而非自定义实例的问题。
解决方案
- 消费端校验兜底(推荐)
确保消费端的ActiveMQConnectionFactory也配置相同的可信包规则,消费时如果接收到非可信包的对象消息,会直接抛出反序列化异常,阻止风险,消费端配置参考如下:
@Bean public ConnectionFactory consumerConnectionFactory() { ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(brokerUrl); factory.setTrustAllPackages(false); factory.setTrustedPackages(Collections.singletonList("java.lang")); return factory; }
- 生产端新增发送前校验逻辑
如果需要在发送时就拦截不符合要求的对象,直接在发送方法里新增所属包校验即可,修改后的send方法参考:
public void sendObjectMessage(final Serializable msg) { // 新增发送前包名校验 if (msg != null && !msg.getClass().getPackageName().equals("java.lang")) { logger.error("拒绝发送非可信包对象: {}", msg.getClass().getName()); throw new IllegalArgumentException("仅允许发送java.lang包下的消息对象"); } try { this.jmsTemplate.send(this.queue, new MessageCreator() { public Message createMessage(final Session session) throws JMSException { return session.createObjectMessage(msg); } }); logger.info("Success sending Object MQ message [{}]", msg); } catch (Exception e) { logger.error("Error sending Object MQ message [{}]", msg, e); } }
- 确保自定义连接工厂优先级
在你的自定义连接工厂Bean上添加@Primary注解,避免Spring自动配置的连接工厂覆盖你的自定义配置:
@Primary @Bean(name="jmsConnectionFactory") public ConnectionFactory getJmsConnectionFactory(){ ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(active_MQ_BrokerURL); factory.setTrustAllPackages(false); factory.setTrustedPackages(Arrays.asList("java.lang")); return factory; }
内容的提问来源于stack exchange,提问作者peter.petrov
相关产品推荐
相关产品推荐

