From fd660f11ef3b25a22c2c7806e2e7a7f466b3d28e Mon Sep 17 00:00:00 2001 From: hyeonjune Date: Sun, 31 May 2026 08:09:05 +0900 Subject: [PATCH] fix: add allowIfSubType for URL and Instant in OAuth2ClientJacksonModule Signed-off-by: hyeonjune --- .../jackson/OAuth2ClientJacksonModule.java | 7 ++++- .../OAuth2AuthenticationTokenMixinTests.java | 30 +++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/jackson/OAuth2ClientJacksonModule.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/jackson/OAuth2ClientJacksonModule.java index 0d27b4eec11..21060dfc426 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/jackson/OAuth2ClientJacksonModule.java +++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/jackson/OAuth2ClientJacksonModule.java @@ -16,6 +16,9 @@ package org.springframework.security.oauth2.client.jackson; +import java.net.URL; +import java.time.Instant; + import tools.jackson.core.Version; import tools.jackson.databind.jsontype.BasicPolymorphicTypeValidator; @@ -94,7 +97,9 @@ public void configurePolymorphicTypeValidator(BasicPolymorphicTypeValidator.Buil .allowIfSubType(OAuth2RefreshToken.class) .allowIfSubType(OAuth2AuthenticationToken.class) .allowIfSubType(OidcUserAuthority.class) - .allowIfSubType(OAuth2UserAuthority.class); + .allowIfSubType(OAuth2UserAuthority.class) + .allowIfSubType(URL.class) + .allowIfSubType(Instant.class); } @Override diff --git a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/jackson/OAuth2AuthenticationTokenMixinTests.java b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/jackson/OAuth2AuthenticationTokenMixinTests.java index d24cf351f88..ec1b36fa979 100644 --- a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/jackson/OAuth2AuthenticationTokenMixinTests.java +++ b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/jackson/OAuth2AuthenticationTokenMixinTests.java @@ -16,11 +16,14 @@ package org.springframework.security.oauth2.client.jackson; +import java.net.URL; import java.time.Instant; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; import com.fasterxml.jackson.datatype.jsr310.DecimalUtils; @@ -171,6 +174,33 @@ public void deserializeWhenRequiredAttributesOnlyThenDeserializes() throws Excep assertThat(principal.getUserInfo()).isNull(); } + @Test + public void deserializeWhenClaimsContainUrlAndInstantThenDeserializes() throws Exception { + Map claims = new HashMap<>(); + Instant issuedAt = Instant.now(); + Instant expiresAt = issuedAt.plusSeconds(3600); + claims.put(IdTokenClaimNames.ISS, new URL("http://localhost/issuer")); + claims.put(IdTokenClaimNames.SUB, "subject"); + claims.put(IdTokenClaimNames.IAT, issuedAt); + claims.put(IdTokenClaimNames.EXP, expiresAt); + + OidcIdToken idToken = new OidcIdToken("id-token", issuedAt, expiresAt, claims); + Collection authorities = + Collections.singleton(new OidcUserAuthority(idToken)); + DefaultOidcUser principal = new DefaultOidcUser(authorities, idToken); + OAuth2AuthenticationToken authentication = + new OAuth2AuthenticationToken(principal, authorities, "registration-id"); + + String json = this.mapper.writeValueAsString(authentication); + OAuth2AuthenticationToken deserialized = + this.mapper.readValue(json, OAuth2AuthenticationToken.class); + + assertThat(deserialized).isNotNull(); + DefaultOidcUser deserializedUser = (DefaultOidcUser) deserialized.getPrincipal(); + assertThat(deserializedUser.getIdToken().getClaims()) + .containsKey(IdTokenClaimNames.ISS); + } + private static String asJson(OAuth2AuthenticationToken authentication) { String principalJson = (authentication.getPrincipal() instanceof DefaultOidcUser) ? asJson((DefaultOidcUser) authentication.getPrincipal())