[java-identity-provider] branch main updated: IDP-2330 - Hook for populating group ID in attribute resolution context

Scott Cantor cantor.2 at osu.edu
Mon Feb 17 20:41:30 UTC 2025


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

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

View the commit online:
http://git.shibboleth.net/view/?p=java-identity-provider.git;a=commit;h=0eabeeab58b9d7f09a4a0d8914835370cffa6f6d

The following commit(s) were added to refs/heads/main by this push:
     new 0eabeeab5 IDP-2330 - Hook for populating group ID in attribute resolution context
0eabeeab5 is described below

commit 0eabeeab58b9d7f09a4a0d8914835370cffa6f6d
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Mon Feb 17 15:41:26 2025 -0500

    IDP-2330 - Hook for populating group ID in attribute resolution context
    
    https://shibboleth.atlassian.net/browse/IDP-2330
    
    Added setting to attribute resolving profile configs.
---
 .../admin/BasicAdministrativeFlowDescriptor.java   | 38 +++++++++++++++++--
 .../cas/config/AbstractProtocolConfiguration.java  | 34 +++++++++++++++++
 .../shibboleth/idp/conf/relying-party-mddriven.xml | 17 ++++++++-
 .../idp/profile/impl/FilterAttributes.java         |  7 ++++
 .../idp/profile/impl/ResolveAttributes.java        |  7 ++++
 .../impl/AttributeQueryProfileConfiguration.java   | 44 ++++++++++++++++++++++
 .../impl/BrowserSSOProfileConfiguration.java       | 33 ++++++++++++++++
 .../impl/AttributeQueryProfileConfiguration.java   | 42 ++++++++++++++++++++-
 .../impl/BrowserSSOProfileConfiguration.java       | 33 ++++++++++++++++
 9 files changed, 250 insertions(+), 5 deletions(-)

diff --git a/idp-admin-api/src/main/java/net/shibboleth/idp/admin/BasicAdministrativeFlowDescriptor.java b/idp-admin-api/src/main/java/net/shibboleth/idp/admin/BasicAdministrativeFlowDescriptor.java
index ad4e4fc73..401e5ffba 100644
--- a/idp-admin-api/src/main/java/net/shibboleth/idp/admin/BasicAdministrativeFlowDescriptor.java
+++ b/idp-admin-api/src/main/java/net/shibboleth/idp/admin/BasicAdministrativeFlowDescriptor.java
@@ -89,6 +89,9 @@ public class BasicAdministrativeFlowDescriptor extends AbstractInterceptorAwareP
     /** Whether attributes should be resolved in the course of the flow. */
     @Nonnull private Predicate<ProfileRequestContext> resolveAttributesPredicate;
     
+    /** Lookup strategy for attribute recipient group ID. */
+    @Nonnull private Function<ProfileRequestContext,String> attributeRecipientGroupIDLookupStrategy;
+    
     /** Selects, and limits, the authentication flows to use for requests by supported principals. */
     @Nonnull private Function<ProfileRequestContext,Collection<Principal>>
             defaultAuthenticationMethodsLookupStrategy;
@@ -130,8 +133,10 @@ public class BasicAdministrativeFlowDescriptor extends AbstractInterceptorAwareP
         supportsNonBrowserPredicate = PredicateSupport.alwaysTrue();
         authenticatedPredicate = PredicateSupport.alwaysFalse();
         policyNameLookupStrategy = FunctionSupport.constant(null);
-        resolveAttributesPredicate = PredicateSupport.alwaysFalse();
         forceAuthnPredicate = PredicateSupport.alwaysFalse();
