Patch request deserialization is case sensitive
Something seems to be wrong with Jackson where deserialization of a patch request with operations having "OP" instead of "op" causes failures.
Updating this issue with a few more details in case I need to look at it later.
The following cases will cause deserialization failures:
- The 'op' field of a patch operation uses some other case, such as 'OP'.
- The 'Operations' field of a patch request uses some other case, such as 'operations'.
- The 'value' field of a patch operation uses some other case.
The following case will cause 'path' to be treated as if it were null, which will result in unintended behavior and possibly an error, depending on the value of 'value':
- The 'path' field of a patch operation uses some other case.
In com.unboundid.scim2.common.utils.MapperFactory, we configure the SDK object mapper to use MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, so we wouldn't expect any of the above cases to happen. And this mapper feature does work for cases of simple POJO field annotation with @JsonProperty. But it looks as if Jackson simply fails to apply this mapper feature for the following annotation scenarios:
- Polymorphic deserialization using the
@JsonTypeInfoand@JsonSubTypesannotations. This applies to the first case above. - Annotating a constructor with
@JsonCreatorand its arguments with@JsonProperty. This applies to the other cases.
We just ran into a similar issue while trying to use this library with Azure AD. Azure Patch requests are sending operations of "Replace" and "Add" instead of "replace" and "add" like the ping identity library is expecting.
@JasonMathison sorry for the blast from the past, but I've encountered the same issue with Azure AD. Curious if you found a solution in the end.
We ended up preprocessing the patch messages in order to work around issues like this. So in this case we look for "Replace" or "Add" operations and change them to "replace" and "add". I don't have all of the details handy, but be warned that there are other ways that Azure doesn't follow the RFC the way that Ping expects, so there are a few other scenarios you will likely have to account for.
@JasonMathison really appreciate the reply. That's the only solution I had thought up so far as well; we'll have to move in that direction for now and perhaps later focus on contributing a fix upstream for the long-term. Thanks!
It turns out that this is a simple configuration change for the ObjectMapper that the sdk uses. The necessary feature is MapperFeature.ACCEPT_CASE_INSENSITIVE_VALUES.
Feature that permits parsing some enumerated text-based value types but ignoring the case of the values on deserialization: for example, date/time type deserializers.
Enabling that feature has us up and running with Azure AD patch requests. If you are using Spring Boot, it is a pretty simple change:
@Bean
public ObjectMapper objectMapper() {
ObjectMapper mapper = JsonUtils.createObjectMapper();
mapper.enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_VALUES);
return mapper;
}
Seems to be a duplicate of https://github.com/pingidentity/scim2/issues/152 ?