[java-identity-provider] branch main updated: JSPROF-11 - Add attributes to resolve to resolving profile interface
Scott Cantor
cantor.2 at osu.edu
Wed Sep 17 19:55: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=816c2783978d5a231e3b02f1f1a7ec0a95e884b9
The following commit(s) were added to refs/heads/main by this push:
new 816c27839 JSPROF-11 - Add attributes to resolve to resolving profile interface
816c27839 is described below
commit 816c2783978d5a231e3b02f1f1a7ec0a95e884b9
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Wed Sep 17 15:55:26 2025 -0400
JSPROF-11 - Add attributes to resolve to resolving profile interface
https://shibboleth.atlassian.net/browse/JSPROF-11
Implemented setting for all relevant profiles.
Added to MDDriven wiring.
Added to ResolveAttributes action.
---
.../admin/BasicAdministrativeFlowDescriptor.java | 44 +++++++++++++++++++
.../cas/config/AbstractProtocolConfiguration.java | 49 ++++++++++++++++++++++
.../shibboleth/idp/conf/relying-party-mddriven.xml | 15 +++++++
.../idp/profile/impl/ResolveAttributes.java | 45 ++++++++++++++++++--
.../impl/AttributeQueryProfileConfiguration.java | 49 ++++++++++++++++++++++
.../impl/BrowserSSOProfileConfiguration.java | 44 +++++++++++++++++++
.../impl/AttributeQueryProfileConfiguration.java | 49 ++++++++++++++++++++++
.../impl/BrowserSSOProfileConfiguration.java | 44 +++++++++++++++++++
8 files changed, 336 insertions(+), 3 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 401e5ffba..76db23878 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
@@ -38,6 +38,7 @@ import org.opensaml.security.config.SecurityConfiguration;
import com.google.common.base.MoreObjects;
+import net.shibboleth.idp.attribute.IdPAttribute;
import net.shibboleth.idp.authn.principal.PrincipalServiceManager;
import net.shibboleth.idp.profile.config.AbstractInterceptorAwareProfileConfiguration;
import net.shibboleth.profile.config.OverriddenIssuerProfileConfiguration;
@@ -88,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 requested IdP attribute names to pass into resolver. */
+ @Nonnull private Function<ProfileRequestContext,Collection<String>> requestedIdPAttributeNamesLookupStrategy;
/** Lookup strategy for attribute recipient group ID. */
@Nonnull private Function<ProfileRequestContext,String> attributeRecipientGroupIDLookupStrategy;
@@ -136,6 +140,7 @@ public class BasicAdministrativeFlowDescriptor extends AbstractInterceptorAwareP
forceAuthnPredicate = PredicateSupport.alwaysFalse();
resolveAttributesPredicate = PredicateSupport.alwaysFalse();
+ requestedIdPAttributeNamesLookupStrategy = FunctionSupport.constant(null);
attributeRecipientGroupIDLookupStrategy = FunctionSupport.constant(null);
builderFactory = XMLObjectProviderRegistrySupport.getBuilderFactory();
@@ -391,6 +396,45 @@ public class BasicAdministrativeFlowDescriptor extends AbstractInterceptorAwareP
resolveAttributesPredicate = Constraint.isNotNull(condition, "Resolve attributes predicate cannot be null");
}
+ /** {@inheritDoc} */
+ @Nonnull @Unmodifiable @NotLive public Collection<String> getRequestedIdPAttributeNames(
+ @Nullable final ProfileRequestContext profileRequestContext) {
+ final Collection<String> names = requestedIdPAttributeNamesLookupStrategy.apply(profileRequestContext);
+ if (names != null) {
+ return CollectionSupport.copyToSet(names);
+ }
+ return CollectionSupport.emptySet();
+ }
+
+ /**
+ * Set {@link IdPAttribute} names to resolve (if resolving attributes).
+ *
+ * @param names {@link IdPAttribute} names to resolve
+ *
+ * @since 5.2.0
+ */
+ public void setRequestedIdPAttributeNames(@Nullable final Collection<String> names) {
+ if (names == null || names.isEmpty()) {
+ requestedIdPAttributeNamesLookupStrategy = FunctionSupport.constant(null);
+ } else {
+ requestedIdPAttributeNamesLookupStrategy = FunctionSupport.constant(
+ CollectionSupport.copyToSet(StringSupport.normalizeStringCollection(names)));
+ }
+ }
+
+ /**
+ * Lookup strategy for {@link IdPAttribute} names to resolve (if resolving attributes).
+ *
+ * @param strategy lookup strategy
+ *
+ * @since 5.2.0
+ */
+ public void setRequestedIdPAttributeNamesLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext,Collection<String>> strategy) {
+ requestedIdPAttributeNamesLookupStrategy =
+ Constraint.isNotNull(strategy, "Requested IdPAttribute names lookup strategy cannot be null");
+ }
+
/** {@inheritDoc} */
@Nullable public String getAttributeRecipientGroupID(@Nullable final ProfileRequestContext profileRequestContext) {
return attributeRecipientGroupIDLookupStrategy.apply(profileRequestContext);
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 5f05aebef..a7e2d0791 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
@@ -15,6 +15,7 @@
package net.shibboleth.idp.cas.config;
import java.time.Duration;
+import java.util.Collection;
import java.util.function.Function;
import java.util.function.Predicate;
@@ -25,15 +26,20 @@ import org.opensaml.profile.context.ProfileRequestContext;
import org.opensaml.security.config.BasicSecurityConfiguration;
import org.opensaml.security.config.SecurityConfiguration;
+import net.shibboleth.idp.attribute.IdPAttribute;
import net.shibboleth.idp.cas.ticket.TicketIdentifierGenerationStrategy;
import net.shibboleth.idp.profile.config.AbstractInterceptorAwareProfileConfiguration;
import net.shibboleth.profile.config.AttributeResolvingProfileConfiguration;
import net.shibboleth.shared.annotation.ConfigurationSetting;
import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.annotation.constraint.NotLive;
+import net.shibboleth.shared.annotation.constraint.Unmodifiable;
+import net.shibboleth.shared.collection.CollectionSupport;
import net.shibboleth.shared.component.InitializableComponent;
import net.shibboleth.shared.logic.Constraint;
import net.shibboleth.shared.logic.FunctionSupport;
import net.shibboleth.shared.logic.PredicateSupport;
+import net.shibboleth.shared.primitive.StringSupport;
/**
* Base class for CAS protocol configuration.
@@ -59,6 +65,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 requested IdP attribute names to pass into resolver. */
+ @Nonnull private Function<ProfileRequestContext,Collection<String>> requestedIdPAttributeNamesLookupStrategy;
+
/** Lookup strategy for attribute recipient group ID. */
@Nonnull private Function<ProfileRequestContext,String> attributeRecipientGroupIDLookupStrategy;
@@ -74,6 +83,7 @@ public abstract class AbstractProtocolConfiguration extends AbstractInterceptorA
super(profileId);
resolveAttributesPredicate = PredicateSupport.alwaysTrue();
+ requestedIdPAttributeNamesLookupStrategy = FunctionSupport.constant(null);
attributeRecipientGroupIDLookupStrategy = FunctionSupport.constant(null);
ticketValidityPeriodLookupStrategy = FunctionSupport.constant(DEFAULT_TICKET_VALIDITY_PERIOD);
@@ -156,6 +166,45 @@ public abstract class AbstractProtocolConfiguration extends AbstractInterceptorA
resolveAttributesPredicate = Constraint.isNotNull(condition, "Resolve attributes predicate cannot be null");
}
+ /** {@inheritDoc} */
+ @Nonnull @Unmodifiable @NotLive public Collection<String> getRequestedIdPAttributeNames(
+ @Nullable final ProfileRequestContext profileRequestContext) {
+ final Collection<String> names = requestedIdPAttributeNamesLookupStrategy.apply(profileRequestContext);
+ if (names != null) {
+ return CollectionSupport.copyToSet(names);
+ }
+ return CollectionSupport.emptySet();
+ }
+
+ /**
+ * Set {@link IdPAttribute} names to resolve (if resolving attributes).
+ *
+ * @param names {@link IdPAttribute} names to resolve
+ *
+ * @since 5.2.0
+ */
+ public void setRequestedIdPAttributeNames(@Nullable final Collection<String> names) {
+ if (names == null || names.isEmpty()) {
+ requestedIdPAttributeNamesLookupStrategy = FunctionSupport.constant(null);
+ } else {
+ requestedIdPAttributeNamesLookupStrategy = FunctionSupport.constant(
+ CollectionSupport.copyToSet(StringSupport.normalizeStringCollection(names)));
+ }
+ }
+
+ /**
+ * Lookup strategy for {@link IdPAttribute} names to resolve (if resolving attributes).
+ *
+ * @param strategy lookup strategy
+ *
+ * @since 5.2.0
+ */
+ public void setRequestedIdPAttributeNamesLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext,Collection<String>> strategy) {
+ requestedIdPAttributeNamesLookupStrategy =
+ Constraint.isNotNull(strategy, "Requested IdPAttribute names lookup strategy cannot be null");
+ }
+
/** {@inheritDoc} */
@Nullable public String getAttributeRecipientGroupID(@Nullable final ProfileRequestContext profileRequestContext) {
return attributeRecipientGroupIDLookupStrategy.apply(profileRequestContext);
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 bca776910..fb4fcfb5f 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="requestedIdPAttributeNamesLookupStrategy">
+ <bean parent="shibboleth.MDDrivenSetProperty" p:propertyName="requestedIdPAttributeNames" />
+ </property>
<property name="attributeRecipientGroupIDLookupStrategy">
<bean parent="shibboleth.MDDrivenStringProperty" p:propertyName="attributeRecipientGroupID" />
</property>
@@ -298,6 +301,9 @@
<constructor-arg value="true" />
</bean>
</property>
+ <property name="requestedIdPAttributeNamesLookupStrategy">
+ <bean parent="shibboleth.MDDrivenSetProperty" p:propertyName="requestedIdPAttributeNames" />
+ </property>
<property name="attributeRecipientGroupIDLookupStrategy">
<bean parent="shibboleth.MDDrivenStringProperty" p:propertyName="attributeRecipientGroupID" />
</property>
@@ -344,6 +350,9 @@
</constructor-arg>
</bean>
</property>
+ <property name="requestedIdPAttributeNamesLookupStrategy">
+ <bean parent="shibboleth.MDDrivenSetProperty" p:propertyName="requestedIdPAttributeNames" />
+ </property>
<property name="attributeRecipientGroupIDLookupStrategy">
<bean parent="shibboleth.MDDrivenStringProperty" p:propertyName="attributeRecipientGroupID" />
</property>
@@ -426,6 +435,9 @@
<constructor-arg value="true" />
</bean>
</property>
+ <property name="requestedIdPAttributeNamesLookupStrategy">
+ <bean parent="shibboleth.MDDrivenSetProperty" p:propertyName="requestedIdPAttributeNames" />
+ </property>
<property name="attributeRecipientGroupIDLookupStrategy">
<bean parent="shibboleth.MDDrivenStringProperty" p:propertyName="attributeRecipientGroupID" />
</property>
@@ -706,6 +718,9 @@
<constructor-arg value="false" />
</bean>
</property>
+ <property name="requestedIdPAttributeNamesLookupStrategy">
+ <bean parent="shibboleth.MDDrivenSetProperty" p:propertyName="requestedIdPAttributeNames" />
+ </property>
<property name="attributeRecipientGroupIDLookupStrategy">
<bean parent="shibboleth.MDDrivenStringProperty" p:propertyName="attributeRecipientGroupID" />
</property>
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 19b6f752a..c919077f8 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
@@ -61,7 +61,12 @@ public final class ResolveAttributes extends AbstractProfileAction {
/** Class logger. */
@Nonnull private final Logger log = LoggerFactory.getLogger(ResolveAttributes.class);
-
+
+ /**
+ * Strategy used to locate the {@link RelyingPartyContext} associated with a given {@link ProfileRequestContext}.
+ */
+ @Nonnull private Function<ProfileRequestContext,RelyingPartyContext> relyingPartyContextLookupStrategy;
+
/** Service used to get the resolver used to fetch attributes. */
@Nonnull private final ReloadableService<AttributeResolver> attributeResolverService;
@@ -91,6 +96,9 @@ public final class ResolveAttributes extends AbstractProfileAction {
/** Whether to create and populate {@link AttributeResolutionContext}. */
private boolean createResolutionContext;
+
+ /** Tracked type-specific profile configuration. */
+ @Nullable private AttributeResolvingProfileConfiguration profileConfiguration;
/**
* Constructor.
@@ -99,6 +107,8 @@ public final class ResolveAttributes extends AbstractProfileAction {
*/
@SuppressWarnings("null")
public ResolveAttributes(@Nonnull final ReloadableService<AttributeResolver> resolverService) {
+ relyingPartyContextLookupStrategy = new ChildContextLookup<>(RelyingPartyContext.class);
+
attributeResolverService = Constraint.isNotNull(resolverService, "AttributeResolver cannot be null");
issuerLookupStrategy = new IssuerLookupFunction();
@@ -118,6 +128,22 @@ public final class ResolveAttributes extends AbstractProfileAction {
createResolutionContext = true;
}
+ /**
+ * Set the strategy used to locate the {@link RelyingPartyContext} associated with a given
+ * {@link ProfileRequestContext}.
+ *
+ * @param strategy strategy used to locate the {@link RelyingPartyContext} associated with a given
+ * {@link ProfileRequestContext}
+ *
+ * @since 5.2.0
+ */
+ public void setRelyingPartyContextLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext,RelyingPartyContext> strategy) {
+ checkSetterPreconditions();
+ relyingPartyContextLookupStrategy = Constraint.isNotNull(strategy,
+ "RelyingPartyContext lookup strategy cannot be null");
+ }
+
/**
* Set the strategy used to lookup the issuer for this attribute resolution.
*
@@ -247,6 +273,11 @@ public final class ResolveAttributes extends AbstractProfileAction {
}
}
+ final RelyingPartyContext ctx = relyingPartyContextLookupStrategy.apply(profileRequestContext);
+ if (ctx != null && ctx.getProfileConfig() instanceof AttributeResolvingProfileConfiguration pc) {
+ profileConfiguration = pc;
+ }
+
return true;
}
@@ -294,6 +325,7 @@ public final class ResolveAttributes extends AbstractProfileAction {
}
}
+// Checkstyle: CyclomaticComplexity OFF
/**
* Fill in the resolution context data.
*
@@ -306,12 +338,18 @@ public final class ResolveAttributes extends AbstractProfileAction {
resolutionContext.setResolutionLabel(resolutionLabel);
// Populate requested attributes, if not already set.
+ // Otherwise reference the directly provided strategy and if that does nothing,
+ // fall back to profile config if available.
if (resolutionContext.getRequestedIdPAttributeNames() == null
|| resolutionContext.getRequestedIdPAttributeNames().isEmpty()) {
assert attributesLookupStrategy != null;
final Collection<String> names = attributesLookupStrategy.apply(profileRequestContext);
- assert names != null;
- resolutionContext.setRequestedIdPAttributeNames(names);
+ if (names != null && !names.isEmpty()) {
+ resolutionContext.setRequestedIdPAttributeNames(names);
+ } else if (profileConfiguration != null) {
+ resolutionContext.setRequestedIdPAttributeNames(
+ profileConfiguration.getRequestedIdPAttributeNames(profileRequestContext));
+ }
}
if (null != principalNameLookupStrategy) {
@@ -345,5 +383,6 @@ public final class ResolveAttributes extends AbstractProfileAction {
}
}
}
+// Checkstyle: CyclomaticComplexity ON
}
\ 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 0e2ed978f..1c89e0ace 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,6 +14,7 @@
package net.shibboleth.idp.saml.saml1.profile.config.impl;
+import java.util.Collection;
import java.util.function.Function;
import javax.annotation.Nonnull;
@@ -22,10 +23,15 @@ import javax.annotation.Nullable;
import org.opensaml.profile.context.ProfileRequestContext;
import org.opensaml.profile.logic.NoIntegrityMessageChannelPredicate;
+import net.shibboleth.idp.attribute.IdPAttribute;
import net.shibboleth.saml.profile.config.SAMLAssertionProducingProfileConfiguration;
import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.annotation.constraint.NotLive;
+import net.shibboleth.shared.annotation.constraint.Unmodifiable;
+import net.shibboleth.shared.collection.CollectionSupport;
import net.shibboleth.shared.logic.Constraint;
import net.shibboleth.shared.logic.FunctionSupport;
+import net.shibboleth.shared.primitive.StringSupport;
/** Configuration support for SAML 1 attribute query requests. */
public class AttributeQueryProfileConfiguration extends AbstractSAML1AssertionProducingProfileConfiguration
@@ -34,6 +40,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 requested IdP attribute names to pass into resolver. */
+ @Nonnull private Function<ProfileRequestContext,Collection<String>> requestedIdPAttributeNamesLookupStrategy;
/** Lookup strategy for attribute recipient group ID. */
@Nonnull private Function<ProfileRequestContext,String> attributeRecipientGroupIDLookupStrategy;
@@ -51,6 +60,7 @@ public class AttributeQueryProfileConfiguration extends AbstractSAML1AssertionPr
protected AttributeQueryProfileConfiguration(@Nonnull @NotEmpty final String profileId) {
super(profileId);
setSignResponsesPredicate(new NoIntegrityMessageChannelPredicate());
+ requestedIdPAttributeNamesLookupStrategy = FunctionSupport.constant(null);
attributeRecipientGroupIDLookupStrategy = FunctionSupport.constant(null);
}
@@ -59,6 +69,45 @@ public class AttributeQueryProfileConfiguration extends AbstractSAML1AssertionPr
return true;
}
+ /** {@inheritDoc} */
+ @Nonnull @Unmodifiable @NotLive public Collection<String> getRequestedIdPAttributeNames(
+ @Nullable final ProfileRequestContext profileRequestContext) {
+ final Collection<String> names = requestedIdPAttributeNamesLookupStrategy.apply(profileRequestContext);
+ if (names != null) {
+ return CollectionSupport.copyToSet(names);
+ }
+ return CollectionSupport.emptySet();
+ }
+
+ /**
+ * Set {@link IdPAttribute} names to resolve (if resolving attributes).
+ *
+ * @param names {@link IdPAttribute} names to resolve
+ *
+ * @since 5.2.0
+ */
+ public void setRequestedIdPAttributeNames(@Nullable final Collection<String> names) {
+ if (names == null || names.isEmpty()) {
+ requestedIdPAttributeNamesLookupStrategy = FunctionSupport.constant(null);
+ } else {
+ requestedIdPAttributeNamesLookupStrategy = FunctionSupport.constant(
+ CollectionSupport.copyToSet(StringSupport.normalizeStringCollection(names)));
+ }
+ }
+
+ /**
+ * Lookup strategy for {@link IdPAttribute} names to resolve (if resolving attributes).
+ *
+ * @param strategy lookup strategy
+ *
+ * @since 5.2.0
+ */
+ public void setRequestedIdPAttributeNamesLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext,Collection<String>> strategy) {
+ requestedIdPAttributeNamesLookupStrategy =
+ Constraint.isNotNull(strategy, "Requested IdPAttribute names lookup strategy cannot be null");
+ }
+
/** {@inheritDoc} */
@Nullable public String getAttributeRecipientGroupID(@Nullable final ProfileRequestContext profileRequestContext) {
return attributeRecipientGroupIDLookupStrategy.apply(profileRequestContext);
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 bc7628b91..4e0363ea1 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
@@ -26,6 +26,7 @@ import javax.annotation.Nullable;
import org.opensaml.profile.context.ProfileRequestContext;
+import net.shibboleth.idp.attribute.IdPAttribute;
import net.shibboleth.idp.authn.config.AuthenticationProfileConfiguration;
import net.shibboleth.shared.annotation.constraint.NonNegative;
import net.shibboleth.shared.annotation.constraint.NotEmpty;
@@ -49,6 +50,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 requested IdP attribute names to pass into resolver. */
+ @Nonnull private Function<ProfileRequestContext,Collection<String>> requestedIdPAttributeNamesLookupStrategy;
+
/** Lookup strategy for attribute recipient group ID. */
@Nonnull private Function<ProfileRequestContext,String> attributeRecipientGroupIDLookupStrategy;
@@ -88,6 +92,7 @@ public class BrowserSSOProfileConfiguration extends AbstractSAML1AssertionProduc
super(profileId);
setSignResponses(true);
resolveAttributesPredicate = PredicateSupport.alwaysTrue();
+ requestedIdPAttributeNamesLookupStrategy = FunctionSupport.constant(null);
attributeRecipientGroupIDLookupStrategy = FunctionSupport.constant(null);
includeAttributeStatementPredicate = PredicateSupport.alwaysFalse();
authenticationFlowsLookupStrategy = FunctionSupport.constant(null);
@@ -121,6 +126,45 @@ public class BrowserSSOProfileConfiguration extends AbstractSAML1AssertionProduc
resolveAttributesPredicate = Constraint.isNotNull(condition, "Resolve attributes predicate cannot be null");
}
+ /** {@inheritDoc} */
+ @Nonnull @Unmodifiable @NotLive public Collection<String> getRequestedIdPAttributeNames(
+ @Nullable final ProfileRequestContext profileRequestContext) {
+ final Collection<String> names = requestedIdPAttributeNamesLookupStrategy.apply(profileRequestContext);
+ if (names != null) {
+ return CollectionSupport.copyToSet(names);
+ }
+ return CollectionSupport.emptySet();
+ }
+
+ /**
+ * Set {@link IdPAttribute} names to resolve (if resolving attributes).
+ *
+ * @param names {@link IdPAttribute} names to resolve
+ *
+ * @since 5.2.0
+ */
+ public void setRequestedIdPAttributeNames(@Nullable final Collection<String> names) {
+ if (names == null || names.isEmpty()) {
+ requestedIdPAttributeNamesLookupStrategy = FunctionSupport.constant(null);
+ } else {
+ requestedIdPAttributeNamesLookupStrategy = FunctionSupport.constant(
+ CollectionSupport.copyToSet(StringSupport.normalizeStringCollection(names)));
+ }
+ }
+
+ /**
+ * Lookup strategy for {@link IdPAttribute} names to resolve (if resolving attributes).
+ *
+ * @param strategy lookup strategy
+ *
+ * @since 5.2.0
+ */
+ public void setRequestedIdPAttributeNamesLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext,Collection<String>> strategy) {
+ requestedIdPAttributeNamesLookupStrategy =
+ Constraint.isNotNull(strategy, "Requested IdPAttribute names lookup strategy cannot be null");
+ }
+
/** {@inheritDoc} */
@Nullable public String getAttributeRecipientGroupID(@Nullable final ProfileRequestContext profileRequestContext) {
return attributeRecipientGroupIDLookupStrategy.apply(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 ab9687ccf..a2204d320 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.Collection;
import java.util.function.Function;
import java.util.function.Predicate;
@@ -25,10 +26,15 @@ import org.opensaml.profile.context.ProfileRequestContext;
import org.opensaml.profile.logic.NoConfidentialityMessageChannelPredicate;
import org.opensaml.profile.logic.NoIntegrityMessageChannelPredicate;
+import net.shibboleth.idp.attribute.IdPAttribute;
import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.annotation.constraint.NotLive;
+import net.shibboleth.shared.annotation.constraint.Unmodifiable;
+import net.shibboleth.shared.collection.CollectionSupport;
import net.shibboleth.shared.logic.Constraint;
import net.shibboleth.shared.logic.FunctionSupport;
import net.shibboleth.shared.logic.PredicateSupport;
+import net.shibboleth.shared.primitive.StringSupport;
/** Configuration support for IdP SAML 2.0 attribute query profile. */
public class AttributeQueryProfileConfiguration extends AbstractSAML2AssertionProducingProfileConfiguration
@@ -40,6 +46,9 @@ public class AttributeQueryProfileConfiguration extends AbstractSAML2AssertionPr
/** Whether the FriendlyName attribute should be randomized when encoding Attributes. */
@Nonnull private Predicate<ProfileRequestContext> randomizeFriendlyNamePredicate;
+ /** Lookup strategy for requested IdP attribute names to pass into resolver. */
+ @Nonnull private Function<ProfileRequestContext,Collection<String>> requestedIdPAttributeNamesLookupStrategy;
+
/** Lookup strategy for attribute recipient group ID. */
@Nonnull private Function<ProfileRequestContext,String> attributeRecipientGroupIDLookupStrategy;
@@ -64,6 +73,7 @@ public class AttributeQueryProfileConfiguration extends AbstractSAML2AssertionPr
setSignResponsesPredicate(new NoIntegrityMessageChannelPredicate());
setEncryptAssertionsPredicate(new NoConfidentialityMessageChannelPredicate());
randomizeFriendlyNamePredicate = PredicateSupport.alwaysFalse();
+ requestedIdPAttributeNamesLookupStrategy = FunctionSupport.constant(null);
attributeRecipientGroupIDLookupStrategy = FunctionSupport.constant(null);
signSOAPRequestsPredicate = new org.opensaml.messaging.logic.NoIntegrityMessageChannelPredicate();
@@ -107,6 +117,45 @@ public class AttributeQueryProfileConfiguration extends AbstractSAML2AssertionPr
return true;
}
+ /** {@inheritDoc} */
+ @Nonnull @Unmodifiable @NotLive public Collection<String> getRequestedIdPAttributeNames(
+ @Nullable final ProfileRequestContext profileRequestContext) {
+ final Collection<String> names = requestedIdPAttributeNamesLookupStrategy.apply(profileRequestContext);
+ if (names != null) {
+ return CollectionSupport.copyToSet(names);
+ }
+ return CollectionSupport.emptySet();
+ }
+
+ /**
+ * Set {@link IdPAttribute} names to resolve (if resolving attributes).
+ *
+ * @param names {@link IdPAttribute} names to resolve
+ *
+ * @since 5.2.0
+ */
+ public void setRequestedIdPAttributeNames(@Nullable final Collection<String> names) {
+ if (names == null || names.isEmpty()) {
+ requestedIdPAttributeNamesLookupStrategy = FunctionSupport.constant(null);
+ } else {
+ requestedIdPAttributeNamesLookupStrategy = FunctionSupport.constant(
+ CollectionSupport.copyToSet(StringSupport.normalizeStringCollection(names)));
+ }
+ }
+
+ /**
+ * Lookup strategy for {@link IdPAttribute} names to resolve (if resolving attributes).
+ *
+ * @param strategy lookup strategy
+ *
+ * @since 5.2.0
+ */
+ public void setRequestedIdPAttributeNamesLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext,Collection<String>> strategy) {
+ requestedIdPAttributeNamesLookupStrategy =
+ Constraint.isNotNull(strategy, "Requested IdPAttribute names lookup strategy cannot be null");
+ }
+
/** {@inheritDoc} */
@Nullable public String getAttributeRecipientGroupID(@Nullable final ProfileRequestContext profileRequestContext) {
return attributeRecipientGroupIDLookupStrategy.apply(profileRequestContext);
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 699ba5cea..5137eefd0 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
@@ -25,6 +25,7 @@ import java.util.function.Predicate;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import net.shibboleth.idp.attribute.IdPAttribute;
import net.shibboleth.idp.authn.config.AuthenticationProfileConfiguration;
import net.shibboleth.idp.saml.profile.config.logic.ProxyAwareForceAuthnPredicate;
import net.shibboleth.idp.saml.saml2.profile.config.navigate.ProxyAwareAuthnContextComparisonLookupFunction;
@@ -59,6 +60,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 requested IdP attribute names to pass into resolver. */
+ @Nonnull private Function<ProfileRequestContext,Collection<String>> requestedIdPAttributeNamesLookupStrategy;
+
/** Lookup strategy for attribute recipient group ID. */
@Nonnull private Function<ProfileRequestContext,String> attributeRecipientGroupIDLookupStrategy;
@@ -165,6 +169,7 @@ public class BrowserSSOProfileConfiguration extends AbstractSAML2AssertionProduc
setSignResponses(true);
setEncryptAssertions(true);
resolveAttributesPredicate = PredicateSupport.alwaysTrue();
+ requestedIdPAttributeNamesLookupStrategy = FunctionSupport.constant(null);
attributeRecipientGroupIDLookupStrategy = FunctionSupport.constant(null);
includeAttributeStatementPredicate = PredicateSupport.alwaysTrue();
ignoreScoping = PredicateSupport.alwaysFalse();
@@ -218,6 +223,45 @@ public class BrowserSSOProfileConfiguration extends AbstractSAML2AssertionProduc
resolveAttributesPredicate = Constraint.isNotNull(condition, "Resolve attributes predicate cannot be null");
}
+ /** {@inheritDoc} */
+ @Nonnull @Unmodifiable @NotLive public Collection<String> getRequestedIdPAttributeNames(
+ @Nullable final ProfileRequestContext profileRequestContext) {
+ final Collection<String> names = requestedIdPAttributeNamesLookupStrategy.apply(profileRequestContext);
+ if (names != null) {
+ return CollectionSupport.copyToSet(names);
+ }
+ return CollectionSupport.emptySet();
+ }
+
+ /**
+ * Set {@link IdPAttribute} names to resolve (if resolving attributes).
+ *
+ * @param names {@link IdPAttribute} names to resolve
+ *
+ * @since 5.2.0
+ */
+ public void setRequestedIdPAttributeNames(@Nullable final Collection<String> names) {
+ if (names == null || names.isEmpty()) {
+ requestedIdPAttributeNamesLookupStrategy = FunctionSupport.constant(null);
+ } else {
+ requestedIdPAttributeNamesLookupStrategy = FunctionSupport.constant(
+ CollectionSupport.copyToSet(StringSupport.normalizeStringCollection(names)));
+ }
+ }
+
+ /**
+ * Lookup strategy for {@link IdPAttribute} names to resolve (if resolving attributes).
+ *
+ * @param strategy lookup strategy
+ *
+ * @since 5.2.0
+ */
+ public void setRequestedIdPAttributeNamesLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext,Collection<String>> strategy) {
+ requestedIdPAttributeNamesLookupStrategy =
+ Constraint.isNotNull(strategy, "Requested IdPAttribute names lookup strategy cannot be null");
+ }
+
/** {@inheritDoc} */
@Nullable public String getAttributeRecipientGroupID(@Nullable final ProfileRequestContext profileRequestContext) {
return attributeRecipientGroupIDLookupStrategy.apply(profileRequestContext);
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list