+
+        resolveAttributesPredicate = PredicateSupport.alwaysFalse();
+        attributeRecipientGroupIDLookupStrategy = FunctionSupport.constant(null);
         
         builderFactory = XMLObjectProviderRegistrySupport.getBuilderFactory();
         uiInfo = ((SAMLObjectBuilder<UIInfo>) builderFactory.<UIInfo>ensureBuilder(
@@ -386,6 +391,35 @@ public class BasicAdministrativeFlowDescriptor extends AbstractInterceptorAwareP
         resolveAttributesPredicate = Constraint.isNotNull(condition, "Resolve attributes predicate cannot be null");
     }
     
+    /** {@inheritDoc} */
+    @Nullable public String getAttributeRecipientGroupID(@Nullable final ProfileRequestContext profileRequestContext) {
+        return attributeRecipientGroupIDLookupStrategy.apply(profileRequestContext);
+    }
+    
+    /**
+     * Set the group of services for which attributes are being resolved.
+     * 
+     * @param groupID group identifier
+     * 
+     * @since 5.2.0
+     */
+    public void setAttributeRecipientGroupID(@Nullable final String groupID) {
+        attributeRecipientGroupIDLookupStrategy = FunctionSupport.constant(groupID);
+    }
+
+    /**
+     * Set the lookup strategy for the group of services for which attributes are being resolved.
+     * 
+     * @param strategy  lookup strategy
+     * 
+     * @since 5.2.0
+     */
+    public void setAttributeRecipientGroupIDLookupStrategy(
+            @Nonnull final Function<ProfileRequestContext,String> strategy) {
+        attributeRecipientGroupIDLookupStrategy =
+                Constraint.isNotNull(strategy, "Group ID lookup strategy cannot be null");
+    }
+    
     /** {@inheritDoc} */
     @Nonnull @NotLive @Unmodifiable public List<String> getInboundInterceptorFlows(
             @Nullable final ProfileRequestContext profileRequestContext) {
@@ -692,6 +726,4 @@ public class BasicAdministrativeFlowDescriptor extends AbstractInterceptorAwareP
         }
     }
 
-    /** {@inheritDoc} */
-
 }
\ No newline at end of file
diff --git a/idp-cas-api/src/main/java/net/shibboleth/idp/cas/config/AbstractProtocolConfiguration.java b/idp-cas-api/src/main/java/net/shibboleth/idp/cas/config/AbstractProtocolConfiguration.java
index 5471b9ec5..5f05aebef 100644
--- a/idp-cas-api/src/main/java/net/shibboleth/idp/cas/config/AbstractProtocolConfiguration.java
+++ b/idp-cas-api/src/main/java/net/shibboleth/idp/cas/config/AbstractProtocolConfiguration.java
@@ -59,6 +59,9 @@ public abstract class AbstractProtocolConfiguration extends AbstractInterceptorA
     /** Whether attributes should be resolved in the course of the profile. */
     @Nonnull private Predicate<ProfileRequestContext> resolveAttributesPredicate;
     
+    /** Lookup strategy for attribute recipient group ID. */
+    @Nonnull private Function<ProfileRequestContext,String> attributeRecipientGroupIDLookupStrategy;
+    
     /** Holds default security config object to use. */
     @Nonnull private final SecurityConfiguration defaultSecurityConfiguration;
 
@@ -71,6 +74,8 @@ public abstract class AbstractProtocolConfiguration extends AbstractInterceptorA
         super(profileId);
         
         resolveAttributesPredicate = PredicateSupport.alwaysTrue();
+        attributeRecipientGroupIDLookupStrategy = FunctionSupport.constant(null);
+        
         ticketValidityPeriodLookupStrategy = FunctionSupport.constant(DEFAULT_TICKET_VALIDITY_PERIOD);
         final Duration fiveMins = Duration.ofMinutes(5);
         assert fiveMins!=null;
@@ -150,6 +155,35 @@ public abstract class AbstractProtocolConfiguration extends AbstractInterceptorA
     public void setResolveAttributesPredicate(@Nonnull final Predicate<ProfileRequestContext> condition) {
         resolveAttributesPredicate = Constraint.isNotNull(condition, "Resolve attributes predicate cannot be null");
     }
