[java-identity-provider] branch main updated: IDP-2424 - Accessing user attributes from within authnContextTranslationStrategyEx

Codeberg noreply at shibboleth.net
Wed Jul 15 17:22:41 UTC 2026


This is an automated email from the git hooks/post-receive script.

codeberg pushed a commit to branch main
in repository java-identity-provider.

View the commit online:
https://codeberg.org/Shibboleth/java-identity-provider/commit/2d48159b4892a7a1a8fb16979b9a7efe7273249d

The following commit(s) were added to refs/heads/main by this push:
     new 2d48159b4 IDP-2424 - Accessing user attributes from within authnContextTranslationStrategyEx
2d48159b4 is described below

commit 2d48159b4892a7a1a8fb16979b9a7efe7273249d
Author: Scott Cantor <scott at restingparrotsoftware.com>
AuthorDate: Wed Jul 15 13:22:31 2026 -0400

    IDP-2424 - Accessing user attributes from within
    authnContextTranslationStrategyEx
    
    https://shibboleth.atlassian.net/browse/IDP-2424
    
    Add yet another setter that handles multiple outputs.
---
 ...buteSourcedAuthnContextTranslationStrategy.java | 54 ++++++++++++++++++----
 1 file changed, 45 insertions(+), 9 deletions(-)

diff --git a/idp-saml-api/src/main/java/net/shibboleth/idp/saml/saml2/profile/config/AttributeSourcedAuthnContextTranslationStrategy.java b/idp-saml-api/src/main/java/net/shibboleth/idp/saml/saml2/profile/config/AttributeSourcedAuthnContextTranslationStrategy.java
index d043eace3..f3c08094f 100644
--- a/idp-saml-api/src/main/java/net/shibboleth/idp/saml/saml2/profile/config/AttributeSourcedAuthnContextTranslationStrategy.java
+++ b/idp-saml-api/src/main/java/net/shibboleth/idp/saml/saml2/profile/config/AttributeSourcedAuthnContextTranslationStrategy.java
@@ -62,7 +62,7 @@ public class AttributeSourcedAuthnContextTranslationStrategy extends AbstractIni
     @Nonnull private Set<String> attributeSourceIDs;
     
     /** Translation map to convert values if necessary. */
-    @Nonnull private Map<String,Principal> valueMappings;
+    @Nonnull private Map<String,Collection<Principal>> valueMappings;
     
     /** Constructor. */
     public AttributeSourcedAuthnContextTranslationStrategy() {
@@ -104,7 +104,7 @@ public class AttributeSourcedAuthnContextTranslationStrategy extends AbstractIni
      * of a value caising it to be skipped. Also, keys are not trimmed, but values are, to ensure
      * the result is a valid context class reference.</p>
      *
-     *<p>This is deprecated in favor of the type-neutral variant.</p>
+     *<p>This is deprecated in favor of the type-neutral variants.</p>
      * 
      * @param mappings the value mappings
      * 
@@ -121,7 +121,8 @@ public class AttributeSourcedAuthnContextTranslationStrategy extends AbstractIni
                 if (entry.getKey() != null) {
                     final String trimmed = StringSupport.trimOrNull(entry.getValue());
                     valueMappings.put(entry.getKey(),
-                            trimmed != null ? new AuthnContextClassRefPrincipal(trimmed) : null);
+                            trimmed != null
+                                ? CollectionSupport.singletonList(new AuthnContextClassRefPrincipal(trimmed)) : null);
                 }
             }
         } else {
@@ -138,6 +139,8 @@ public class AttributeSourcedAuthnContextTranslationStrategy extends AbstractIni
      * the result is a valid context class reference.</p>
      * 
      * @param mappings the value mappings
+     * 
+     * @since 5.2.0
      */
     public void setMappings(@Nullable final Map<String,Principal> mappings) {
         checkSetterPreconditions();
@@ -147,7 +150,39 @@ public class AttributeSourcedAuthnContextTranslationStrategy extends AbstractIni
             // Needs to allow for null values.
             for (final Map.Entry<String,Principal> entry : mappings.entrySet()) {
                 if (entry.getKey() != null) {
-                    valueMappings.put(entry.getKey(), entry.getValue());
+                    valueMappings.put(entry.getKey(), CollectionSupport.singletonList(entry.getValue()));
+                }
+            }
+        } else {
+            valueMappings = CollectionSupport.emptyMap();
+        }
+    }
+    
+    /**
+     * Sets the mappings to transform {@link StringAttributeValue} data into different values for use as
+     * {@link Principal} objects.
+     * 
+     * <p>Note that null keys are ignored, but null values are allowed, which suppresses the mapping
+     * of a value caising it to be skipped. Also, keys are not trimmed, but values are, to ensure
+     * the result is a valid context class reference.</p>
+     * 
+     * @param mappings the value mappings
+     * 
+     * @since 5.3.0
+     */
+    public void setMappingsEx(@Nullable final Map<String,Collection<Principal>> mappings) {
+        checkSetterPreconditions();
+        
+        if (mappings != null) {
+            valueMappings = new HashMap<>();
+            // Needs to allow for null values.
+            for (final Map.Entry<String,Collection<Principal>> entry : mappings.entrySet()) {
+                if (entry.getKey() != null) {
+                    if (entry.getValue() != null) {
+                        valueMappings.put(entry.getKey(), CollectionSupport.copyToList(entry.getValue()));
+                    } else {
+                        valueMappings.put(entry.getKey(), null);
+                    }
                 }
             }
         } else {
@@ -155,6 +190,7 @@ public class AttributeSourcedAuthnContextTranslationStrategy extends AbstractIni
         }
     }
     
+    
     /** {@inheritDoc} */
     @Nullable public Collection<Principal> apply(@Nullable final ProfileRequestContext input) {
         checkComponentActive();
@@ -186,18 +222,18 @@ public class AttributeSourcedAuthnContextTranslationStrategy extends AbstractIni
             .map(StringAttributeValue::getValue)
             .forEach(v -> {
                 if (valueMappings.containsKey(v)) {
-                    final Principal mapped = valueMappings.get(v);
+                    final Collection<Principal> mapped = valueMappings.get(v);
                     if (mapped != null) {
-                        log.debug("Attrbute value for {} mapped to Principal {}", source.getId(), mapped);
-                        results.add(mapped);
+                        log.debug("Attrbute value for {} mapped to Principals {}", source.getId(), mapped);
+                        results.addAll(mapped);
                     } else {
                         log.debug("Skipping suppressed attribute value for {}", source.getId());
                     }
                 } else {
                     final String trimmed = StringSupport.trimOrNull(v);
                     if (trimmed != null) {
-                        log.debug("Attrbute value for {} passed through as SAML AuthnContextClassRef {}", source.getId(),
-                                trimmed);
+                        log.debug("Attrbute value for {} passed through as SAML AuthnContextClassRef {}",
+                                source.getId(), trimmed);
                         results.add(new AuthnContextClassRefPrincipal(trimmed));
                     }
                 }

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list