Ver Fonte

Update to Jackson 2.9.4

Fixes: gh-4985
Rob Winch há 7 anos atrás
pai
commit
8b7f772761

+ 1 - 1
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 = "{"

+ 1 - 0
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.<Object>unmodifiableSet(Collections.emptySet()).getClass(), UnmodifiableSetMixin.class);
+		context.setMixInAnnotations(Collections.<Object>unmodifiableList(Collections.emptyList()).getClass(), UnmodifiableListMixin.class);
 		context.setMixInAnnotations(User.class, UserMixin.class);
 		context.setMixInAnnotations(UsernamePasswordAuthenticationToken.class, UsernamePasswordAuthenticationTokenMixin.class);
 	}

+ 3 - 0
core/src/main/java/org/springframework/security/jackson2/SecurityJackson2Modules.java

@@ -142,7 +142,10 @@ public final class SecurityJackson2Modules {
 	static class WhitelistTypeIdResolver implements TypeIdResolver {
 		private static final Set<String> WHITELIST_CLASS_NAMES = Collections.unmodifiableSet(new HashSet(Arrays.asList(
 			"java.util.ArrayList",
+			"java.util.Collections$EmptyList",
 			"java.util.Collections$EmptyMap",
+			"java.util.Collections$UnmodifiableRandomAccessList",
+			"java.util.Collections$SingletonList",
 			"java.util.Date",
 			"java.util.TreeMap",
 			"java.util.HashMap",

+ 61 - 0
core/src/main/java/org/springframework/security/jackson2/UnmodifiableListDeserializer.java

@@ -0,0 +1,61 @@
+/*
+ * 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.Iterator;
+import java.util.List;
+
+/**
+ * Custom deserializer for {@link UnmodifiableListDeserializer}.
+ *
+ * @author Rob Winch
+ * @see UnmodifiableListMixin
+ * @since 5.0.2
+ */
+class UnmodifiableListDeserializer extends JsonDeserializer<List> {
+
+	@Override
+	public List deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
+		ObjectMapper mapper = (ObjectMapper) jp.getCodec();
+		JsonNode node = mapper.readTree(jp);
+		List<Object> result = new ArrayList<Object>();
+		if (node != null) {
+			if (node instanceof ArrayNode) {
+				ArrayNode arrayNode = (ArrayNode) node;
+				Iterator<JsonNode> 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);
+	}
+}

+ 50 - 0
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.
+ *
+ * <pre>
+ *     ObjectMapper mapper = new ObjectMapper();
+ *     mapper.registerModule(new CoreJackson2Module());
+ * </pre>
+ *
+ * @author Rob Winch
+ * @see UnmodifiableListDeserializer
+ * @see CoreJackson2Module
+ * @see SecurityJackson2Modules
+ * @since 5.0.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) {}
+}

+ 4 - 2
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.Collections$EmptyList\", []]";
 
 	public static final String NO_AUTHORITIES_SET_JSON = "[\"java.util.Collections$UnmodifiableSet\", []]";
 	// @formatter:on

+ 1 - 1
core/src/test/java/org/springframework/security/jackson2/UsernamePasswordAuthenticationTokenMixinTests.java

@@ -69,7 +69,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

+ 3 - 3
gradle/dependency-management.gradle

@@ -28,9 +28,9 @@ dependencyManagement {
 		dependency 'asm:asm:3.1'
 		dependency 'ch.qos.logback:logback-classic:1.2.3'
 		dependency 'ch.qos.logback:logback-core:1.2.3'
-		dependency 'com.fasterxml.jackson.core:jackson-annotations:2.9.0'
-		dependency 'com.fasterxml.jackson.core:jackson-core:2.9.2'
-		dependency 'com.fasterxml.jackson.core:jackson-databind:2.9.2'
+		dependency 'com.fasterxml.jackson.core:jackson-annotations:2.9.4'
+		dependency 'com.fasterxml.jackson.core:jackson-core:2.9.4'
+		dependency 'com.fasterxml.jackson.core:jackson-databind:2.9.4'
 		dependency 'com.fasterxml:classmate:1.3.4'
 		dependency 'com.github.stephenc.jcip:jcip-annotations:1.0-1'
 		dependency 'com.google.appengine:appengine-api-1.0-sdk:1.9.60'

+ 7 - 2
web/src/main/java/org/springframework/security/web/savedrequest/DefaultSavedRequest.java

@@ -503,8 +503,13 @@ public class DefaultSavedRequest implements SavedRequest {
 
 			this.headers.remove(HEADER_IF_MODIFIED_SINCE);
 			this.headers.remove(HEADER_IF_NONE_MATCH);
-			if (!ObjectUtils.isEmpty(this.headers))
-				savedRequest.headers.putAll(this.headers);
+			for (Map.Entry<String, List<String>> entry : this.headers.entrySet()) {
+				String headerName = entry.getKey();
+				List<String> headerValues = entry.getValue();
+				for (String headerValue : headerValues) {
+					savedRequest.addHeader(headerName, headerValue);
+				}
+			}
 			return savedRequest;
 		}
 	}