Class PolymorphicTypeValidator
- All Implemented Interfaces:
Serializable
- Direct Known Subclasses:
DefaultBaseTypeLimitingValidator
,PolymorphicTypeValidator.Base
@JsonTypeInfo
when using Java Class name as Type Identifier.
The main purpose, initially, is to allow pluggable allow lists to avoid
security problems that occur with unlimited class names
(See
this article for full explanation).
Calls to methods are done as follows:
- When a deserializer is needed for a polymorphic property (including root values) -- either
for explicitly annotated polymorphic type, or "default typing" --
validateBaseType(edu.internet2.middleware.grouperClientExt.com.fasterxml.jackson.databind.cfg.MapperConfig<?>, edu.internet2.middleware.grouperClientExt.com.fasterxml.jackson.databind.JavaType)
is called to see if validity can be determined for all possible types: ifPolymorphicTypeValidator.Validity.ALLOWED
is returned no futher checks are made for any subtypes; ofPolymorphicTypeValidator.Validity.DENIED
is returned, an exception will be thrown to indicate invalid polymorphic property - If neither deny nor allowed was returned for property with specific base type, first time
specific Type Id (Class Name) is encountered, method
validateSubClassName(edu.internet2.middleware.grouperClientExt.com.fasterxml.jackson.databind.cfg.MapperConfig<?>, edu.internet2.middleware.grouperClientExt.com.fasterxml.jackson.databind.JavaType, java.lang.String)
is called with resolved class name: it may indicate allowed/denied, resulting in either allowed use or denial with exception - If no denial/allowance indicated, class name is resolved to actual
Class
, andvalidateSubType(MapperConfig, JavaType, JavaType)
is called: ifPolymorphicTypeValidator.Validity.ALLOWED
is returned, usage is accepted; otherwise (denied or indeterminate) usage is not allowed and exception is thrown
Notes on implementations: implementations must be thread-safe and shareable (usually meaning they
are stateless). Determinations for validity are usually effectively cached on per-property
basis (by virtue of subtype deserializers being cached by polymorphic deserializers) so
caching at validator level is usually not needed. If caching is used, however, it must be done
in thread-safe manner as validators are shared within ObjectMapper
as well as possible
across mappers (in case of default/standard validator).
Also note that it is strongly recommended that all implementations are based on provided
abstract base class, PolymorphicTypeValidator.Base
which contains helper methods
and default implementations for returning PolymorphicTypeValidator.Validity.INDETERMINATE
for validation
methods (to allow only overriding relevant methods implementation cares about)
- Since:
- 2.10
- See Also:
-
Nested Class Summary
Modifier and TypeClassDescriptionstatic class
Shared base class with partial implementation (with all validation calls returningPolymorphicTypeValidator.Validity.INDETERMINATE
) and convenience methods for indicating failure reasons.static enum
Definition of return values to indicate determination regarding validity. -
Constructor Summary
-
Method Summary
Modifier and TypeMethodDescriptionabstract PolymorphicTypeValidator.Validity
validateBaseType
(MapperConfig<?> config, JavaType baseType) Method called when a property with polymorphic value is encountered, and aTypeResolverBuilder
is needed.abstract PolymorphicTypeValidator.Validity
validateSubClassName
(MapperConfig<?> config, JavaType baseType, String subClassName) abstract PolymorphicTypeValidator.Validity
validateSubType
(MapperConfig<?> config, JavaType baseType, JavaType subType) Method called after class name has been resolved to actual type, in cases where previous call tovalidateSubClassName(edu.internet2.middleware.grouperClientExt.com.fasterxml.jackson.databind.cfg.MapperConfig<?>, edu.internet2.middleware.grouperClientExt.com.fasterxml.jackson.databind.JavaType, java.lang.String)
returnedPolymorphicTypeValidator.Validity.INDETERMINATE
.
-
Constructor Details
-
PolymorphicTypeValidator
public PolymorphicTypeValidator()
-
-
Method Details
-
validateBaseType
public abstract PolymorphicTypeValidator.Validity validateBaseType(MapperConfig<?> config, JavaType baseType) Method called when a property with polymorphic value is encountered, and aTypeResolverBuilder
is needed. Intent is to allow early determination of cases where subtyping is completely denied (for example for security reasons), or, conversely, allowed for allow subtypes (when base type guarantees that all subtypes are known to be safe). Check can be thought of as both optimization (for latter case) and eager-fail (for former case) to give better feedback.- Parameters:
config
- Configuration for resolution: typically will beDeserializationConfig
baseType
- Nominal base type used for polymorphic handling: subtypes MUST be instances of this type and assignment compatibility is verified by Jackson core- Returns:
- Determination of general validity of all subtypes of given base type; if
PolymorphicTypeValidator.Validity.ALLOWED
returned, all subtypes will automatically be accepted without further checks; isPolymorphicTypeValidator.Validity.DENIED
returned no subtyping allowed at all (caller will usually throw an exception); otherwise (returnPolymorphicTypeValidator.Validity.INDETERMINATE
) per sub-type validation calls are made for each new subclass encountered.
-
validateSubClassName
public abstract PolymorphicTypeValidator.Validity validateSubClassName(MapperConfig<?> config, JavaType baseType, String subClassName) throws JsonMappingException Method called after intended class name for subtype has been read (and in case of minimal class name, expanded to fully-qualified class name) but before attempt is made to look up actualClass
orJavaType
. Validator may be able to determine validity of eventual type (and returnPolymorphicTypeValidator.Validity.ALLOWED
orPolymorphicTypeValidator.Validity.DENIED
) or, if not able to, can defer validation to actual resolved type by returningPolymorphicTypeValidator.Validity.INDETERMINATE
.Validator may also choose to indicate denial by throwing a
JsonMappingException
(such asInvalidTypeIdException
)- Parameters:
config
- Configuration for resolution: typically will beDeserializationConfig
baseType
- Nominal base type used for polymorphic handling: subtypes MUST be instances of this type and assignment compatibility is verified by Jackson coresubClassName
- Name of class that will be resolved toClass
if (and only if) validity check is not denied.- Returns:
- Determination of validity of given class name, as a subtype of given base type:
should NOT return
null
- Throws:
JsonMappingException
-
validateSubType
public abstract PolymorphicTypeValidator.Validity validateSubType(MapperConfig<?> config, JavaType baseType, JavaType subType) throws JsonMappingException Method called after class name has been resolved to actual type, in cases where previous call tovalidateSubClassName(edu.internet2.middleware.grouperClientExt.com.fasterxml.jackson.databind.cfg.MapperConfig<?>, edu.internet2.middleware.grouperClientExt.com.fasterxml.jackson.databind.JavaType, java.lang.String)
returnedPolymorphicTypeValidator.Validity.INDETERMINATE
. Validator should be able to determine validity and return appropriatePolymorphicTypeValidator.Validity
value, although it may alsoValidator may also choose to indicate denial by throwing a
JsonMappingException
(such asInvalidTypeIdException
)- Parameters:
config
- Configuration for resolution: typically will beDeserializationConfig
baseType
- Nominal base type used for polymorphic handling: subtypes MUST be instances of this type and assignment compatibility has been verified by Jackson coresubType
- Resolved subtype to validate- Returns:
- Determination of validity of given class name, as a subtype of given base type:
should NOT return
null
- Throws:
JsonMappingException
-