diff --git a/saml2/saml2-service-provider/src/opensaml3Test/java/org/springframework/security/saml2/provider/service/authentication/OpenSamlAuthenticationProviderTests.java b/saml2/saml2-service-provider/src/opensaml3Test/java/org/springframework/security/saml2/provider/service/authentication/OpenSamlAuthenticationProviderTests.java index 95f0cfe580..79f2071e98 100644 --- a/saml2/saml2-service-provider/src/opensaml3Test/java/org/springframework/security/saml2/provider/service/authentication/OpenSamlAuthenticationProviderTests.java +++ b/saml2/saml2-service-provider/src/opensaml3Test/java/org/springframework/security/saml2/provider/service/authentication/OpenSamlAuthenticationProviderTests.java @@ -244,6 +244,7 @@ public class OpenSamlAuthenticationProviderTests { expected.put("age", Collections.singletonList(21)); expected.put("website", Collections.singletonList("https://johndoe.com/")); expected.put("registered", Collections.singletonList(true)); + expected.put("role", Arrays.asList("RoleTwo")); Instant registeredDate = Instant.ofEpochMilli(DateTime.parse("1970-01-01T00:00:00Z").getMillis()); expected.put("registeredDate", Collections.singletonList(registeredDate)); assertThat((String) principal.getFirstAttribute("name")).isEqualTo("John Doe"); 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 31acccfa74..d4ac38f684 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,7 +23,6 @@ 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; @@ -92,6 +91,8 @@ import org.springframework.security.saml2.provider.service.registration.RelyingP import org.springframework.security.saml2.provider.service.registration.Saml2MessageBinding; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; import org.springframework.util.StringUtils; /** @@ -645,7 +646,7 @@ public final class OpenSaml4AuthenticationProvider implements AuthenticationProv } private static Map> getAssertionAttributes(Assertion assertion) { - Map> attributeMap = new LinkedHashMap<>(); + MultiValueMap attributeMap = new LinkedMultiValueMap<>(); for (AttributeStatement attributeStatement : assertion.getAttributeStatements()) { for (Attribute attribute : attributeStatement.getAttributes()) { List attributeValues = new ArrayList<>(); @@ -655,7 +656,7 @@ public final class OpenSaml4AuthenticationProvider implements AuthenticationProv attributeValues.add(attributeValue); } } - attributeMap.put(attribute.getName(), attributeValues); + attributeMap.addAll(attribute.getName(), attributeValues); } } return attributeMap; 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 6a7eb1ff0c..670c01a8e9 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 @@ -343,6 +343,7 @@ public class OpenSaml4AuthenticationProviderTests { expected.put("registered", Collections.singletonList(true)); Instant registeredDate = Instant.parse("1970-01-01T00:00:00Z"); expected.put("registeredDate", Collections.singletonList(registeredDate)); + expected.put("role", Arrays.asList("RoleOne", "RoleTwo")); // gh-11042 assertThat((String) principal.getFirstAttribute("name")).isEqualTo("John Doe"); assertThat(principal.getAttributes()).isEqualTo(expected); assertThat(principal.getSessionIndexes()).contains("session-index"); diff --git a/saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/authentication/TestOpenSamlObjects.java b/saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/authentication/TestOpenSamlObjects.java index e0edad7136..1727d3e4bc 100644 --- a/saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/authentication/TestOpenSamlObjects.java +++ b/saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/authentication/TestOpenSamlObjects.java @@ -327,6 +327,18 @@ public final class TestOpenSamlObjects { name.setValue("John Doe"); nameAttr.getAttributeValues().add(name); attrStmt1.getAttributes().add(nameAttr); + Attribute roleOneAttr = attributeBuilder.buildObject(); // gh-11042 + roleOneAttr.setName("role"); + XSString roleOne = new XSStringBuilder().buildObject(AttributeValue.DEFAULT_ELEMENT_NAME, XSString.TYPE_NAME); + roleOne.setValue("RoleOne"); + roleOneAttr.getAttributeValues().add(roleOne); + attrStmt1.getAttributes().add(roleOneAttr); + Attribute roleTwoAttr = attributeBuilder.buildObject(); // gh-11042 + roleTwoAttr.setName("role"); + XSString roleTwo = new XSStringBuilder().buildObject(AttributeValue.DEFAULT_ELEMENT_NAME, XSString.TYPE_NAME); + roleTwo.setValue("RoleTwo"); + roleTwoAttr.getAttributeValues().add(roleTwo); + attrStmt1.getAttributes().add(roleTwoAttr); Attribute ageAttr = attributeBuilder.buildObject(); ageAttr.setName("age"); XSInteger age = new XSIntegerBuilder().buildObject(AttributeValue.DEFAULT_ELEMENT_NAME, XSInteger.TYPE_NAME);