Skip to content

Conversation

sdeleuze
Copy link

@sdeleuze sdeleuze commented Sep 1, 2025

This PR adds support for Jackson 3 which has the following major differences with the Jackson 2 one:

  • jackson subpackage instead of jackson2
  • Jackson type prefix instead of Jackson2
  • JsonMapper instead of ObjectMapper
  • For configuration, JsonMapper.Builder instead of ObjectMapper since the latter is now immutable
  • AllowlistTypeResolverBuilder in new a public type in order to be used easily with the JsonMapper.Builder API

Jackson 3 changes compared to Jackson 2 are documented on FasterXML/jackson-future-ideas#72.

It also deprecates Jackson 2 support for removal.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Sep 1, 2025
Copy link
Member

@rwinch rwinch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the pull request. Generally, I think this is looking good. I've provided some feedback inline.

It also appears that there are still some classes that need migrated. Searching for jackson on main should give you a complete list of classes that are using jackson.

For example, webauthn has jackson support. I'm guessing this was missed because it is inconsistent with the rest of the jackson support in that it is in a jackson package rather than jackson2. It is also automatically registered because it does not use default types which would make it insecure.

There are also some tests that still use ObjectMapper or deprecated Spring Framework Jackson 2 classes (e.g. JwtDecodersTests.java#L388). Unless the test is specifically for the Jackson 2 support, we should update these to use non-deprecated classes (e.g. JsonMapper).

There are various Spring framework jackson based classes that have been deprecated that we should migrate away from. For example, MappingJackson2HttpMessageConverter usage (e.g. WebAuthnAuthenticationFilter.converter) should be migrated to JacksonJsonHttpMessageConverter if jackson 3 is on the classpath. Likely there could be a static factory method used that Spring Security uses to obtain the correct default json converter instance.

@sdeleuze
Copy link
Author

sdeleuze commented Sep 8, 2025

@rwinch I have pushed additional commits:

I will do another pass with your feedback to my questions in the comments.

@sdeleuze sdeleuze force-pushed the jackson3 branch 2 times, most recently from e7d5c41 to 20a69ea Compare September 10, 2025 21:06
sdeleuze added a commit to sdeleuze/spring-security that referenced this pull request Sep 10, 2025
See spring-projectsgh-17832
Signed-off-by: Sébastien Deleuze <[email protected]>
sdeleuze added a commit to sdeleuze/spring-security that referenced this pull request Sep 10, 2025
This commit adds support for Jackson 3 which has the following
major differences with the Jackson 2 one:
 - jackson subpackage instead of jackson2
 - Jackson type prefix instead of Jackson2
 - JsonMapper instead of ObjectMapper
 - For configuration, JsonMapper.Builder instead of ObjectMapper
   since the latter is now immutable
 - Remove custom Jackson 3 support for unmodifiable collections
 - AllowlistTypeResolverBuilder in new a public type in order
   to be used easily with the JsonMapper.Builder API

Jackson 3 changes compared to Jackson 2 are documented on
FasterXML/jackson-future-ideas#72.

This commit does not cover webauthn which is a special case (uses
jackson sub-package for Jackson 2 support) which will be handled in
a distinct commit.

See spring-projectsgh-17832
Signed-off-by: Sébastien Deleuze <[email protected]>
sdeleuze added a commit to sdeleuze/spring-security that referenced this pull request Sep 10, 2025
This commit does not cover webauthn which is a special case (uses
jackson sub-package for Jackson 2 support) which will be handled in
a distinct commit.

See spring-projectsgh-17832
Signed-off-by: Sébastien Deleuze <[email protected]>
sdeleuze added a commit to sdeleuze/spring-security that referenced this pull request Sep 10, 2025
Since this module was already using the jackson sub-package for Jackson 2
support, both Jackson 2 and Jackson 3 support lives in the same subpackage
and the former package-private classes has been renamed with a Jackson2
qualifier.

Closes spring-projectsgh-17832
Signed-off-by: Sébastien Deleuze <[email protected]>
@sdeleuze
Copy link
Author

@rwinch I have removed the custom support for unmodifiable collections (seems to work fine with Jackson 3), reworked the commit for a cleaner git history, and rebased the commits on main.

This was referenced May 14, 2025
sdeleuze added a commit to sdeleuze/spring-security that referenced this pull request Sep 25, 2025
See spring-projectsgh-17832
Signed-off-by: Sébastien Deleuze <[email protected]>
sdeleuze added a commit to sdeleuze/spring-security that referenced this pull request Sep 25, 2025
This commit adds support for Jackson 3 which has the following
major differences with the Jackson 2 one:
 - jackson subpackage instead of jackson2
 - Jackson type prefix instead of Jackson2
 - JsonMapper instead of ObjectMapper
 - For configuration, JsonMapper.Builder instead of ObjectMapper
   since the latter is now immutable
 - Remove custom Jackson 3 support for unmodifiable collections
 - AllowlistTypeResolverBuilder in new a public type in order
   to be used easily with the JsonMapper.Builder API

Jackson 3 changes compared to Jackson 2 are documented on
FasterXML/jackson-future-ideas#72.

This commit does not cover webauthn which is a special case (uses
jackson sub-package for Jackson 2 support) which will be handled in
a distinct commit.

See spring-projectsgh-17832
Signed-off-by: Sébastien Deleuze <[email protected]>
sdeleuze added a commit to sdeleuze/spring-security that referenced this pull request Sep 25, 2025
This commit does not cover webauthn which is a special case (uses
jackson sub-package for Jackson 2 support) which will be handled in
a distinct commit.

See spring-projectsgh-17832
Signed-off-by: Sébastien Deleuze <[email protected]>
sdeleuze added a commit to sdeleuze/spring-security that referenced this pull request Sep 25, 2025
Since this module was already using the jackson sub-package for Jackson 2
support, both Jackson 2 and Jackson 3 support lives in the same subpackage
and the former package-private classes has been renamed with a Jackson2
qualifier.

Closes spring-projectsgh-17832
Signed-off-by: Sébastien Deleuze <[email protected]>
@jvalkeal
Copy link
Contributor

@sdeleuze @rwinch I was wondering if message converters in oauth2-core will also be part of this PR.

static {
ClassLoader classLoader = HttpMessageConverters.class.getClassLoader();
jackson2Present = ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", classLoader)
&& ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator", classLoader);
gsonPresent = ClassUtils.isPresent("com.google.gson.Gson", classLoader);
jsonbPresent = ClassUtils.isPresent("jakarta.json.bind.Jsonb", classLoader);
}

That's then causing NPE's i.e in OAuth2AccessTokenResponseHttpMessageConverter as jsonMessageConverter will always be null. Same with other classes in that same package if I only have jackson3 in a classpath.

sdeleuze added a commit to sdeleuze/spring-security that referenced this pull request Sep 28, 2025
Since this module was already using the jackson sub-package for Jackson 2
support, both Jackson 2 and Jackson 3 support lives in the same subpackage
and the former package-private classes has been renamed with a Jackson2
qualifier.

See spring-projectsgh-17832
Signed-off-by: Sébastien Deleuze <[email protected]>
sdeleuze added a commit to sdeleuze/spring-security that referenced this pull request Sep 28, 2025
This commits remove global default typing for better security
and use instead a custom PolymorphicTypeValidator. See
https://cowtowncoder.medium.com/jackson-2-10-safe-default-typing-2d018f0ce2ba
for more details.

See spring-projectsgh-17832
Signed-off-by: Sébastien Deleuze <[email protected]>
@sdeleuze
Copy link
Author

@jvalkeal Good catch, I will add a related commit.

sdeleuze added a commit to sdeleuze/spring-security that referenced this pull request Oct 3, 2025
See spring-projectsgh-17832
Signed-off-by: Sébastien Deleuze <[email protected]>
sdeleuze added a commit to sdeleuze/spring-security that referenced this pull request Oct 3, 2025
This commit adds support for Jackson 3 which has the following
major differences with the Jackson 2 one:
 - jackson subpackage instead of jackson2
 - Jackson type prefix instead of Jackson2
 - JsonMapper instead of ObjectMapper
 - For configuration, JsonMapper.Builder instead of ObjectMapper
   since the latter is now immutable
 - Remove custom Jackson 3 support for unmodifiable collections
 - AllowlistTypeResolverBuilder in new a public type in order
   to be used easily with the JsonMapper.Builder API

Jackson 3 changes compared to Jackson 2 are documented on
FasterXML/jackson-future-ideas#72.

This commit does not cover webauthn which is a special case (uses
jackson sub-package for Jackson 2 support) which will be handled in
a distinct commit.

See spring-projectsgh-17832
Signed-off-by: Sébastien Deleuze <[email protected]>
sdeleuze added a commit to sdeleuze/spring-security that referenced this pull request Oct 3, 2025
This commit does not cover webauthn which is a special case (uses
jackson sub-package for Jackson 2 support) which will be handled in
a distinct commit.

See spring-projectsgh-17832
Signed-off-by: Sébastien Deleuze <[email protected]>
sdeleuze added a commit to sdeleuze/spring-security that referenced this pull request Oct 3, 2025
Since this module was already using the jackson sub-package for Jackson 2
support, both Jackson 2 and Jackson 3 support lives in the same subpackage
and the former package-private classes has been renamed with a Jackson2
qualifier.

See spring-projectsgh-17832
Signed-off-by: Sébastien Deleuze <[email protected]>
sdeleuze added a commit to sdeleuze/spring-security that referenced this pull request Oct 3, 2025
This commits remove global default typing for better security
and use instead a custom PolymorphicTypeValidator which can be
configured by each Spring Security module and customized by the
end users.

See
https://cowtowncoder.medium.com/jackson-2-10-safe-default-typing-2d018f0ce2ba
for more details.

See spring-projectsgh-17832
Signed-off-by: Sébastien Deleuze <[email protected]>
sdeleuze added a commit to sdeleuze/spring-security that referenced this pull request Oct 3, 2025
This commit introduces classpath checks and instantiation of
JacksonJsonHttpMessageConverter (based on Jackson 3) leveraging
a new GenericHttpMessageConverterAdapter which allows to adapt
SmartHttpMessageConverter to GenericHttpMessageConverter.

Closes spring-projectsgh-17832
Signed-off-by: Sébastien Deleuze <[email protected]>
@sdeleuze
Copy link
Author

sdeleuze commented Oct 3, 2025

@rwinch The PR is ready for a new review.

It removes global default typing, allow customization of the authorized types via a PolymorphicTypeValidator , including by the end user. The HttpMessageConverters issue reported by @jvalkeal has also been fixed.

The main missing part is the "Jackson 2 compatibility mode with Jackson 3". It will be implemented via a SecurityJackson2CompatibilityModules that will create a builder with JsonMapper.builderWithJackson2Defaults(), reuse Jackson 2 mixins and apply them to Jackson 3 and keep global default typing enabled.

sdeleuze added a commit to sdeleuze/spring-security that referenced this pull request Oct 6, 2025
See spring-projectsgh-17832
Signed-off-by: Sébastien Deleuze <[email protected]>
sdeleuze added a commit to sdeleuze/spring-security that referenced this pull request Oct 6, 2025
This commit adds support for Jackson 3 which has the following
major differences with the Jackson 2 one:
 - jackson subpackage instead of jackson2
 - Jackson type prefix instead of Jackson2
 - JsonMapper instead of ObjectMapper
 - For configuration, JsonMapper.Builder instead of ObjectMapper
   since the latter is now immutable
 - Remove custom Jackson 3 support for unmodifiable collections
 - AllowlistTypeResolverBuilder in new a public type in order
   to be used easily with the JsonMapper.Builder API

Jackson 3 changes compared to Jackson 2 are documented on
FasterXML/jackson-future-ideas#72.

This commit does not cover webauthn which is a special case (uses
jackson sub-package for Jackson 2 support) which will be handled in
a distinct commit.

See spring-projectsgh-17832
Signed-off-by: Sébastien Deleuze <[email protected]>
sdeleuze added a commit to sdeleuze/spring-security that referenced this pull request Oct 6, 2025
This commit does not cover webauthn which is a special case (uses
jackson sub-package for Jackson 2 support) which will be handled in
a distinct commit.

See spring-projectsgh-17832
Signed-off-by: Sébastien Deleuze <[email protected]>
sdeleuze added a commit to sdeleuze/spring-security that referenced this pull request Oct 6, 2025
Since this module was already using the jackson sub-package for Jackson 2
support, both Jackson 2 and Jackson 3 support lives in the same subpackage
and the former package-private classes has been renamed with a Jackson2
qualifier.

See spring-projectsgh-17832
Signed-off-by: Sébastien Deleuze <[email protected]>
sdeleuze added a commit to sdeleuze/spring-security that referenced this pull request Oct 6, 2025
This commits remove global default typing for better security
and use instead a custom PolymorphicTypeValidator which can be
configured by each Spring Security module and customized by the
end users.

See
https://cowtowncoder.medium.com/jackson-2-10-safe-default-typing-2d018f0ce2ba
for more details.

See spring-projectsgh-17832
Signed-off-by: Sébastien Deleuze <[email protected]>
sdeleuze added a commit to sdeleuze/spring-security that referenced this pull request Oct 6, 2025
This commit introduces classpath checks and instantiation of
JacksonJsonHttpMessageConverter (based on Jackson 3) leveraging
a new GenericHttpMessageConverterAdapter which allows to adapt
SmartHttpMessageConverter to GenericHttpMessageConverter.

Closes spring-projectsgh-17832
Signed-off-by: Sébastien Deleuze <[email protected]>
@sdeleuze
Copy link
Author

sdeleuze commented Oct 6, 2025

PR updated to use Jackson 3.0.0 GA which has just been released.

The DefaultLoginPageGeneratingFilterTests broken test on the CI works fine locally, and was fine with previous build with Jackson 3.0.0-rc10 which is identical to 3.0.0, so I guess that's flaky test that should be fine in the next build.

@sdeleuze
Copy link
Author

sdeleuze commented Oct 6, 2025

Looks like I have missed OAuth2AuthorizationServerJackson2Module which has been added recently, so I will migrate that one as well.

@rwinch
Copy link
Member

rwinch commented Oct 6, 2025

Thanks for all the updates @sdeleuze I'm reviewing now.

The DefaultLoginPageGeneratingFilterTests broken test on the CI works fine locally, and was fine with previous build with Jackson 3.0.0-rc10 which is identical to 3.0.0, so I guess that's flaky test that should be fine in the next build.

If you rebase, this should be fixed in 83da86a which will be resolved more comprehensively in #18012

See spring-projectsgh-17832
Signed-off-by: Sébastien Deleuze <[email protected]>
This commit adds support for Jackson 3 which has the following
major differences with the Jackson 2 one:
 - jackson subpackage instead of jackson2
 - Jackson type prefix instead of Jackson2
 - JsonMapper instead of ObjectMapper
 - For configuration, JsonMapper.Builder instead of ObjectMapper
   since the latter is now immutable
 - Remove custom Jackson 3 support for unmodifiable collections
 - AllowlistTypeResolverBuilder in new a public type in order
   to be used easily with the JsonMapper.Builder API

Jackson 3 changes compared to Jackson 2 are documented on
FasterXML/jackson-future-ideas#72.

This commit does not cover webauthn which is a special case (uses
jackson sub-package for Jackson 2 support) which will be handled in
a distinct commit.

See spring-projectsgh-17832
Signed-off-by: Sébastien Deleuze <[email protected]>
This commit does not cover webauthn which is a special case (uses
jackson sub-package for Jackson 2 support) which will be handled in
a distinct commit.

See spring-projectsgh-17832
Signed-off-by: Sébastien Deleuze <[email protected]>
Since this module was already using the jackson sub-package for Jackson 2
support, both Jackson 2 and Jackson 3 support lives in the same subpackage
and the former package-private classes has been renamed with a Jackson2
qualifier.

See spring-projectsgh-17832
Signed-off-by: Sébastien Deleuze <[email protected]>
Signed-off-by: Sébastien Deleuze <[email protected]>
This commits remove global default typing for better security
and use instead a custom PolymorphicTypeValidator which can be
configured by each Spring Security module and customized by the
end users.

See
https://cowtowncoder.medium.com/jackson-2-10-safe-default-typing-2d018f0ce2ba
for more details.

See spring-projectsgh-17832
Signed-off-by: Sébastien Deleuze <[email protected]>
This commit introduces classpath checks and instantiation of
JacksonJsonHttpMessageConverter (based on Jackson 3) leveraging
a new GenericHttpMessageConverterAdapter which allows to adapt
SmartHttpMessageConverter to GenericHttpMessageConverter.

Closes spring-projectsgh-17832
Signed-off-by: Sébastien Deleuze <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: waiting-for-triage An issue we've not yet triaged
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants