我们正在构建一个通过RabbitMQ接收消息的Sping Boot 应用程序(2.0.4-RELEASE)。因此application.properties
包含了rabbit相关的配置:
spring.rabbitmq.addresses=****
spring.rabbitmq.username=****
spring.rabbitmq.password=****
spring.rabbitmq.listener.simple.concurrency=2
spring.rabbitmq.listener.simple.prefetch=5
spring.rabbitmq.listener.simple.retry.enabled=true
spring.rabbitmq.listener.simple.retry.max-attempts=5
字符串
配置方式:
@Bean
public TopicExchange fileUpdate() {
return new TopicExchange("my.fancy.exchange", true, false);
}
@Bean
public Queue fileUpload() {
return new Queue("myFancyQueue", true);
}
@Bean
public Binding bindingUpload(Queue queue, TopicExchange eventExchange) {
return BindingBuilder.bind(queue).to(eventExchange).with("");
}
型
消息消费者:
@RabbitListener(queues = "myFancyQueue")
public void receive(Object message) {
...
}
型
当接收到特定类型的消息(例如__TypeId__: my.fancy.package.Clazz
)时,会抛出以下错误:
原因:java.lang.IllegalArgumentException:类“my.fancy.package.Clazz”不在受信任的包中:[java.util,java.lang]。如果您认为此类可以安全地序列化,请提供其名称。如果序列化仅由受信任的源完成,您也可以启用trust all(*)。
根据我目前所发现的,activeMQ通过application.properties
提供了一个配置选项,
spring.activemq.packages.trust-all=
型
或
spring.activemq.packages.trusted=
型
但是我找不到任何类似的选项可以用于rabbitMQ。到目前为止,我一直在使用一个解决问题的变通方法,但是当然,如果在配置文件中有这样的选项就太好了。
我的解决方案到目前为止:
添加到配置类:
@Bean
public MessageConverter jsonMessageConverter() {
Jackson2JsonMessageConverter jsonMessageConverter = new Jackson2JsonMessageConverter(new ObjectMapper());
jsonMessageConverter.setClassMapper(new ImporterClassMapper(FileUploadMessage.class));
return jsonMessageConverter;
}
@Bean
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
RabbitTemplate template = new RabbitTemplate(connectionFactory);
template.setMessageConverter(jsonMessageConverter());
return template;
}
型
并将消息使用者更改为
@Resource(name = "jsonMessageConverter")
private MessageConverter messageConverter;
@RabbitListener(queues = "${uploaded.files.queue}")
public void receive(Message message) {
FileUploadMessage uploadMessage = (FileUploadMessage) messageConverter.fromMessage(message);
...
}
型
加上添加一个类Map器,允许导入未知类型,并设置一个默认类型,在导入时将消息转换为该类型:
public class ImporterClassMapper implements ClassMapper, InitializingBean {
private volatile Class<?> defaultType;
public ImporterClassMapper(Class<?> defaultType) {
this.defaultType = defaultType;
}
@Override
public void afterPropertiesSet() throws Exception {
// nothing to do
}
@Override
public void fromClass(Class<?> clazz, MessageProperties properties) {
// avoid setting __TypeId__ header so consumers from other modules can implement their own DTOs
}
@Override
public Class<?> toClass(MessageProperties properties) {
return this.defaultType;
}
public void setClass(Class<?> type) {
this.defaultType = type;
}
}
型
有什么建议可以改进这个解决方案吗?
2条答案
按热度按时间olmpazwi1#
我通过在正在使用的Spring AMQP ClassMapper上设置受信任的包修复了相同的错误。
字符串
piah890a2#
作为
CVE-2023-34050
和Spring AMQP DOC,还有一种替代方法:设置
操作系统环境变量
SPRING_AMQP_DESERIALIZATION_TRUST_ALL
到true
。或
VM options
到-Dspring.amqp.deserialization.trust.all=true
它工作,但不是好方法。