Skip to content

Add Jackson Support for saml2 Module #10905

@ugrave

Description

@ugrave

Describe the bug
I try to use Jackson to de/serialize http jdb session.
I create a ConversionService to use Jackson Object mapper with registred modules of SecurityJackson2Modules.

To Reproduce
Using the following ConversionService:

@Configuration(proxyBeanMethods = false)
public class SessionConfig implements BeanClassLoaderAware {

  private ClassLoader beanClassLoader;
  
  @Bean
  ConversionService springSessionConversionService() {
    ObjectMapper objectMapper = objectMapper();
    var conversionService = new GenericConversionService();
    conversionService.addConverter(new JacksonSerializer(objectMapper));
    conversionService.addConverter(new JacksonDeserializer(objectMapper));
    return conversionService;
  }

  private ObjectMapper objectMapper() {
    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.registerModules(SecurityJackson2Modules.getModules(this.beanClassLoader));
    return objectMapper;
  }

  @Override
  public void setBeanClassLoader(ClassLoader classLoader) {
    this.beanClassLoader = classLoader;
  }

  private static class JacksonSerializer implements GenericConverter {

    private final ObjectMapper objectMapper;

    public JacksonSerializer(ObjectMapper objectMapper) {
      this.objectMapper = objectMapper;
    }

    @Override
    public Set<ConvertiblePair> getConvertibleTypes() {
      return Set.of(new ConvertiblePair(Object.class, byte[].class));
    }

    @Override
    public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
      try {
        return objectMapper.writeValueAsBytes(source);
      } catch (JsonProcessingException e) {
        throw new UncheckedIOException(e);
      }
    }
  }

  private static class JacksonDeserializer implements GenericConverter {

    private final ObjectMapper objectMapper;

    public JacksonDeserializer(ObjectMapper objectMapper) {
      this.objectMapper = objectMapper;
    }

    @Override
    public Set<ConvertiblePair> getConvertibleTypes() {
      return Set.of(new ConvertiblePair(byte[].class, Object.class));
    }

    @Override
    public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
      try {
        return objectMapper.readValue((byte[]) source, targetType.getType());
      } catch (IOException e) {
        throw new UncheckedIOException(e);
      }
    }
  }

}

Will result in the following error on deserilization of http session:

Caused by: java.lang.IllegalArgumentException: The class with org.springframework.security.saml2.provider.service.authentication.Saml2Authentication and name of org.springframework.security.saml2.provider.service.authentication.Saml2Authentication is not in the allowlist. If you believe this class is safe to deserialize, please provide an explicit mapping using Jackson annotations or by providing a Mixin. If the serialization is only done by a trusted source, you can also enable default typing. See https://github.com/spring-projects/spring-security/issues/4370 for details
2022-02-24T08:42:22.271701000Z 	at org.springframework.security.jackson2.SecurityJackson2Modules$AllowlistTypeIdResolver.typeFromId(SecurityJackson2Modules.java:259)

Expected behavior
Would be nice if the SAML classes are also part of the SecurityJackson2Modules (as it is already for other security relates classes).

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions