com.fasterxml.jackson.databind.jsontype

## Class PolymorphicTypeValidator

- java.lang.Object
- - com.fasterxml.jackson.databind.jsontype.PolymorphicTypeValidator

- All Implemented Interfaces:
    Serializable
  Direct Known Subclasses:
    DefaultBaseTypeLimitingValidator, PolymorphicTypeValidator.Base

      public abstract class PolymorphicTypeValidator
      extends Object
      implements Serializable

  Interface for classes that handle validation of class-name - based subtypes used with Polymorphic Deserialization: both via "default typing" and explicit `@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:

  1. When a deserializer is needed for a polymorphic property (including root values) -- either for explicitly annotated polymorphic type, or "default typing" -- `validateBaseType(com.fasterxml.jackson.databind.cfg.MapperConfig<?>, com.fasterxml.jackson.databind.JavaType)` is called to see if validity can be determined for all possible types: if `PolymorphicTypeValidator.Validity.ALLOWED` is returned no futher checks are made for any subtypes; of `PolymorphicTypeValidator.Validity.DENIED` is returned, an exception will be thrown to indicate invalid polymorphic property
  2. If neither deny nor allowed was returned for property with specific base type, first time specific Type Id (Class Name) is encountered, method `validateSubClassName(com.fasterxml.jackson.databind.cfg.MapperConfig<?>, 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
  3. If no denial/allowance indicated, class name is resolved to actual `Class`, and `validateSubType(MapperConfig, JavaType, JavaType)` is called: if `PolymorphicTypeValidator.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:
    Serialized Form

- - ### Nested Class Summary

    Nested Classes
    Modifier and Type | Class and Description
    --- | ---
    `static class` | `PolymorphicTypeValidator.Base` Shared base class with partial implementation (with all validation calls returning `PolymorphicTypeValidator.Validity.INDETERMINATE`) and convenience methods for indicating failure reasons.
    `static class` | `PolymorphicTypeValidator.Validity` Definition of return values to indicate determination regarding validity.

  - ### Constructor Summary

    Constructors
    Constructor and Description
    `PolymorphicTypeValidator()`

  - ### Method Summary

    All Methods Instance Methods Abstract Methods
    Modifier and Type | Method and Description
    --- | ---
    `abstract PolymorphicTypeValidator.Validity` | `validateBaseType(MapperConfig<?> config, JavaType baseType)` Method called when a property with polymorphic value is encountered, and a `TypeResolverBuilder` is needed.
    `abstract PolymorphicTypeValidator.Validity` | `validateSubClassName(MapperConfig<?> config, JavaType baseType, String subClassName)` 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 actual `Class` or `JavaType`.
    `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 to `validateSubClassName(com.fasterxml.jackson.databind.cfg.MapperConfig<?>, com.fasterxml.jackson.databind.JavaType, java.lang.String)` returned `PolymorphicTypeValidator.Validity.INDETERMINATE`.

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- - ### Constructor Detail

    - #### PolymorphicTypeValidator

          public PolymorphicTypeValidator()

  - ### Method Detail

    - #### validateBaseType

          public abstract PolymorphicTypeValidator.Validity validateBaseType(MapperConfig<?> config,
                                                                             JavaType baseType)

      Method called when a property with polymorphic value is encountered, and a `TypeResolverBuilder` 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 be `DeserializationConfig`
        `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; is `PolymorphicTypeValidator.Validity.DENIED` returned no subtyping allowed at all (caller will usually throw an exception); otherwise (return `PolymorphicTypeValidator.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 actual `Class` or `JavaType`. Validator may be able to determine validity of eventual type (and return `PolymorphicTypeValidator.Validity.ALLOWED` or `PolymorphicTypeValidator.Validity.DENIED`) or, if not able to, can defer validation to actual resolved type by returning `PolymorphicTypeValidator.Validity.INDETERMINATE`.

      Validator may also choose to indicate denial by throwing a `JsonMappingException` (such as `InvalidTypeIdException`)

      Parameters:
        `config` - Configuration for resolution: typically will be `DeserializationConfig`
        `baseType` - Nominal base type used for polymorphic handling: subtypes MUST be instances of this type and assignment compatibility is verified by Jackson core
        `subClassName` - Name of class that will be resolved to `Class` 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 to `validateSubClassName(com.fasterxml.jackson.databind.cfg.MapperConfig<?>, com.fasterxml.jackson.databind.JavaType, java.lang.String)` returned `PolymorphicTypeValidator.Validity.INDETERMINATE`. Validator should be able to determine validity and return appropriate `PolymorphicTypeValidator.Validity` value, although it may also

      Validator may also choose to indicate denial by throwing a `JsonMappingException` (such as `InvalidTypeIdException`)

      Parameters:
        `config` - Configuration for resolution: typically will be `DeserializationConfig`
        `baseType` - Nominal base type used for polymorphic handling: subtypes MUST be instances of this type and assignment compatibility has been verified by Jackson core
        `subType` - 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`

Copyright © 2008–2020 FasterXML. All rights reserved.