+    
+    /** {@inheritDoc} */
+    @Nullable public String getAttributeRecipientGroupID(@Nullable final ProfileRequestContext profileRequestContext) {
+        return attributeRecipientGroupIDLookupStrategy.apply(profileRequestContext);
+    }
+    
+    /**
+     * Set the group of services for which attributes are being resolved.
+     * 
+     * @param groupID group identifier
+     * 
+     * @since 5.2.0
+     */
+    public void setAttributeRecipientGroupID(@Nullable final String groupID) {
+        attributeRecipientGroupIDLookupStrategy = FunctionSupport.constant(groupID);
+    }
+
+    /**
+     * Set the lookup strategy for the group of services for which attributes are being resolved.
+     * 
+     * @param strategy  lookup strategy
+     * 
+     * @since 5.2.0
+     */
+    public void setAttributeRecipientGroupIDLookupStrategy(
+            @Nonnull final Function<ProfileRequestContext,String> strategy) {
+        attributeRecipientGroupIDLookupStrategy =
+                Constraint.isNotNull(strategy, "Group ID lookup strategy cannot be null");
+    }    
 
     /**
      * Get default ticket prefix.
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/relying-party-mddriven.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/relying-party-mddriven.xml
index 5061b6306..4d381bec1 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/relying-party-mddriven.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/relying-party-mddriven.xml
@@ -260,6 +260,9 @@
                 <constructor-arg value="true" />
             </bean>
         </property>
+        <property name="attributeRecipientGroupIDLookupStrategy">
+            <bean parent="shibboleth.MDDrivenStringProperty" p:propertyName="attributeRecipientGroupID" />
+        </property>
         <property name="ticketValidityPeriodLookupStrategy">
             <bean parent="shibboleth.MDDrivenDurationProperty" p:propertyName="ticketValidityPeriod">
                 <property name="defaultValue">
@@ -295,7 +298,10 @@
                 <constructor-arg value="true" />
             </bean>
         </property>
-        <property name="includeAttributeStatementPredicate">
+        <property name="attributeRecipientGroupIDLookupStrategy">
+            <bean parent="shibboleth.MDDrivenStringProperty" p:propertyName="attributeRecipientGroupID" />
+        </property>
+        <property name="includeAttributeStatementPredicate"> 
             <bean class="net.shibboleth.shared.logic.PredicateSupport" factory-method="fromFunction">
                 <constructor-arg>
                     <bean parent="shibboleth.MDDrivenBoolProperty" p:propertyName="includeAttributeStatement" />
@@ -338,6 +344,9 @@
                 </constructor-arg>
             </bean>
         </property>
+        <property name="attributeRecipientGroupIDLookupStrategy">
+            <bean parent="shibboleth.MDDrivenStringProperty" p:propertyName="attributeRecipientGroupID" />
+        </property>
     </bean>
 
     <bean id="SAML1.ArtifactResolution.MDDriven" parent="AbstractMDDrivenSAMLProfile" lazy-init="true"
@@ -417,6 +426,9 @@
                 <constructor-arg value="true" />
             </bean>
         </property>
+        <property name="attributeRecipientGroupIDLookupStrategy">
+            <bean parent="shibboleth.MDDrivenStringProperty" p:propertyName="attributeRecipientGroupID" />
+        </property>
         <property name="includeAttributeStatementPredicate">
             <bean class="net.shibboleth.shared.logic.PredicateSupport" factory-method="fromFunction">
                 <constructor-arg>
@@ -686,6 +698,9 @@
                 <constructor-arg value="false" />
             </bean>
         </property>
+        <property name="attributeRecipientGroupIDLookupStrategy">
+            <bean parent="shibboleth.MDDrivenStringProperty" p:propertyName="attributeRecipientGroupID" />
+        </property>
     </bean>
 
     <bean id="SAML2.ArtifactResolution.MDDriven" parent="AbstractMDDrivenSAML2Profile" lazy-init="true"
diff --git a/idp-profile-impl/src/main/java/net/shibboleth/idp/profile/impl/FilterAttributes.java b/idp-profile-impl/src/main/java/net/shibboleth/idp/profile/impl/FilterAttributes.java
index 0de9496b2..e43b6dc39 100644
--- a/idp-profile-impl/src/main/java/net/shibboleth/idp/profile/impl/FilterAttributes.java
+++ b/idp-profile-impl/src/main/java/net/shibboleth/idp/profile/impl/FilterAttributes.java
@@ -39,6 +39,7 @@ import net.shibboleth.idp.authn.context.SubjectContext;
 import net.shibboleth.idp.authn.context.navigate.SubjectContextPrincipalLookupFunction;
 import net.shibboleth.idp.profile.AbstractProfileAction;
 import net.shibboleth.idp.profile.IdPEventIds;
+import net.shibboleth.profile.config.AttributeResolvingProfileConfiguration;
 import net.shibboleth.profile.context.RelyingPartyContext;
 import net.shibboleth.profile.context.navigate.IssuerLookupFunction;
 import net.shibboleth.profile.context.navigate.RelyingPartyIdLookupFunction;
@@ -430,6 +431,12 @@ public class FilterAttributes extends AbstractProfileAction {
             .setProxiedRequesterContextLookupStrategy(proxiesFromFilterLookupStrategy)
             .setProxiedRequesterMetadataContextLookupStrategy(proxiedMetadataFromFilterLookupStrategy);
 
+        // Check for profile config to drive group ID determination.
+        final RelyingPartyContext rpContext = profileRequestContext.getSubcontext(RelyingPartyContext.class);
+        if (rpContext != null && rpContext.getProfileConfig() instanceof AttributeResolvingProfileConfiguration arpc) {
+            filterContext.setAttributeRecipientGroupID(arpc.getAttributeRecipientGroupID(profileRequestContext));
+        }
+        
         // If the filter context doesn't have a set of attributes to filter already
         // then look for them in the AttributeContext.
         if (filterContext.getPrefilteredIdPAttributes().isEmpty()) {
diff --git a/idp-profile-impl/src/main/java/net/shibboleth/idp/profile/impl/ResolveAttributes.java b/idp-profile-impl/src/main/java/net/shibboleth/idp/profile/impl/ResolveAttributes.java
index f22dc5c37..e36247044 100644
--- a/idp-profile-impl/src/main/java/net/shibboleth/idp/profile/impl/ResolveAttributes.java
+++ b/idp-profile-impl/src/main/java/net/shibboleth/idp/profile/impl/ResolveAttributes.java
@@ -36,6 +36,7 @@ import net.shibboleth.idp.authn.context.navigate.SubjectContextPrincipalLookupFu
 import net.shibboleth.idp.profile.AbstractProfileAction;
 import net.shibboleth.idp.profile.IdPEventIds;
 import net.shibboleth.idp.profile.context.SpringRequestContext;
+import net.shibboleth.profile.config.AttributeResolvingProfileConfiguration;
 import net.shibboleth.profile.context.RelyingPartyContext;
 import net.shibboleth.profile.context.navigate.RelyingPartyIdLookupFunction;
 import net.shibboleth.profile.context.navigate.IssuerLookupFunction;
@@ -334,6 +335,12 @@ public final class ResolveAttributes extends AbstractProfileAction {
         if (resolutionContextDecorator != null) {
             resolutionContextDecorator.accept(resolutionContext);
         }
+        
+        // Check for profile config to drive group ID determination.
+        final RelyingPartyContext rpContext = profileRequestContext.getSubcontext(RelyingPartyContext.class);
+        if (rpContext != null && rpContext.getProfileConfig() instanceof AttributeResolvingProfileConfiguration arpc) {
+            resolutionContext.setAttributeRecipientGroupID(arpc.getAttributeRecipientGroupID(profileRequestContext));
+        }
     }
     
 }
\ No newline at end of file
diff --git a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml1/profile/config/impl/AttributeQueryProfileConfiguration.java b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml1/profile/config/impl/AttributeQueryProfileConfiguration.java
index af82cce88..0e2ed978f 100644
--- a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml1/profile/config/impl/AttributeQueryProfileConfiguration.java
+++ b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml1/profile/config/impl/AttributeQueryProfileConfiguration.java
@@ -14,12 +14,18 @@
 
 package net.shibboleth.idp.saml.saml1.profile.config.impl;
 
+import java.util.function.Function;
+
 import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 
+import org.opensaml.profile.context.ProfileRequestContext;
 import org.opensaml.profile.logic.NoIntegrityMessageChannelPredicate;
 
 import net.shibboleth.saml.profile.config.SAMLAssertionProducingProfileConfiguration;
 import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.logic.FunctionSupport;
 
 /** Configuration support for SAML 1 attribute query requests. */
 public class AttributeQueryProfileConfiguration extends AbstractSAML1AssertionProducingProfileConfiguration
@@ -29,6 +35,9 @@ public class AttributeQueryProfileConfiguration extends AbstractSAML1AssertionPr
     /** Name of profile counter. */
     @Nonnull @NotEmpty public static final String PROFILE_COUNTER = "net.shibboleth.idp.profiles.saml1.query.attribute";
     
+    /** Lookup strategy for attribute recipient group ID. */
+    @Nonnull private Function<ProfileRequestContext,String> attributeRecipientGroupIDLookupStrategy;
+    
     /** Constructor. */
     public AttributeQueryProfileConfiguration() {
         this(PROFILE_ID);
@@ -42,6 +51,41 @@ public class AttributeQueryProfileConfiguration extends AbstractSAML1AssertionPr
     protected AttributeQueryProfileConfiguration(@Nonnull @NotEmpty final String profileId) {
         super(profileId);
         setSignResponsesPredicate(new NoIntegrityMessageChannelPredicate());
+        attributeRecipientGroupIDLookupStrategy = FunctionSupport.constant(null);
+    }
+
+    /** {@inheritDoc} */
+    public boolean isResolveAttributes(@Nullable final ProfileRequestContext profileRequestContext) {
+        return true;
+    }
+
+    /** {@inheritDoc} */
+    @Nullable public String getAttributeRecipientGroupID(@Nullable final ProfileRequestContext profileRequestContext) {
+        return attributeRecipientGroupIDLookupStrategy.apply(profileRequestContext);
+    }
+    
+    /**
+     * Set the group of services for which attributes are being resolved.
+     * 
+     * @param groupID group identifier
+     * 
+     * @since 5.2.0
+     */
+    public void setAttributeRecipientGroupID(@Nullable final String groupID) {
+        attributeRecipientGroupIDLookupStrategy = FunctionSupport.constant(groupID);
+    }
+
+    /**
+     * Set the lookup strategy for the group of services for which attributes are being resolved.
+     * 
+     * @param strategy  lookup strategy
+     * 
+     * @since 5.2.0
+     */
+    public void setAttributeRecipientGroupIDLookupStrategy(
+            @Nonnull final Function<ProfileRequestContext,String> strategy) {
+        attributeRecipientGroupIDLookupStrategy =
+                Constraint.isNotNull(strategy, "Group ID lookup strategy cannot be null");
     }
 
 }
