From 16aedb7012830085a10be0ef0aee9c7bbf98b65e Mon Sep 17 00:00:00 2001 From: Junlin Zhou Date: Tue, 23 Nov 2021 17:28:43 +0800 Subject: [PATCH] Fix OAuth2ClientAuthenticationToken deserialization --- .../jackson2/AuthorizationGrantTypeMixin.java | 30 ++++++ .../ClientAuthenticationMethodMixin.java | 29 ++++++ .../jackson2/ClientSettingsDeserializer.java | 29 ++++++ .../jackson2/ClientSettingsMixin.java | 17 ++++ .../authorization/jackson2/InstantMixin.java | 31 ++++++ ...uth2AuthorizationServerJackson2Module.java | 14 +++ ...ClientAuthenticationTokenDeserializer.java | 67 +++++++++++++ .../OAuth2ClientAuthenticationTokenMixin.java | 17 ++++ .../RegisteredClientDeserializer.java | 96 +++++++++++++++++++ .../jackson2/RegisteredClientMixin.java | 17 ++++ .../jackson2/TokenSettingsDeserializer.java | 32 +++++++ .../jackson2/TokenSettingsMixin.java | 17 ++++ 12 files changed, 396 insertions(+) create mode 100644 oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/AuthorizationGrantTypeMixin.java create mode 100644 oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/ClientAuthenticationMethodMixin.java create mode 100644 oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/ClientSettingsDeserializer.java create mode 100644 oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/ClientSettingsMixin.java create mode 100644 oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/InstantMixin.java create mode 100644 oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/OAuth2ClientAuthenticationTokenDeserializer.java create mode 100644 oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/OAuth2ClientAuthenticationTokenMixin.java create mode 100644 oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/RegisteredClientDeserializer.java create mode 100644 oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/RegisteredClientMixin.java create mode 100644 oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/TokenSettingsDeserializer.java create mode 100644 oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/TokenSettingsMixin.java diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/AuthorizationGrantTypeMixin.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/AuthorizationGrantTypeMixin.java new file mode 100644 index 000000000..a36d4a6d8 --- /dev/null +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/AuthorizationGrantTypeMixin.java @@ -0,0 +1,30 @@ +package org.springframework.security.oauth2.server.authorization.jackson2; + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonGetter; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeInfo; + + +/** + * Jackson Mixin class helps in serialize/deserialize + * {@link org.springframework.security.oauth2.core.AuthorizationGrantType}. + * + * @author Junlin Zhou + */ +@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS) +@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.NONE, + getterVisibility = JsonAutoDetect.Visibility.PUBLIC_ONLY, isGetterVisibility = JsonAutoDetect.Visibility.NONE) +@JsonIgnoreProperties(ignoreUnknown = true) +abstract class AuthorizationGrantTypeMixin { + + @JsonGetter("value") + abstract long getValue(); + + @JsonCreator + public AuthorizationGrantTypeMixin(@JsonProperty("value") String value) { + } + +} diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/ClientAuthenticationMethodMixin.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/ClientAuthenticationMethodMixin.java new file mode 100644 index 000000000..3a06d3749 --- /dev/null +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/ClientAuthenticationMethodMixin.java @@ -0,0 +1,29 @@ +package org.springframework.security.oauth2.server.authorization.jackson2; + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonGetter; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeInfo; + +/** + * Jackson Mixin class helps in serialize/deserialize + * {@link org.springframework.security.oauth2.core.ClientAuthenticationMethod}. + * + * @author Junlin Zhou + */ +@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS) +@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.NONE, + getterVisibility = JsonAutoDetect.Visibility.PUBLIC_ONLY, isGetterVisibility = JsonAutoDetect.Visibility.NONE) +@JsonIgnoreProperties(ignoreUnknown = true) +abstract class ClientAuthenticationMethodMixin { + + @JsonGetter("value") + abstract long getValue(); + + @JsonCreator + public ClientAuthenticationMethodMixin(@JsonProperty("value") String value) { + } + +} diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/ClientSettingsDeserializer.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/ClientSettingsDeserializer.java new file mode 100644 index 000000000..034d13786 --- /dev/null +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/ClientSettingsDeserializer.java @@ -0,0 +1,29 @@ +package org.springframework.security.oauth2.server.authorization.jackson2; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.security.oauth2.server.authorization.config.ClientSettings; + +import java.io.IOException; +import java.util.Map; + +/** + * Deserializer used for deserializing {@link ClientSettings} from JSON. + * + * @author Junlin Zhou + */ +public class ClientSettingsDeserializer extends JsonDeserializer { + + @Override + public ClientSettings deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { + ObjectMapper mapper = (ObjectMapper) p.getCodec(); + JsonNode root = mapper.readTree(p); + Map settings = JsonNodeUtils + .findValue(root, "settings", JsonNodeUtils.STRING_OBJECT_MAP, mapper); + return ClientSettings.withSettings(settings).build(); + } + +} diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/ClientSettingsMixin.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/ClientSettingsMixin.java new file mode 100644 index 000000000..de874655e --- /dev/null +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/ClientSettingsMixin.java @@ -0,0 +1,17 @@ +package org.springframework.security.oauth2.server.authorization.jackson2; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * Jackson Mixin class helps in serialize/deserialize + * {@link org.springframework.security.oauth2.server.authorization.config.ClientSettings}. + * + * @author Junlin Zhou + */ +@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS) +@JsonDeserialize(using = ClientSettingsDeserializer.class) +@JsonIgnoreProperties(ignoreUnknown = true) +abstract class ClientSettingsMixin { +} diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/InstantMixin.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/InstantMixin.java new file mode 100644 index 000000000..b2933e0cc --- /dev/null +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/InstantMixin.java @@ -0,0 +1,31 @@ +package org.springframework.security.oauth2.server.authorization.jackson2; + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonGetter; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeInfo; + +/** + * Jackson Mixin class helps in serialize/deserialize + * {@link java.time.Instant}. + * + * @author Junlin Zhou + */ +@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS) +@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.NONE, getterVisibility = JsonAutoDetect.Visibility.NONE, + isGetterVisibility = JsonAutoDetect.Visibility.NONE, setterVisibility = JsonAutoDetect.Visibility.NONE, + creatorVisibility = JsonAutoDetect.Visibility.NONE) +abstract class InstantMixin { + + @JsonCreator + static void ofSeconds(@JsonProperty("seconds") long seconds, @JsonProperty("nano") long nanoAdjustment) { + } + + @JsonGetter("seconds") + abstract long getSeconds(); + + @JsonGetter("nano") + abstract int getNano(); + +} diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/OAuth2AuthorizationServerJackson2Module.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/OAuth2AuthorizationServerJackson2Module.java index ee71d5db7..ba1a8b35d 100644 --- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/OAuth2AuthorizationServerJackson2Module.java +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/OAuth2AuthorizationServerJackson2Module.java @@ -16,6 +16,7 @@ package org.springframework.security.oauth2.server.authorization.jackson2; import java.time.Duration; +import java.time.Instant; import java.util.Collections; import java.util.HashSet; import java.util.LinkedHashSet; @@ -24,8 +25,14 @@ import com.fasterxml.jackson.databind.module.SimpleModule; import org.springframework.security.jackson2.SecurityJackson2Modules; +import org.springframework.security.oauth2.core.AuthorizationGrantType; +import org.springframework.security.oauth2.core.ClientAuthenticationMethod; import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest; import org.springframework.security.oauth2.jose.jws.SignatureAlgorithm; +import org.springframework.security.oauth2.server.authorization.authentication.OAuth2ClientAuthenticationToken; +import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; +import org.springframework.security.oauth2.server.authorization.config.ClientSettings; +import org.springframework.security.oauth2.server.authorization.config.TokenSettings; /** * Jackson {@code Module} for {@code spring-authorization-server}, that registers the @@ -75,7 +82,14 @@ public void setupModule(SetupContext context) { context.setMixInAnnotations(LinkedHashSet.class, HashSetMixin.class); context.setMixInAnnotations(OAuth2AuthorizationRequest.class, OAuth2AuthorizationRequestMixin.class); context.setMixInAnnotations(Duration.class, DurationMixin.class); + context.setMixInAnnotations(Instant.class, InstantMixin.class); context.setMixInAnnotations(SignatureAlgorithm.class, SignatureAlgorithmMixin.class); + context.setMixInAnnotations(OAuth2ClientAuthenticationToken.class, OAuth2ClientAuthenticationTokenMixin.class); + context.setMixInAnnotations(RegisteredClient.class, RegisteredClientMixin.class); + context.setMixInAnnotations(AuthorizationGrantType.class, AuthorizationGrantTypeMixin.class); + context.setMixInAnnotations(ClientAuthenticationMethod.class, ClientAuthenticationMethodMixin.class); + context.setMixInAnnotations(TokenSettings.class, TokenSettingsMixin.class); + context.setMixInAnnotations(ClientSettings.class, ClientSettingsMixin.class); } } diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/OAuth2ClientAuthenticationTokenDeserializer.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/OAuth2ClientAuthenticationTokenDeserializer.java new file mode 100644 index 000000000..6fb417230 --- /dev/null +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/OAuth2ClientAuthenticationTokenDeserializer.java @@ -0,0 +1,67 @@ +package org.springframework.security.oauth2.server.authorization.jackson2; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.util.StdConverter; +import org.springframework.security.oauth2.core.ClientAuthenticationMethod; +import org.springframework.security.oauth2.server.authorization.authentication.OAuth2ClientAuthenticationToken; +import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; + +import java.io.IOException; +import java.util.Map; + +/** + * Deserializer used for deserializing {@link OAuth2ClientAuthenticationToken} from JSON. + * + * @author Junlin Zhou + */ +public class OAuth2ClientAuthenticationTokenDeserializer extends JsonDeserializer { + + private static final StdConverter CLIENT_AUTHENTICATION_METHOD_CONVERTER = + new StdConverters.ClientAuthenticationMethodConverter(); + + private static final TypeReference REGISTERED_CLIENT_TYPE_REFERENCE = + new TypeReference() { + }; + + /** + * {@inheritDoc} + */ + @Override + public OAuth2ClientAuthenticationToken deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { + ObjectMapper mapper = (ObjectMapper) p.getCodec(); + JsonNode root = mapper.readTree(p); + + Object credentials = JsonNodeUtils.findStringValue(root, "credentials"); + + ClientAuthenticationMethod clientAuthenticationMethod = CLIENT_AUTHENTICATION_METHOD_CONVERTER + .convert(JsonNodeUtils.findObjectNode(root, "clientAuthenticationMethod")); + + boolean authenticated = findBooleanValue(root, "authenticated"); + + if (authenticated) { + RegisteredClient registeredClient = JsonNodeUtils + .findValue(root, "registeredClient", REGISTERED_CLIENT_TYPE_REFERENCE, mapper); + return new OAuth2ClientAuthenticationToken(registeredClient, clientAuthenticationMethod, credentials); + } else { + String clientId = JsonNodeUtils.findStringValue(root, "clientId"); + Map additionalParameters = JsonNodeUtils + .findValue(root, "additionalParameters", JsonNodeUtils.STRING_OBJECT_MAP, mapper); + return new OAuth2ClientAuthenticationToken(clientId, clientAuthenticationMethod, credentials, + additionalParameters); + } + } + + private boolean findBooleanValue(JsonNode jsonNode, String fieldName) { + if (jsonNode == null) { + return false; + } + JsonNode value = jsonNode.findValue(fieldName); + return (value != null && value.asBoolean()); + } + +} diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/OAuth2ClientAuthenticationTokenMixin.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/OAuth2ClientAuthenticationTokenMixin.java new file mode 100644 index 000000000..185d41fa5 --- /dev/null +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/OAuth2ClientAuthenticationTokenMixin.java @@ -0,0 +1,17 @@ +package org.springframework.security.oauth2.server.authorization.jackson2; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * Jackson Mixin class helps in serialize/deserialize + * {@link org.springframework.security.oauth2.server.authorization.authentication.OAuth2ClientAuthenticationToken}. + * + * @author Junlin Zhou + */ +@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS) +@JsonDeserialize(using = OAuth2ClientAuthenticationTokenDeserializer.class) +@JsonIgnoreProperties(ignoreUnknown = true) +abstract class OAuth2ClientAuthenticationTokenMixin { +} diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/RegisteredClientDeserializer.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/RegisteredClientDeserializer.java new file mode 100644 index 000000000..f4c4a0b0a --- /dev/null +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/RegisteredClientDeserializer.java @@ -0,0 +1,96 @@ +package org.springframework.security.oauth2.server.authorization.jackson2; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.security.oauth2.core.AuthorizationGrantType; +import org.springframework.security.oauth2.core.ClientAuthenticationMethod; +import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; +import org.springframework.security.oauth2.server.authorization.config.ClientSettings; +import org.springframework.security.oauth2.server.authorization.config.TokenSettings; + +import java.io.IOException; +import java.time.Instant; +import java.util.Set; + +/** + * Deserializer used for deserializing {@link RegisteredClient} from JSON. + * + * @author Junlin Zhou + */ +public class RegisteredClientDeserializer extends JsonDeserializer { + + private static final TypeReference> AUTHORIZATION_GRANT_TYPE_SET = + new TypeReference>() { + }; + + private static final TypeReference> CLIENT_AUTHENTICATION_METHOD_SET = + new TypeReference>() { + }; + + private static final TypeReference CLIENT_SETTINGS_TYPE_REFERENCE = + new TypeReference() { + }; + + private static final TypeReference TOKEN_SETTINGS_TYPE_REFERENCE = + new TypeReference() { + }; + + private static final TypeReference INSTANT_TYPE_REFERENCE = new TypeReference() { + }; + + /** + * {@inheritDoc} + */ + @Override + public RegisteredClient deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { + ObjectMapper mapper = (ObjectMapper) p.getCodec(); + JsonNode root = mapper.readTree(p); + return deserialize(root, mapper); + } + + private RegisteredClient deserialize(JsonNode root, ObjectMapper mapper) { + String id = JsonNodeUtils.findStringValue(root, "id"); + String clientId = JsonNodeUtils.findStringValue(root, "clientId"); + String clientSecret = JsonNodeUtils.findStringValue(root, "clientSecret"); + String clientName = JsonNodeUtils.findStringValue(root, "clientName"); + + Instant clientIdIssuedAt = JsonNodeUtils + .findValue(root, "clientIdIssuedAt", INSTANT_TYPE_REFERENCE, mapper); + + Instant clientSecretExpiresAt = JsonNodeUtils + .findValue(root, "clientSecretExpiresAtNode", INSTANT_TYPE_REFERENCE, mapper); + + Set grantTypes = JsonNodeUtils + .findValue(root, "authorizationGrantTypes", AUTHORIZATION_GRANT_TYPE_SET, mapper); + Set clientAuthenticationMethods = JsonNodeUtils + .findValue(root, "clientAuthenticationMethods", CLIENT_AUTHENTICATION_METHOD_SET, mapper); + Set redirectUris = JsonNodeUtils + .findValue(root, "redirectUris", JsonNodeUtils.STRING_SET, mapper); + Set scopes = JsonNodeUtils.findValue(root, "scopes", JsonNodeUtils.STRING_SET, mapper); + + ClientSettings clientSettings = JsonNodeUtils + .findValue(root, "clientSettings", CLIENT_SETTINGS_TYPE_REFERENCE, mapper); + TokenSettings tokenSettings = JsonNodeUtils + .findValue(root, "tokenSettings", TOKEN_SETTINGS_TYPE_REFERENCE, mapper); + + return RegisteredClient + .withId(id) + .clientId(clientId) + .clientIdIssuedAt(clientIdIssuedAt) + .clientSecret(clientSecret) + .clientSecretExpiresAt(clientSecretExpiresAt) + .clientName(clientName) + .clientAuthenticationMethods(consumer -> consumer.addAll(clientAuthenticationMethods)) + .authorizationGrantTypes(consumer -> consumer.addAll(grantTypes)) + .redirectUris(consumer -> consumer.addAll(redirectUris)) + .scopes(consumer -> consumer.addAll(scopes)) + .clientSettings(clientSettings) + .tokenSettings(tokenSettings) + .build(); + } + +} diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/RegisteredClientMixin.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/RegisteredClientMixin.java new file mode 100644 index 000000000..eef068da7 --- /dev/null +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/RegisteredClientMixin.java @@ -0,0 +1,17 @@ +package org.springframework.security.oauth2.server.authorization.jackson2; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * Jackson Mixin class helps in serialize/deserialize + * {@link org.springframework.security.oauth2.server.authorization.client.RegisteredClient}. + * + * @author Junlin Zhou + */ +@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS) +@JsonDeserialize(using = RegisteredClientDeserializer.class) +@JsonIgnoreProperties(ignoreUnknown = true) +abstract class RegisteredClientMixin { +} diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/TokenSettingsDeserializer.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/TokenSettingsDeserializer.java new file mode 100644 index 000000000..aa568d87e --- /dev/null +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/TokenSettingsDeserializer.java @@ -0,0 +1,32 @@ +package org.springframework.security.oauth2.server.authorization.jackson2; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.security.oauth2.server.authorization.config.TokenSettings; + +import java.io.IOException; +import java.util.Map; + +/** + * Deserializer used for deserializing {@link TokenSettings} from JSON. + * + * @author Junlin Zhou + */ +public class TokenSettingsDeserializer extends JsonDeserializer { + + /** + * {@inheritDoc} + */ + @Override + public TokenSettings deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { + ObjectMapper mapper = (ObjectMapper) p.getCodec(); + JsonNode root = mapper.readTree(p); + Map settings = JsonNodeUtils + .findValue(root, "settings", JsonNodeUtils.STRING_OBJECT_MAP, mapper); + return TokenSettings.withSettings(settings).build(); + } + +} diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/TokenSettingsMixin.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/TokenSettingsMixin.java new file mode 100644 index 000000000..13eb130cf --- /dev/null +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/jackson2/TokenSettingsMixin.java @@ -0,0 +1,17 @@ +package org.springframework.security.oauth2.server.authorization.jackson2; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * Jackson Mixin class helps in serialize/deserialize + * {@link org.springframework.security.oauth2.server.authorization.config.TokenSettings}. + * + * @author Junlin Zhou + */ +@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS) +@JsonDeserialize(using = TokenSettingsDeserializer.class) +@JsonIgnoreProperties(ignoreUnknown = true) +abstract class TokenSettingsMixin { +}