[java-oidc-common] branch main updated: JCOMOIDC-127 - Transcoding of object type of claim fails
Phil Smart
philip.smart at jisc.ac.uk
Thu Apr 17 10:54:51 UTC 2025
This is an automated email from the git hooks/post-receive script.
philsmart pushed a commit to branch main
in repository java-oidc-common.
View the commit online:
http://git.shibboleth.net/view/?p=java-oidc-common.git;a=commit;h=126b9eafb60e05d09c0583434dc6f390a10fcf15
The following commit(s) were added to refs/heads/main by this push:
new 126b9ea JCOMOIDC-127 - Transcoding of object type of claim fails
126b9ea is described below
commit 126b9eafb60e05d09c0583434dc6f390a10fcf15
Author: Phil Smart <philip.smart at jisc.ac.uk>
AuthorDate: Thu Apr 17 11:54:49 2025 +0100
JCOMOIDC-127 - Transcoding of object type of claim fails
- Added a conditional statement to the decode method that serialises
any Map type into a JSON string.
https://shibboleth.atlassian.net/browse/JCOMOIDC-127
---
.../impl/OIDCStringAttributeTranscoder.java | 25 ++++++++++----
.../impl/OIDCStringAttributeTranscoderTest.java | 39 ++++++++++++++++++++++
2 files changed, 58 insertions(+), 6 deletions(-)
diff --git a/oidc-common-attribute-impl/src/main/java/net/shibboleth/oidc/attribute/transcoding/impl/OIDCStringAttributeTranscoder.java b/oidc-common-attribute-impl/src/main/java/net/shibboleth/oidc/attribute/transcoding/impl/OIDCStringAttributeTranscoder.java
index 268cc8a..8e0e829 100644
--- a/oidc-common-attribute-impl/src/main/java/net/shibboleth/oidc/attribute/transcoding/impl/OIDCStringAttributeTranscoder.java
+++ b/oidc-common-attribute-impl/src/main/java/net/shibboleth/oidc/attribute/transcoding/impl/OIDCStringAttributeTranscoder.java
@@ -15,7 +15,9 @@
package net.shibboleth.oidc.attribute.transcoding.impl;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -68,8 +70,8 @@ import net.shibboleth.shared.primitive.LoggerFactory;
* <li>If a JSON Array and PROP_ARRAY_AS_STRING is false, attempt to recursively convert elements of the array
* to string attribute values using the same set of rules. If any element fails to convert it will be excluded
* from the result.</li>
- * <li>If a JSON Object and PROP_ASOBJECT is true, convert the object to a string by serializing into JSON. Else,
- * return an empty values list.</li>
+ * <li>If a JSON Object or a generic Map and PROP_ASOBJECT is true, convert the object to a string by serializing into
+ * JSON. Else, return an empty values list.</li>
* <li>For any other unknown type, return an empty values list.</li>
* </ul>
*/
@@ -175,8 +177,7 @@ public class OIDCStringAttributeTranscoder extends AbstractOIDCAttributeTranscod
// Input could be any JSON data type e.g. String, Number, JSONObject, Array, Boolean.
if (input instanceof String) {
- return CollectionSupport.listOf(StringAttributeValue.valueOf((String)input));
-
+ return CollectionSupport.listOf(StringAttributeValue.valueOf((String)input));
}
final Boolean numAsString = rule.getOrDefault(PROP_NUMBER_AS_STRING, Boolean.class, false);
@@ -211,12 +212,24 @@ public class OIDCStringAttributeTranscoder extends AbstractOIDCAttributeTranscod
return arrayValuesDecoded;
}
- } else if (input instanceof JSONObject && asObject) {
+ } if (input instanceof JSONObject && asObject) {
// Serialize JSONObject to a JSON string.
return CollectionSupport.listOf(StringAttributeValue.valueOf(((JSONObject)input).toJSONString()));
+ } else if (input instanceof final Map<?,?> mapInput && asObject) {
+ final Map<String, Object> mapWithStringKeys = new HashMap<>();
+
+ // Only convert values which have String keys.
+ for (final Map.Entry<?, ?> entry : mapInput.entrySet()) {
+ if (entry.getKey() instanceof String) {
+ mapWithStringKeys.put((String) entry.getKey(), entry.getValue());
+ }
+ }
+
+ return CollectionSupport.listOf(StringAttributeValue.valueOf(
+ new JSONObject(mapWithStringKeys).toJSONString()));
} else {
- log.trace("Could not convert values of type {} for the claim '{}' to a string attribute using "
+ log.warn("Could not convert values of type {} for the claim '{}' to a string attribute using "
+ "transcoding rule '{} -> {}'",
input.getClass().getName(), input, rule.getOrDefault(PROP_NAME, String.class, "unknown"),
rule.getOrDefault(AttributeTranscoderRegistry.PROP_ID, String.class, "unknown"));
diff --git a/oidc-common-attribute-impl/src/test/java/net/shibboleth/oidc/attribute/transcoding/impl/OIDCStringAttributeTranscoderTest.java b/oidc-common-attribute-impl/src/test/java/net/shibboleth/oidc/attribute/transcoding/impl/OIDCStringAttributeTranscoderTest.java
index f7ccb07..6049e12 100644
--- a/oidc-common-attribute-impl/src/test/java/net/shibboleth/oidc/attribute/transcoding/impl/OIDCStringAttributeTranscoderTest.java
+++ b/oidc-common-attribute-impl/src/test/java/net/shibboleth/oidc/attribute/transcoding/impl/OIDCStringAttributeTranscoderTest.java
@@ -25,6 +25,7 @@ import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
+import com.nimbusds.jose.shaded.gson.internal.LinkedTreeMap;
import com.nimbusds.openid.connect.sdk.claims.ClaimsSetRequest;
import net.minidev.json.JSONArray;
@@ -690,6 +691,44 @@ public class OIDCStringAttributeTranscoderTest {
.getNativeValue(), "{\"name\":\"John\",\"age\":\"30\"}");
}
+ /* Nimbus delivers some claims as LinkedTreeMap, See https://shibboleth.atlassian.net/browse/JCOMOIDC-127 */
+ @Test
+ public void testDecodingLinkedTreeMap() throws ComponentInitializationException, AttributeDecodingException {
+
+ ruleset.put(OIDCStringAttributeTranscoder.PROP_ASOBJECT, true);
+
+ registry.setTranscoderRegistry(CollectionSupport.singletonList(new TranscodingRule(ruleset)));
+ registry.setApplicationContext(new MockApplicationContext());
+ registry.initialize();
+
+ final JSONObject inputAttribute = new JSONObject();
+
+ final LinkedTreeMap<String, String> linkedTree = new LinkedTreeMap<>();
+
+ linkedTree.put("address", "234 Hollywood Blvd.");
+ linkedTree.put("country", "US");
+ linkedTree.put("locality", "Los Angeles");
+ linkedTree.put("CA", "90210");
+
+ inputAttribute.put("bar", linkedTree);
+
+ final Collection<TranscodingRule> rulesets = registry.getTranscodingRules(inputAttribute);
+ Assert.assertEquals(rulesets.size(), 1);
+ final TranscodingRule tr = rulesets.iterator().next();
+ assert tr != null;
+
+ final IdPAttribute decodedAttribute = TranscoderSupport.<JSONObject>getTranscoder(tr)
+ .decode(null, inputAttribute, tr);
+
+ assert decodedAttribute != null;
+ Assert.assertEquals(decodedAttribute.getId(), ATTR_ID);
+ Assert.assertEquals(decodedAttribute.getValues().size(), 1);
+ Assert.assertNotNull(decodedAttribute.getValues().get(0).getNativeValue());
+ Assert.assertEquals(decodedAttribute.getValues().get(0)
+ .getNativeValue(), "{\"locality\":\"Los Angeles\",\"country\":\"US\",\"address\":"
+ + "\"234 Hollywood Blvd.\",\"CA\":\"90210\"}");
+ }
+
@Test
public void testDecodingJSONObjectDisabledByRule() throws ComponentInitializationException, AttributeDecodingException {
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list