\ No newline at end of file
diff --git a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml1/profile/config/impl/BrowserSSOProfileConfiguration.java b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml1/profile/config/impl/BrowserSSOProfileConfiguration.java
index d0e1a9885..bc7628b91 100644
--- a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml1/profile/config/impl/BrowserSSOProfileConfiguration.java
+++ b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml1/profile/config/impl/BrowserSSOProfileConfiguration.java
@@ -49,6 +49,9 @@ public class BrowserSSOProfileConfiguration extends AbstractSAML1AssertionProduc
     /** Whether attributes should be resolved in the course of the profile. */
     @Nonnull private Predicate<ProfileRequestContext> resolveAttributesPredicate;
 
+    /** Lookup strategy for attribute recipient group ID. */
+    @Nonnull private Function<ProfileRequestContext,String> attributeRecipientGroupIDLookupStrategy;
+    
     /** Whether responses to the authentication request should include an attribute statement. */
     @Nonnull private Predicate<ProfileRequestContext> includeAttributeStatementPredicate;
     
@@ -85,6 +88,7 @@ public class BrowserSSOProfileConfiguration extends AbstractSAML1AssertionProduc
         super(profileId);
         setSignResponses(true);
         resolveAttributesPredicate = PredicateSupport.alwaysTrue();
+        attributeRecipientGroupIDLookupStrategy = FunctionSupport.constant(null);
         includeAttributeStatementPredicate = PredicateSupport.alwaysFalse();
         authenticationFlowsLookupStrategy = FunctionSupport.constant(null);
         postAuthenticationFlowsLookupStrategy = FunctionSupport.constant(null);
@@ -117,6 +121,35 @@ public class BrowserSSOProfileConfiguration extends AbstractSAML1AssertionProduc
         resolveAttributesPredicate = Constraint.isNotNull(condition, "Resolve attributes predicate cannot be null");
     }
 
