From 5dedbb628360242c55aae087fc2dc05af87bcf9c Mon Sep 17 00:00:00 2001 From: Rob Winch Date: Tue, 30 Jan 2018 11:16:02 -0600 Subject: [PATCH] Update to jackson-databind-2.8.11.1 Fixes: gh-5101 --- .../CasAuthenticationTokenMixinTests.java | 6 +- .../security/jackson2/CoreJackson2Module.java | 1 + .../jackson2/SecurityJackson2Modules.java | 1 + .../UnmodifiableListDeserializer.java | 63 +++++++++++++++++++ .../jackson2/UnmodifiableListMixin.java | 50 +++++++++++++++ .../SimpleGrantedAuthorityMixinTests.java | 6 +- ...PasswordAuthenticationTokenMixinTests.java | 2 +- gradle/javaprojects.gradle | 2 +- 8 files changed, 124 insertions(+), 7 deletions(-) create mode 100644 core/src/main/java/org/springframework/security/jackson2/UnmodifiableListDeserializer.java create mode 100644 core/src/main/java/org/springframework/security/jackson2/UnmodifiableListMixin.java diff --git a/cas/src/test/java/org/springframework/security/cas/jackson2/CasAuthenticationTokenMixinTests.java b/cas/src/test/java/org/springframework/security/cas/jackson2/CasAuthenticationTokenMixinTests.java index 665e1a8a7e..f6ce57bb2b 100644 --- a/cas/src/test/java/org/springframework/security/cas/jackson2/CasAuthenticationTokenMixinTests.java +++ b/cas/src/test/java/org/springframework/security/cas/jackson2/CasAuthenticationTokenMixinTests.java @@ -55,7 +55,7 @@ public class CasAuthenticationTokenMixinTests { public static final String AUTHORITIES_SET_JSON = "[\"java.util.Collections$UnmodifiableSet\", [" + AUTHORITY_JSON + "]]"; - public static final String AUTHORITIES_ARRAYLIST_JSON = "[\"java.util.ArrayList\", [" + AUTHORITY_JSON + "]]"; + public static final String AUTHORITIES_ARRAYLIST_JSON = "[\"java.util.Collections$UnmodifiableRandomAccessList\", [" + AUTHORITY_JSON + "]]"; // @formatter:off public static final String USER_JSON = "{" @@ -84,14 +84,14 @@ public class CasAuthenticationTokenMixinTests { + "\"principal\": {" + "\"@class\": \"org.jasig.cas.client.authentication.AttributePrincipalImpl\", " + "\"name\": \"assertName\", " - + "\"attributes\": {\"@class\": \"java.util.Collections$EmptyMap\"}, " + + "\"attributes\": {\"@class\": \"java.util.HashMap\"}, " + "\"proxyGrantingTicket\": null, " + "\"proxyRetriever\": null" + "}, " + "\"validFromDate\": [\"java.util.Date\", " + START_DATE.getTime() + "], " + "\"validUntilDate\": [\"java.util.Date\", " + END_DATE.getTime() + "]," + "\"authenticationDate\": [\"java.util.Date\", " + START_DATE.getTime() + "], " - + "\"attributes\": {\"@class\": \"java.util.Collections$EmptyMap\"}" + + + "\"attributes\": {\"@class\": \"java.util.HashMap\"}" + "}" + "}"; diff --git a/core/src/main/java/org/springframework/security/jackson2/CoreJackson2Module.java b/core/src/main/java/org/springframework/security/jackson2/CoreJackson2Module.java index b21de20bfa..4dda441791 100644 --- a/core/src/main/java/org/springframework/security/jackson2/CoreJackson2Module.java +++ b/core/src/main/java/org/springframework/security/jackson2/CoreJackson2Module.java @@ -58,6 +58,7 @@ public class CoreJackson2Module extends SimpleModule { context.setMixInAnnotations(RememberMeAuthenticationToken.class, RememberMeAuthenticationTokenMixin.class); context.setMixInAnnotations(SimpleGrantedAuthority.class, SimpleGrantedAuthorityMixin.class); context.setMixInAnnotations(Collections.unmodifiableSet(Collections.emptySet()).getClass(), UnmodifiableSetMixin.class); + context.setMixInAnnotations(Collections.unmodifiableList(Collections.emptyList()).getClass(), UnmodifiableListMixin.class); context.setMixInAnnotations(User.class, UserMixin.class); context.setMixInAnnotations(UsernamePasswordAuthenticationToken.class, UsernamePasswordAuthenticationTokenMixin.class); } diff --git a/core/src/main/java/org/springframework/security/jackson2/SecurityJackson2Modules.java b/core/src/main/java/org/springframework/security/jackson2/SecurityJackson2Modules.java index 2d935b4101..9a3c37f4d5 100644 --- a/core/src/main/java/org/springframework/security/jackson2/SecurityJackson2Modules.java +++ b/core/src/main/java/org/springframework/security/jackson2/SecurityJackson2Modules.java @@ -143,6 +143,7 @@ public final class SecurityJackson2Modules { private static final Set WHITELIST_CLASS_NAMES = Collections.unmodifiableSet(new HashSet(Arrays.asList( "java.util.ArrayList", "java.util.Collections$EmptyMap", + "java.util.Collections$UnmodifiableRandomAccessList", "java.util.Date", "java.util.TreeMap", "java.util.HashMap", diff --git a/core/src/main/java/org/springframework/security/jackson2/UnmodifiableListDeserializer.java b/core/src/main/java/org/springframework/security/jackson2/UnmodifiableListDeserializer.java new file mode 100644 index 0000000000..3ec489e03c --- /dev/null +++ b/core/src/main/java/org/springframework/security/jackson2/UnmodifiableListDeserializer.java @@ -0,0 +1,63 @@ +/* + * Copyright 2002-2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.security.jackson2; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +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.node.ArrayNode; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +/** + * Custom deserializer for {@link UnmodifiableListMixin}. + * + * @author Rob Winch + * @see UnmodifiableSetMixin + * @since 4.2 + */ +class UnmodifiableListDeserializer extends JsonDeserializer { + + @Override + public List deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { + ObjectMapper mapper = (ObjectMapper) jp.getCodec(); + JsonNode node = mapper.readTree(jp); + List result = new ArrayList(); + if (node != null) { + if (node instanceof ArrayNode) { + ArrayNode arrayNode = (ArrayNode) node; + Iterator nodeIterator = arrayNode.iterator(); + while (nodeIterator.hasNext()) { + JsonNode elementNode = nodeIterator.next(); + result.add(mapper.readValue(elementNode.traverse(mapper), Object.class)); + } + } else { + result.add(mapper.readValue(node.traverse(mapper), Object.class)); + } + } + return Collections.unmodifiableList(result); + } +} diff --git a/core/src/main/java/org/springframework/security/jackson2/UnmodifiableListMixin.java b/core/src/main/java/org/springframework/security/jackson2/UnmodifiableListMixin.java new file mode 100644 index 0000000000..99ed128446 --- /dev/null +++ b/core/src/main/java/org/springframework/security/jackson2/UnmodifiableListMixin.java @@ -0,0 +1,50 @@ +/* + * Copyright 2002-2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.security.jackson2; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +import java.util.Set; + +/** + * This mixin class used to deserialize java.util.Collections$UnmodifiableRandomAccessList + * and used with various AuthenticationToken implementation's mixin classes. + * + *
+ *     ObjectMapper mapper = new ObjectMapper();
+ *     mapper.registerModule(new CoreJackson2Module());
+ * 
+ * + * @author Rob Winch + * @see UnmodifiableListDeserializer + * @see CoreJackson2Module + * @see SecurityJackson2Modules + * @since 4.2 + */ +@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY) +@JsonDeserialize(using = UnmodifiableListDeserializer.class) +class UnmodifiableListMixin { + + /** + * Mixin Constructor + * @param s the Set + */ + @JsonCreator + UnmodifiableListMixin(Set s) {} +} diff --git a/core/src/test/java/org/springframework/security/jackson2/SimpleGrantedAuthorityMixinTests.java b/core/src/test/java/org/springframework/security/jackson2/SimpleGrantedAuthorityMixinTests.java index a5e11f2e9b..c22f287c3b 100644 --- a/core/src/test/java/org/springframework/security/jackson2/SimpleGrantedAuthorityMixinTests.java +++ b/core/src/test/java/org/springframework/security/jackson2/SimpleGrantedAuthorityMixinTests.java @@ -36,11 +36,13 @@ public class SimpleGrantedAuthorityMixinTests extends AbstractMixinTests { // @formatter:off public static final String AUTHORITY_JSON = "{\"@class\": \"org.springframework.security.core.authority.SimpleGrantedAuthority\", \"authority\": \"ROLE_USER\"}"; - public static final String AUTHORITIES_ARRAYLIST_JSON = "[\"java.util.ArrayList\", [" + AUTHORITY_JSON + "]]"; + public static final String AUTHORITIES_ARRAYLIST_JSON = "[\"java.util.Collections$UnmodifiableRandomAccessList\", [" + AUTHORITY_JSON + "]]"; public static final String AUTHORITIES_SET_JSON = "[\"java.util.Collections$UnmodifiableSet\", [" + AUTHORITY_JSON + "]]"; - public static final String NO_AUTHORITIES_ARRAYLIST_JSON = "[\"java.util.ArrayList\", []]"; + public static final String NO_AUTHORITIES_ARRAYLIST_JSON = "[\"java.util.Collections$UnmodifiableRandomAccessList\", []]"; + + public static final String EMPTY_AUTHORITIES_ARRAYLIST_JSON = "[\"java.util.ArrayList\", []]"; public static final String NO_AUTHORITIES_SET_JSON = "[\"java.util.Collections$UnmodifiableSet\", []]"; // @formatter:on diff --git a/core/src/test/java/org/springframework/security/jackson2/UsernamePasswordAuthenticationTokenMixinTests.java b/core/src/test/java/org/springframework/security/jackson2/UsernamePasswordAuthenticationTokenMixinTests.java index de0cba9918..f58f0eb656 100644 --- a/core/src/test/java/org/springframework/security/jackson2/UsernamePasswordAuthenticationTokenMixinTests.java +++ b/core/src/test/java/org/springframework/security/jackson2/UsernamePasswordAuthenticationTokenMixinTests.java @@ -70,7 +70,7 @@ public class UsernamePasswordAuthenticationTokenMixinTests extends AbstractMixin // @formatter:off private static final String UNAUTHENTICATED_STRINGPRINCIPAL_JSON = AUTHENTICATED_STRINGPRINCIPAL_JSON .replace("\"authenticated\": true, ", "\"authenticated\": false, ") - .replace(SimpleGrantedAuthorityMixinTests.AUTHORITIES_ARRAYLIST_JSON, SimpleGrantedAuthorityMixinTests.NO_AUTHORITIES_ARRAYLIST_JSON); + .replace(SimpleGrantedAuthorityMixinTests.AUTHORITIES_ARRAYLIST_JSON, SimpleGrantedAuthorityMixinTests.EMPTY_AUTHORITIES_ARRAYLIST_JSON); // @formatter:on @Test diff --git a/gradle/javaprojects.gradle b/gradle/javaprojects.gradle index b0a220705b..8a842297c7 100644 --- a/gradle/javaprojects.gradle +++ b/gradle/javaprojects.gradle @@ -21,7 +21,7 @@ ext.groovyVersion = '2.4.4' ext.hsqlVersion = '2.3.2' ext.hibernateVersion = '5.0.12.Final' ext.hibernateValidatorVersion = '5.3.6.Final' -ext.jacksonDatabindVersion = '2.8.10' +ext.jacksonDatabindVersion = '2.8.11.1' ext.javaPersistenceVersion = '2.1.1' ext.jettyVersion = '6.1.26' ext.jstlVersion = '1.2.1'