Repository: jwtk/jjwt
Pull request #896 (2024-01-18 09:31:05)

#893 Disable Jackson ObjectMapper FAIL_ON_UNKNOWN_PROPERTIES Deserialization Feature by default
In order to disable Jackson `ObjectMapper` `FAIL_ON_UNKNOWN_PROPERTIES` Deserialization Feature by default , Edit static `newObjectMapper` method of `JacksonSerializer`:
```
static ObjectMapper newObjectMapper() {
    return new ObjectMapper()
            .registerModule(MODULE)
            .configure(JsonParser.Feature.STRICT_DUPLICATE_DETECTION, true) // https://github.com/jwtk/jjwt/issues/877
            .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); // https://github.com/jwtk/jjwt/issues/893
}
```


**Also add specific test with `json` which has unknown field and must seserialize to custom data type.**


This PR fixs #893 


Note:
I close #894 PR and reopen this PR, because it has confilict with synchronous and same changes in #895 PR of @lhazlewood

amiriahmad72: Hi @lhazlewood
Could you please check this PR?
lhazlewood: @amiriahmad72 sorry about the delay, I should be able to review it properly today.

Patch:
diff --git a/extensions/jackson/src/main/java/io/jsonwebtoken/jackson/io/JacksonSerializer.java b/extensions/jackson/src/main/java/io/jsonwebtoken/jackson/io/JacksonSerializer.java
index 2582da5..a00541b 100644
--- a/extensions/jackson/src/main/java/io/jsonwebtoken/jackson/io/JacksonSerializer.java
+++ b/extensions/jackson/src/main/java/io/jsonwebtoken/jackson/io/JacksonSerializer.java
@@ -17,6 +17,7 @@ package io.jsonwebtoken.jackson.io;
 
 import com.fasterxml.jackson.core.JsonGenerator;
 import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.DeserializationFeature;
 import com.fasterxml.jackson.databind.Module;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.ObjectWriter;
@@ -46,17 +47,21 @@ public class JacksonSerializer<T> extends AbstractSerializer<T> {
 
     /**
      * Creates and returns a new ObjectMapper with the {@code jjwt-jackson} module registered and
-     * {@code JsonParser.Feature.STRICT_DUPLICATE_DETECTION} enabled (set to true).
+     * {@code JsonParser.Feature.STRICT_DUPLICATE_DETECTION} enabled (set to true) and
+     * {@code DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES} disabled (set to false).
+     *
+     * @return a new ObjectMapper with the {@code jjwt-jackson} module registered and
+     * {@code JsonParser.Feature.STRICT_DUPLICATE_DETECTION} enabled (set to true) and
+     * {@code DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES} disabled (set to false).
      *
-     * @return and returns a new ObjectMapper with the {@code jjwt-jackson} module registered and
-     * {@code JsonParser.Feature.STRICT_DUPLICATE_DETECTION} enabled (set to true).
      * @since 0.12.4
      */
     // package protected on purpose, do not expose to the public API
     static ObjectMapper newObjectMapper() {
         return new ObjectMapper()
                 .registerModule(MODULE)
-                .configure(JsonParser.Feature.STRICT_DUPLICATE_DETECTION, true); // https://github.com/jwtk/jjwt/issues/877
+                .configure(JsonParser.Feature.STRICT_DUPLICATE_DETECTION, true) // https://github.com/jwtk/jjwt/issues/877
+                .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); // https://github.com/jwtk/jjwt/issues/893
     }
 
     protected final ObjectMapper objectMapper;


Test patch:
diff --git a/extensions/jackson/src/test/groovy/io/jsonwebtoken/jackson/io/JacksonDeserializerTest.groovy b/extensions/jackson/src/test/groovy/io/jsonwebtoken/jackson/io/JacksonDeserializerTest.groovy
index 62f253e..2363057 100644
--- a/extensions/jackson/src/test/groovy/io/jsonwebtoken/jackson/io/JacksonDeserializerTest.groovy
+++ b/extensions/jackson/src/test/groovy/io/jsonwebtoken/jackson/io/JacksonDeserializerTest.groovy
@@ -146,6 +146,64 @@ class JacksonDeserializerTest {
         }
     }
 
+    /**
+     * Asserts https://github.com/jwtk/jjwt/issues/893
+     */
+    @Test
+    void testIgnoreUnknownPropertiesWhenDeserializeWithCustomObject() {
+        
+        long currentTime = System.currentTimeMillis()
+
+        String json = """
+             {
+                "oneKey":"oneValue", 
+                "custom": {
+                    "stringValue": "s-value",
+                    "intValue": "11",
+                    "dateValue": ${currentTime},
+                    "shortValue": 22,
+                    "longValue": 33,
+                    "byteValue": 15,
+                    "byteArrayValue": "${base64('bytes')}",
+                    "unknown": "unknown",
+                    "nestedValue": {
+                        "stringValue": "nested-value",
+                        "intValue": "111",
+                        "dateValue": ${currentTime + 1},
+                        "shortValue": 222,
+                        "longValue": 333,
+                        "byteValue": 10,
+                        "byteArrayValue": "${base64('bytes2')}",
+                        "unknown": "unknown"
+                    }
+                }
+            }
+            """
+
+        CustomBean expectedCustomBean = new CustomBean()
+                .setByteArrayValue("bytes".getBytes("UTF-8"))
+                .setByteValue(0xF as byte)
+                .setDateValue(new Date(currentTime))
+                .setIntValue(11)
+                .setShortValue(22 as short)
+                .setLongValue(33L)
+                .setStringValue("s-value")
+                .setNestedValue(new CustomBean()
+                        .setByteArrayValue("bytes2".getBytes("UTF-8"))
+                        .setByteValue(0xA as byte)
+                        .setDateValue(new Date(currentTime + 1))
+                        .setIntValue(111)
+                        .setShortValue(222 as short)
+                        .setLongValue(333L)
+                        .setStringValue("nested-value")
+                )
+
+        def expected = [oneKey: "oneValue", custom: expectedCustomBean]
+        def result = new JacksonDeserializer(Maps.of("custom", CustomBean).build())
+                .deserialize(new StringReader(json))
+        assertEquals expected, result
+    }
+
     /**
      * For: https://github.com/jwtk/jjwt/issues/564
      */