+    /** {@inheritDoc} */
+    @Nullable public String getAttributeRecipientGroupID(@Nullable final ProfileRequestContext profileRequestContext) {
+        return attributeRecipientGroupIDLookupStrategy.apply(profileRequestContext);
+    }
+    
+    /**
+     * Set the group of services for which attributes are being resolved.
+     * 
+     * @param groupID group identifier
+     * 
+     * @since 5.2.0
+     */
+    public void setAttributeRecipientGroupID(@Nullable final String groupID) {
+        attributeRecipientGroupIDLookupStrategy = FunctionSupport.constant(groupID);
+    }
+
+    /**
+     * Set the lookup strategy for the group of services for which attributes are being resolved.
+     * 
+     * @param strategy  lookup strategy
+     * 
+     * @since 5.2.0
+     */
+    public void setAttributeRecipientGroupIDLookupStrategy(
+            @Nonnull final Function<ProfileRequestContext,String> strategy) {
+        attributeRecipientGroupIDLookupStrategy =
+                Constraint.isNotNull(strategy, "Group ID lookup strategy cannot be null");
+    }
+    
     /** {@inheritDoc} */
     public boolean isIncludeAttributeStatement(@Nullable final ProfileRequestContext profileRequestContext) {
         return includeAttributeStatementPredicate.test(profileRequestContext);
diff --git a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/config/impl/AttributeQueryProfileConfiguration.java b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/config/impl/AttributeQueryProfileConfiguration.java
index db45bbe98..bec9880b4 100644
--- a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/config/impl/AttributeQueryProfileConfiguration.java
+++ b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/config/impl/AttributeQueryProfileConfiguration.java
@@ -14,6 +14,7 @@
 
 package net.shibboleth.idp.saml.saml2.profile.config.impl;
 
+import java.util.function.Function;
 import java.util.function.Predicate;
 
 import javax.annotation.Nonnull;
@@ -25,6 +26,7 @@ import org.opensaml.profile.logic.NoIntegrityMessageChannelPredicate;
 
 import net.shibboleth.shared.annotation.constraint.NotEmpty;
 import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.logic.FunctionSupport;
 import net.shibboleth.shared.logic.PredicateSupport;
 
 /** Configuration support for IdP SAML 2.0 attribute query profile. */
@@ -33,10 +35,13 @@ public class AttributeQueryProfileConfiguration extends AbstractSAML2AssertionPr
     
     /** Name of profile counter. */
     @Nonnull @NotEmpty public static final String PROFILE_COUNTER = "net.shibboleth.idp.profiles.sam2.query.attribute";
-
+    
     /** Whether the FriendlyName attribute should be randomized when encoding Attributes. */
     @Nonnull private Predicate<ProfileRequestContext> randomizeFriendlyNamePredicate;
 
+    /** Lookup strategy for attribute recipient group ID. */
+    @Nonnull private Function<ProfileRequestContext,String> attributeRecipientGroupIDLookupStrategy;
+    
     /** Constructor. */
     public AttributeQueryProfileConfiguration() {
         this(PROFILE_ID);
@@ -52,6 +57,7 @@ public class AttributeQueryProfileConfiguration extends AbstractSAML2AssertionPr
         setSignResponsesPredicate(new NoIntegrityMessageChannelPredicate());
         setEncryptAssertionsPredicate(new NoConfidentialityMessageChannelPredicate());
         randomizeFriendlyNamePredicate = PredicateSupport.alwaysFalse();
+        attributeRecipientGroupIDLookupStrategy = FunctionSupport.constant(null);
     }
 
     /** {@inheritDoc} */
@@ -82,5 +88,39 @@ public class AttributeQueryProfileConfiguration extends AbstractSAML2AssertionPr
     public void setRandomizeFriendlyNamePredicate(@Nonnull final Predicate<ProfileRequestContext> condition) {
         randomizeFriendlyNamePredicate = Constraint.isNotNull(condition, "Condition cannot be null");
     }
+
+    /** {@inheritDoc} */
+    public boolean isResolveAttributes(@Nullable final ProfileRequestContext profileRequestContext) {
+        return true;
+    }
+
+    /** {@inheritDoc} */
+    @Nullable public String getAttributeRecipientGroupID(@Nullable final ProfileRequestContext profileRequestContext) {
+        return attributeRecipientGroupIDLookupStrategy.apply(profileRequestContext);
+    }
     
+    /**
+     * Set the group of services for which attributes are being resolved.
+     * 
+     * @param groupID group identifier
+     * 
+     * @since 5.2.0
+     */
+    public void setAttributeRecipientGroupID(@Nullable final String groupID) {
+        attributeRecipientGroupIDLookupStrategy = FunctionSupport.constant(groupID);
+    }
+
+    /**
+     * Set the lookup strategy for the group of services for which attributes are being resolved.
+     * 
+     * @param strategy  lookup strategy
+     * 
+     * @since 5.2.0
+     */
+    public void setAttributeRecipientGroupIDLookupStrategy(
+            @Nonnull final Function<ProfileRequestContext,String> strategy) {
+        attributeRecipientGroupIDLookupStrategy =
+                Constraint.isNotNull(strategy, "Group ID lookup strategy cannot be null");
+    }
+
 }
