Skip to content

Commit bd49070

Browse files
garyrussellartembilan
authored andcommitted
GH-1751: JsonDeser. Trust Mapped Class Packages
Resolves #1751 Always trust packages for classes in the id class mappings, even with an externally injected type mapper. We don't normally reconfigure mappers when injected, but in this case it makes sense and provides an easier user experience.
1 parent df6e4b1 commit bd49070

File tree

3 files changed

+50
-7
lines changed

3 files changed

+50
-7
lines changed

spring-kafka/src/main/java/org/springframework/kafka/support/serializer/JsonDeserializer.java

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2015-2020 the original author or authors.
2+
* Copyright 2015-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -296,14 +296,18 @@ public Jackson2JavaTypeMapper getTypeMapper() {
296296
}
297297

298298
/**
299-
* Set a customized type mapper.
299+
* Set a customized type mapper. If the mapper is an {@link AbstractJavaTypeMapper},
300+
* any class mappings configured in the mapper will be added to the trusted packages.
300301
* @param typeMapper the type mapper.
301302
* @since 2.1
302303
*/
303304
public void setTypeMapper(Jackson2JavaTypeMapper typeMapper) {
304305
Assert.notNull(typeMapper, "'typeMapper' cannot be null");
305306
this.typeMapper = typeMapper;
306307
this.typeMapperExplicitlySet = true;
308+
if (typeMapper instanceof AbstractJavaTypeMapper) {
309+
addMappingsToTrusted(((AbstractJavaTypeMapper) typeMapper).getIdClassMapping());
310+
}
307311
}
308312

309313
/**
@@ -375,15 +379,21 @@ public void configure(Map<String, ?> configs, boolean isKey) {
375379
}
376380
if (configs.containsKey(TYPE_MAPPINGS) && !this.typeMapperExplicitlySet
377381
&& this.typeMapper instanceof AbstractJavaTypeMapper) {
378-
((AbstractJavaTypeMapper) this.typeMapper).setIdClassMapping(
379-
JsonSerializer.createMappings(configs.get(JsonSerializer.TYPE_MAPPINGS).toString()));
382+
((AbstractJavaTypeMapper) this.typeMapper).setIdClassMapping(createMappings(configs));
380383
}
381384
if (configs.containsKey(REMOVE_TYPE_INFO_HEADERS)) {
382385
this.removeTypeHeaders = Boolean.parseBoolean(configs.get(REMOVE_TYPE_INFO_HEADERS).toString());
383386
}
384387
setUpTypeMethod(configs, isKey);
385388
}
386389

390+
private Map<String, Class<?>> createMappings(Map<String, ?> configs) {
391+
Map<String, Class<?>> mappings =
392+
JsonSerializer.createMappings(configs.get(JsonSerializer.TYPE_MAPPINGS).toString());
393+
addMappingsToTrusted(mappings);
394+
return mappings;
395+
}
396+
387397
private void setUpTypeMethod(Map<String, ?> configs, boolean isKey) {
388398
if (isKey && configs.containsKey(KEY_TYPE_METHOD)) {
389399
setUpTypeResolver((String) configs.get(KEY_TYPE_METHOD));
@@ -471,6 +481,13 @@ public void addTrustedPackages(String... packages) {
471481
doAddTrustedPackages(packages);
472482
}
473483

484+
private void addMappingsToTrusted(Map<String, Class<?>> mappings) {
485+
mappings.values().forEach(clazz -> {
486+
doAddTrustedPackages(clazz.getPackageName());
487+
doAddTrustedPackages(clazz.getPackageName() + ".*");
488+
});
489+
}
490+
474491
private void addTargetPackageToTrusted() {
475492
String targetPackageName = getTargetPackageName();
476493
if (targetPackageName != null) {

spring-kafka/src/main/java/org/springframework/kafka/support/serializer/JsonSerializer.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2016-2020 the original author or authors.
2+
* Copyright 2016-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -167,7 +167,7 @@ protected static Map<String, Class<?>> createMappings(String mappings) {
167167
ClassUtils.forName(split[1].trim(), ClassUtils.getDefaultClassLoader()));
168168
}
169169
catch (ClassNotFoundException | LinkageError e) {
170-
throw new IllegalArgumentException(e);
170+
throw new IllegalArgumentException("Failed to load: " + split[1] + " for " + split[0], e);
171171
}
172172
}
173173
return mappingsMap;

spring-kafka/src/test/java/org/springframework/kafka/support/serializer/JsonSerializationTests.java

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2016-2020 the original author or authors.
2+
* Copyright 2016-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -291,6 +291,32 @@ void testParseTrustedPackages() {
291291
.contains("foo", "bar", "baz");
292292
}
293293

294+
@SuppressWarnings("unchecked")
295+
@Test
296+
void testTrustMappingPackages() {
297+
JsonDeserializer<Object> deser = new JsonDeserializer<>();
298+
Map<String, Object> props = Collections.singletonMap(JsonDeserializer.TYPE_MAPPINGS,
299+
"foo:" + Foo.class.getName());
300+
deser.configure(props, false);
301+
assertThat(KafkaTestUtils.getPropertyValue(deser, "typeMapper.trustedPackages", Set.class))
302+
.contains(Foo.class.getPackageName());
303+
assertThat(KafkaTestUtils.getPropertyValue(deser, "typeMapper.trustedPackages", Set.class))
304+
.contains(Foo.class.getPackageName() + ".*");
305+
}
306+
307+
@SuppressWarnings("unchecked")
308+
@Test
309+
void testTrustMappingPackagesMapper() {
310+
JsonDeserializer<Object> deser = new JsonDeserializer<>();
311+
DefaultJackson2JavaTypeMapper mapper = new DefaultJackson2JavaTypeMapper();
312+
mapper.setIdClassMapping(Collections.singletonMap("foo", Foo.class));
313+
deser.setTypeMapper(mapper);
314+
assertThat(KafkaTestUtils.getPropertyValue(deser, "typeMapper.trustedPackages", Set.class))
315+
.contains(Foo.class.getPackageName());
316+
assertThat(KafkaTestUtils.getPropertyValue(deser, "typeMapper.trustedPackages", Set.class))
317+
.contains(Foo.class.getPackageName() + ".*");
318+
}
319+
294320
@Test
295321
void testTypeFunctionViaProperties() {
296322
JsonDeserializer<Object> deser = new JsonDeserializer<>();

0 commit comments

Comments
 (0)