From 3cfaf0d11da97f92560e5aa2be32b6ccbf82f9ef Mon Sep 17 00:00:00 2001 From: Josh Cummings Date: Fri, 23 Dec 2022 15:54:00 -0700 Subject: [PATCH] Avoid LinkedMultiValueMap in Serializable Object Closes gh-11785 --- .../OpenSaml4AuthenticationProvider.java | 3 ++- .../OpenSaml4AuthenticationProviderTests.java | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/saml2/saml2-service-provider/src/opensaml4Main/java/org/springframework/security/saml2/provider/service/authentication/OpenSaml4AuthenticationProvider.java b/saml2/saml2-service-provider/src/opensaml4Main/java/org/springframework/security/saml2/provider/service/authentication/OpenSaml4AuthenticationProvider.java index d4ac38f684..92ece427ce 100644 --- a/saml2/saml2-service-provider/src/opensaml4Main/java/org/springframework/security/saml2/provider/service/authentication/OpenSaml4AuthenticationProvider.java +++ b/saml2/saml2-service-provider/src/opensaml4Main/java/org/springframework/security/saml2/provider/service/authentication/OpenSaml4AuthenticationProvider.java @@ -23,6 +23,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.function.Consumer; @@ -659,7 +660,7 @@ public final class OpenSaml4AuthenticationProvider implements AuthenticationProv attributeMap.addAll(attribute.getName(), attributeValues); } } - return attributeMap; + return new LinkedHashMap<>(attributeMap); // gh-11785 } private static List getSessionIndexes(Assertion assertion) { diff --git a/saml2/saml2-service-provider/src/opensaml4Test/java/org/springframework/security/saml2/provider/service/authentication/OpenSaml4AuthenticationProviderTests.java b/saml2/saml2-service-provider/src/opensaml4Test/java/org/springframework/security/saml2/provider/service/authentication/OpenSaml4AuthenticationProviderTests.java index 670c01a8e9..796558e635 100644 --- a/saml2/saml2-service-provider/src/opensaml4Test/java/org/springframework/security/saml2/provider/service/authentication/OpenSaml4AuthenticationProviderTests.java +++ b/saml2/saml2-service-provider/src/opensaml4Test/java/org/springframework/security/saml2/provider/service/authentication/OpenSaml4AuthenticationProviderTests.java @@ -32,6 +32,7 @@ import java.util.function.Consumer; import javax.xml.namespace.QName; +import com.fasterxml.jackson.databind.ObjectMapper; import net.shibboleth.utilities.java.support.xml.SerializeSupport; import org.junit.jupiter.api.Test; import org.opensaml.core.xml.XMLObject; @@ -68,6 +69,7 @@ import org.w3c.dom.Element; import org.springframework.core.convert.converter.Converter; import org.springframework.security.core.Authentication; +import org.springframework.security.jackson2.SecurityJackson2Modules; import org.springframework.security.saml2.Saml2Exception; import org.springframework.security.saml2.core.Saml2Error; import org.springframework.security.saml2.core.Saml2ErrorCodes; @@ -349,6 +351,23 @@ public class OpenSaml4AuthenticationProviderTests { assertThat(principal.getSessionIndexes()).contains("session-index"); } + // gh-11785 + @Test + public void deserializeWhenAssertionContainsAttributesThenWorks() throws Exception { + ObjectMapper mapper = new ObjectMapper(); + ClassLoader loader = getClass().getClassLoader(); + mapper.registerModules(SecurityJackson2Modules.getModules(loader)); + Response response = response(); + Assertion assertion = assertion(); + List attributes = TestOpenSamlObjects.attributeStatements(); + assertion.getAttributeStatements().addAll(attributes); + response.getAssertions().add(signed(assertion)); + Saml2AuthenticationToken token = token(response, verifying(registration())); + Authentication authentication = this.provider.authenticate(token); + String result = mapper.writeValueAsString(authentication); + mapper.readValue(result, Authentication.class); + } + @Test public void authenticateWhenAssertionContainsCustomAttributesThenItSucceeds() { Response response = response();