Spring Cloud Stream设置spring.json.trusted.packages='*'的利弊与性能影响
Spring Cloud Stream批量消费场景下的反序列化疑问
我在项目里用Spring Cloud Stream,目前还是通过@StreamListener以批量模式消费数据,因此必须配置反序列化器。但输入主题太多,每个主题都要新建反序列化器类实在麻烦。后来发现设置spring.json.trusted.packages: '*'的话,不用新建反序列化器,用通用的JsonDeserializer就能处理任意数据。但我有几个疑问:
- 这种通用方式会影响消费性能吗?
- 单独写反序列化器有啥好处?
- 为啥要给每种数据都新建反序列化器类?
- 设置
spring.json.trusted.packages='*'有哪些危害?
带PersonDeserializer的配置
反序列化器代码
public class PersonDeserializer extends JsonDeserializer<Person> { }
application.yml配置
spring: cloud: stream: binders: bulkKafka: type: kafka environment: spring: cloud: stream: kafka: binder: brokers: ${kafka.brokers} minPartitionCount: ${default-configuration.kafka.partition-count} autoCreateTopics: true autoAddPartitions: true configuration: max.poll.records: 3000 fetch.min.bytes: 900000 fetch.max.wait.ms: 500 value.deserializer: org.example.PersonDeserializer bindings: person-topic-in: destination: person-topic contentType: application/json binder: bulkKafka group: ${spring.application.name} consumer: batch-mode: true
不带PersonDeserializer的配置
spring: kafka: consumer: properties: spring.json.trusted.packages: "*" cloud: stream: binders: bulkKafka: type: kafka environment: spring: cloud: stream: kafka: binder: brokers: ${kafka.brokers} minPartitionCount: ${default-configuration.kafka.partition-count} autoCreateTopics: true autoAddPartitions: true configuration: max.poll.records: 3000 fetch.min.bytes: 900000 fetch.max.wait.ms: 500 value.deserializer: org.springframework.kafka.support.serializer.JsonDeserializer bindings: person-topic-in: destination: person-topic contentType: application/json binder: bulkKafka group: ${spring.application.name} consumer: batch-mode: true
疑问解答
1. 通用JsonDeserializer加trusted.packages='*'会影响性能吗?
基本不会有明显影响。JsonDeserializer本身的反序列化逻辑和自定义继承类完全一致——自定义类只是明确了泛型类型,底层还是依赖Jackson做JSON解析。唯一可能的微小差异是:如果通用方式需要通过消息的__TypeId__头推断目标类,会多一步类型查找,但这步开销极小,除非是超大规模的消息量,否则根本感知不到。
2. 单独写反序列化器有何益处?
- 类型安全:直接指定泛型类型,不用依赖消息头的类型信息,避免因类型头缺失或错误导致的反序列化失败。
- 自定义扩展:可以在反序列化前后插入自定义逻辑,比如字段校验、数据格式转换、异常处理定制。比如在
PersonDeserializer里重写deserialize方法,对Person的字段做合法性检查,不符合就抛出特定异常。 - 配置隔离:不同主题的反序列化规则可以独立设置,比如某个主题需要特殊的Jackson配置(忽略未知字段、自定义日期格式),可以在对应的自定义反序列化器里单独配置,不影响其他主题。
3. 为何要为每种数据创建新的反序列化器类?
主要是早期的使用习惯和类型安全要求:
- 旧版本的Spring Cloud Stream + Kafka中,如果不指定具体的泛型反序列化器,
JsonDeserializer可能无法正确推断目标类型,导致反序列化失败,因此必须每个类型写一个继承类明确泛型。 - 团队规范要求:确保每个消息类型对应明确的反序列化逻辑,便于维护和排查问题,避免一个通用反序列化器出问题影响所有主题。
4. 设置spring.json.trusted.packages='*'的危害?
这是高危配置,核心风险是反序列化漏洞:
- 如果攻击者控制了消息中的
__TypeId__头,指定一个恶意Java类(比如包含恶意代码的类),JsonDeserializer会信任并实例化该类,从而引发代码执行、数据泄露等严重安全问题。 - 扩大了信任范围,即使是项目外的未知包也能被反序列化,大幅增加了攻击面。
- 可能导致意外的类型转换:如果消息里的类型头错误指向了其他类,会引发不可预期的反序列化结果,增加问题排查难度。
内容的提问来源于stack exchange,提问作者eomercelik
相关产品推荐
相关产品推荐