\ No newline at end of file
diff --git a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/config/impl/BrowserSSOProfileConfiguration.java b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/config/impl/BrowserSSOProfileConfiguration.java
index 0ceaa2d03..a737e8f53 100644
--- a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/config/impl/BrowserSSOProfileConfiguration.java
+++ b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/config/impl/BrowserSSOProfileConfiguration.java
@@ -59,6 +59,9 @@ public class BrowserSSOProfileConfiguration extends AbstractSAML2AssertionProduc
     /** Whether attributes should be resolved in the course of the profile. */
     @Nonnull private Predicate<ProfileRequestContext> resolveAttributesPredicate;
 
+    /** Lookup strategy for attribute recipient group ID. */
+    @Nonnull private Function<ProfileRequestContext,String> attributeRecipientGroupIDLookupStrategy;
+    
     /** Whether responses to the authentication request should include an attribute statement. */
     @Nonnull private Predicate<ProfileRequestContext> includeAttributeStatementPredicate;
 
@@ -159,6 +162,7 @@ public class BrowserSSOProfileConfiguration extends AbstractSAML2AssertionProduc
         setSignResponses(true);
         setEncryptAssertions(true);
         resolveAttributesPredicate = PredicateSupport.alwaysTrue();
+        attributeRecipientGroupIDLookupStrategy = FunctionSupport.constant(null);
         includeAttributeStatementPredicate = PredicateSupport.alwaysTrue();
         ignoreScoping = PredicateSupport.alwaysFalse();
         forceAuthnPredicate = new ProxyAwareForceAuthnPredicate();
@@ -210,6 +214,35 @@ public class BrowserSSOProfileConfiguration extends AbstractSAML2AssertionProduc
         resolveAttributesPredicate = Constraint.isNotNull(condition, "Resolve attributes predicate cannot be null");
     }
 
+    /** {@inheritDoc} */
+    @Nullable public String getAttributeRecipientGroupID(@Nullable final ProfileRequestContext profileRequestContext) {
+        return attributeRecipientGroupIDLookupStrategy.apply(profileRequestContext);
+    }
+    
+    /**
+     * Set the group of services for which attributes are being resolved.
+     * 
+     * @param groupID group identifier
+     * 
+     * @since 5.2.0
+     */
+    public void setAttributeRecipientGroupID(@Nullable final String groupID) {
+        attributeRecipientGroupIDLookupStrategy = FunctionSupport.constant(groupID);
+    }
+
+    /**
+     * Set the lookup strategy for the group of services for which attributes are being resolved.
+     * 
+     * @param strategy  lookup strategy
+     * 
+     * @since 5.2.0
+     */
+    public void setAttributeRecipientGroupIDLookupStrategy(
+            @Nonnull final Function<ProfileRequestContext,String> strategy) {
+        attributeRecipientGroupIDLookupStrategy =
+                Constraint.isNotNull(strategy, "Group ID lookup strategy cannot be null");
+    }
+    
     /** {@inheritDoc} */
     public boolean isIncludeAttributeStatement(@Nullable final ProfileRequestContext profileRequestContext) {
         return includeAttributeStatementPredicate.test(profileRequestContext);

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


More information about the commits mailing list