[java-sp-server] branch main updated: Initial set of profile configuration classes.
Scott Cantor
cantor.2 at osu.edu
Fri Feb 3 19:15:02 UTC 2023
This is an automated email from the git hooks/post-receive script.
scantor pushed a commit to branch main
in repository java-sp-server.
View the commit online:
http://git.shibboleth.net/view/?p=java-sp-server.git;a=commit;h=d8d9ef99d176aea7b4cc1fcefa6063c1a010ef87
The following commit(s) were added to refs/heads/main by this push:
new d8d9ef9 Initial set of profile configuration classes.
d8d9ef9 is described below
commit d8d9ef99d176aea7b4cc1fcefa6063c1a010ef87
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Fri Feb 3 14:15:00 2023 -0500
Initial set of profile configuration classes.
---
...tSAML2ArtifactConsumerProfileConfiguration.java | 103 +++++
...SAML2AssertionConsumerProfileConfiguration.java | 160 +++++++
.../config/AbstractSAML2ProfileConfiguration.java | 183 ++++++++
.../config/BrowserSSOProfileConfiguration.java | 501 +++++++++++++++++++++
.../SAML2ArtifactConsumerProfileConfiguration.java | 50 ++
...SAML2AssertionConsumerProfileConfiguration.java | 66 +++
.../sp/saml2/config/SAML2ProfileConfiguration.java | 81 ++++
.../shibboleth/sp/saml2/config/package-info.java | 25 +-
.../sp/config/AbstractProfileConfiguration.java | 36 ++
.../shibboleth/sp/config/ProfileConfiguration.java | 21 +
10 files changed, 1203 insertions(+), 23 deletions(-)
diff --git a/sp-saml-api/src/main/java/net/shibboleth/sp/saml2/config/AbstractSAML2ArtifactConsumerProfileConfiguration.java b/sp-saml-api/src/main/java/net/shibboleth/sp/saml2/config/AbstractSAML2ArtifactConsumerProfileConfiguration.java
new file mode 100644
index 0000000..1f8e654
--- /dev/null
+++ b/sp-saml-api/src/main/java/net/shibboleth/sp/saml2/config/AbstractSAML2ArtifactConsumerProfileConfiguration.java
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.sp.saml2.config;
+
+import java.util.function.Predicate;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.messaging.context.MessageContext;
+import org.opensaml.messaging.logic.NoIntegrityMessageChannelPredicate;
+
+import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.logic.PredicateSupport;
+
+/**
+ * Configuration support for artifact-consuming profiles.
+ */
+public abstract class AbstractSAML2ArtifactConsumerProfileConfiguration extends AbstractSAML2ProfileConfiguration
+ implements SAML2ArtifactConsumerProfileConfiguration {
+
+ /** Predicate used to determine if artifact resolution requests should be signed. */
+ @Nonnull private Predicate<MessageContext> signArtifactRequestsPredicate;
+
+ /** Predicate used to determine if artifact resolution requests should use client TLS. */
+ @Nonnull private Predicate<MessageContext> clientTLSArtifactRequestsPredicate;
+
+ /**
+ * Constructor.
+ *
+ * @param profileId unique ID for this profile
+ */
+ protected AbstractSAML2ArtifactConsumerProfileConfiguration(@Nonnull @NotEmpty final String profileId) {
+ super(profileId);
+ signArtifactRequestsPredicate = new NoIntegrityMessageChannelPredicate();
+ clientTLSArtifactRequestsPredicate = new NoIntegrityMessageChannelPredicate().negate();
+ }
+
+ /** {@inheritDoc} */
+ public boolean isSignArtifactRequests(@Nullable final MessageContext messageContext) {
+ return signArtifactRequestsPredicate.test(messageContext);
+ }
+
+ /**
+ * Set whether artifact resolution requests should be signed.
+ *
+ * @param flag flag to set
+ */
+ public void setSignArtifactRequests(final boolean flag) {
+ signArtifactRequestsPredicate = PredicateSupport.constant(flag);
+ }
+
+ /**
+ * Set the predicate used to determine if artifact resolution requests should be signed.
+ *
+ * @param predicate the predicate
+ */
+ public void setSignArtifactRequestsPredicate(@Nonnull final Predicate<MessageContext> predicate) {
+ signArtifactRequestsPredicate = Constraint.isNotNull(predicate,
+ "Predicate used to determine artifact request signing may not be null");
+ }
+
+ /** {@inheritDoc} */
+ public boolean isClientTLSArtifactRequests(@Nullable final MessageContext messageContext) {
+ return clientTLSArtifactRequestsPredicate.test(messageContext);
+ }
+
+ /**
+ * Set whether artifact resolution requests should use client TLS.
+ *
+ * @param flag flag to set
+ */
+ public void setClientTLSArtifactRequests(final boolean flag) {
+ clientTLSArtifactRequestsPredicate = PredicateSupport.constant(flag);
+ }
+
+ /**
+ * Set the predicate used to determine if artifact resolution requests should use client TLS.
+ *
+ * @param predicate the predicate
+ */
+ public void setClientTLSArtifactRequestsPredicate(@Nonnull final Predicate<MessageContext> predicate) {
+ clientTLSArtifactRequestsPredicate = Constraint.isNotNull(predicate,
+ "Predicate used to determine artifact client TLS use may not be null");
+ }
+
+}
\ No newline at end of file
diff --git a/sp-saml-api/src/main/java/net/shibboleth/sp/saml2/config/AbstractSAML2AssertionConsumerProfileConfiguration.java b/sp-saml-api/src/main/java/net/shibboleth/sp/saml2/config/AbstractSAML2AssertionConsumerProfileConfiguration.java
new file mode 100644
index 0000000..cf822bf
--- /dev/null
+++ b/sp-saml-api/src/main/java/net/shibboleth/sp/saml2/config/AbstractSAML2AssertionConsumerProfileConfiguration.java
@@ -0,0 +1,160 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.sp.saml2.config;
+
+import java.time.Duration;
+import java.util.Collection;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import net.shibboleth.shared.annotation.constraint.NonNegative;
+import net.shibboleth.shared.annotation.constraint.NonnullElements;
+import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.annotation.constraint.NotLive;
+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;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+/** Base class for SAML profile configurations. */
+public abstract class AbstractSAML2AssertionConsumerProfileConfiguration
+ extends AbstractSAML2ArtifactConsumerProfileConfiguration
+ implements SAML2AssertionConsumerProfileConfiguration {
+
+ /** Whether to require signed assertions. */
+ @Nonnull private Predicate<ProfileRequestContext> requireSignedAssertionsPredicate;
+
+ /** Lookup function to supply assertionLifetime property. */
+ @Nonnull private Function<ProfileRequestContext,Duration> assertionLifetimeLookupStrategy;
+
+ /** Lookup function to supply additionalAudiences property. */
+ @Nonnull private Function<ProfileRequestContext,Set<String>> additionalAudiencesLookupStrategy;
+
+ /**
+ * Constructor.
+ *
+ * @param profileId ID of the communication profile
+ */
+ public AbstractSAML2AssertionConsumerProfileConfiguration(@Nonnull @NotEmpty final String profileId) {
+ super(profileId);
+
+ requireSignedAssertionsPredicate = PredicateSupport.alwaysFalse();
+ assertionLifetimeLookupStrategy = FunctionSupport.constant(null);
+ additionalAudiencesLookupStrategy = FunctionSupport.constant(null);
+ }
+
+ /** {@inheritDoc} */
+ public boolean isRequireSignedAssertions(@Nullable final ProfileRequestContext profileRequestContext) {
+ return requireSignedAssertionsPredicate.test(profileRequestContext);
+ }
+
+ /**
+ * Set whether to require signed assertions.
+ *
+ * @param flag flag to set
+ */
+ public void setRequireSignedAssertions(final boolean flag) {
+ requireSignedAssertionsPredicate = PredicateSupport.constant(flag);
+ }
+
+ /**
+ * Set condition to determine whether to require signed assertions.
+ *
+ * @param condition condition to set
+ */
+ public void setRequireSignedAssertionsPredicate(@Nonnull final Predicate<ProfileRequestContext> condition) {
+ requireSignedAssertionsPredicate = Constraint.isNotNull(condition, "Condition cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Nullable @NonNegative public Duration getAssertionLifetime(@Nullable final ProfileRequestContext profileRequestContext) {
+ final Duration lifetime = assertionLifetimeLookupStrategy.apply(profileRequestContext);
+ if (lifetime != null) {
+ Constraint.isFalse(lifetime.isNegative(), "Assertion lifetime must be non-negative");
+ }
+ return lifetime;
+ }
+
+ /**
+ * Set the maximum lifetime of an assertion.
+ *
+ * @param lifetime lifetime of an assertion
+ */
+ public void setAssertionLifetime(@Nullable @NonNegative final Duration lifetime) {
+ if (lifetime != null) {
+ Constraint.isFalse(lifetime.isNegative(), "Assertion lifetime must be non-negative");
+ }
+
+ assertionLifetimeLookupStrategy = FunctionSupport.constant(lifetime);
+ }
+
+ /**
+ * Set a lookup strategy for the maximum lifetime of an assertion.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setAssertionLifetimeLookupStrategy(@Nonnull final Function<ProfileRequestContext,Duration> strategy) {
+ assertionLifetimeLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Nonnull @NonnullElements @NotLive public Set<String> getAdditionalAudiences(
+ @Nullable final ProfileRequestContext profileRequestContext) {
+
+ final Set<String> audiences = additionalAudiencesLookupStrategy.apply(profileRequestContext);
+ if (audiences != null) {
+ return CollectionSupport.copyToSet(audiences);
+ }
+ return CollectionSupport.emptySet();
+ }
+
+ /**
+ * Set the set of audiences, in addition to our entityID, to validate the assertion against.
+ *
+ * @param audiences the additional audiences
+ */
+ public void setAdditionalAudiences(@Nullable @NonnullElements final Collection<String> audiences) {
+
+ if (audiences == null || audiences.isEmpty()) {
+ additionalAudiencesLookupStrategy = FunctionSupport.constant(null);
+ } else {
+ additionalAudiencesLookupStrategy = FunctionSupport.constant(
+ CollectionSupport.copyToSet(StringSupport.normalizeStringCollection(audiences)));
+ }
+ }
+
+ /**
+ * Set a lookup strategy for the set of audiences, in addition to our entityID, to validate the assertion against.
+ *
+ * @param strategy lookup strategy
+ *
+ * @since 4.0.0
+ */
+ public void setAdditionalAudiencesLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext,Set<String>> strategy) {
+ additionalAudiencesLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null");
+ }
+
+}
\ No newline at end of file
diff --git a/sp-saml-api/src/main/java/net/shibboleth/sp/saml2/config/AbstractSAML2ProfileConfiguration.java b/sp-saml-api/src/main/java/net/shibboleth/sp/saml2/config/AbstractSAML2ProfileConfiguration.java
new file mode 100644
index 0000000..677ed74
--- /dev/null
+++ b/sp-saml-api/src/main/java/net/shibboleth/sp/saml2/config/AbstractSAML2ProfileConfiguration.java
@@ -0,0 +1,183 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.sp.saml2.config;
+
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+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;
+import net.shibboleth.sp.config.AbstractConditionalProfileConfiguration;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+/** Base class for SAML profile configurations. */
+public abstract class AbstractSAML2ProfileConfiguration extends AbstractConditionalProfileConfiguration implements
+ SAML2ProfileConfiguration {
+
+ /** Function used to obtain our entityID. */
+ @Nonnull private Function<ProfileRequestContext,String> entityIDLookupStrategy;
+
+ /** Predicate used to determine if the generated request should be signed. Default returns false. */
+ @Nonnull private Predicate<ProfileRequestContext> signRequestsPredicate;
+
+ /** Predicate used to determine if the generated response should be signed. Default returns false. */
+ @Nonnull private Predicate<ProfileRequestContext> signResponsesPredicate;
+
+ /** Whether encryption is optional in the face of no key, etc. */
+ @Nonnull private Predicate<ProfileRequestContext> encryptionOptionalPredicate;
+
+ /** Predicate used to determine if name identifiers should be encrypted. */
+ @Nonnull private Predicate<ProfileRequestContext> encryptNameIDsPredicate;
+
+ /**
+ * Constructor.
+ *
+ * @param profileId ID of the communication profile
+ */
+ public AbstractSAML2ProfileConfiguration(@Nonnull @NotEmpty final String profileId) {
+ super(profileId);
+
+ entityIDLookupStrategy = FunctionSupport.constant(null);
+ signRequestsPredicate = PredicateSupport.alwaysFalse();
+ signResponsesPredicate = PredicateSupport.alwaysFalse();
+ encryptionOptionalPredicate = PredicateSupport.alwaysFalse();
+ encryptNameIDsPredicate = PredicateSupport.alwaysFalse();
+ }
+
+ /** {@inheritDoc} */
+ @Nullable @NotEmpty public String getEntityID(@Nullable final ProfileRequestContext profileRequestContext) {
+ return entityIDLookupStrategy.apply(profileRequestContext);
+ }
+
+ /**
+ * Set the entityID of this system.
+ *
+ * @param id entityID
+ */
+ public void setEntityID(@Nullable @NotEmpty final String id) {
+ entityIDLookupStrategy = FunctionSupport.constant(id);
+ }
+
+ /**
+ * Set the lookup strategy for the entityID of this system
+ *
+ * @param strategy lookup strategy
+ */
+ public void setEntityIDLookupStrategy(@Nonnull final Function<ProfileRequestContext,String> strategy) {
+ entityIDLookupStrategy = Constraint.isNotNull(strategy, "EntityID lookup strategy cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ public boolean isSignRequests(@Nullable final ProfileRequestContext profileRequestContext) {
+ return signRequestsPredicate.test(profileRequestContext);
+ }
+
+ /**
+ * Set whether generated requests should be signed.
+ *
+ * @param flag flag to set
+ */
+ public void setSignRequests(final boolean flag) {
+ signRequestsPredicate = PredicateSupport.constant(flag);
+ }
+
+ /**
+ * Set the predicate used to determine if generated requests should be signed.
+ *
+ * @param predicate predicate used to determine if generated requests should be signed
+ */
+ public void setSignRequestsPredicate(@Nonnull final Predicate<ProfileRequestContext> predicate) {
+ signRequestsPredicate = Constraint.isNotNull(predicate, "Condition cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ public boolean isSignResponses(@Nullable final ProfileRequestContext profileRequestContext) {
+ return signResponsesPredicate.test(profileRequestContext);
+ }
+
+ /**
+ * Set whether generated responses should be signed.
+ *
+ * @param flag flag to set
+ */
+ public void setSignResponses(final boolean flag) {
+ signResponsesPredicate = PredicateSupport.constant(flag);
+ }
+
+ /**
+ * Set the predicate used to determine if generated responses should be signed.
+ *
+ * @param predicate predicate used to determine if generated responses should be signed
+ */
+ public void setSignResponsesPredicate(@Nonnull final Predicate<ProfileRequestContext> predicate) {
+ signResponsesPredicate = Constraint.isNotNull(predicate, "Condition cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ public boolean isEncryptionOptional(@Nullable final ProfileRequestContext profileRequestContext) {
+ return encryptionOptionalPredicate.test(profileRequestContext);
+ }
+
+ /**
+ * Set whether encryption is optional in the face of a missing key, etc.
+ *
+ * @param flag flag to set
+ */
+ public void setEncryptionOptional(final boolean flag) {
+ encryptionOptionalPredicate = PredicateSupport.constant(flag);
+ }
+
+ /**
+ * Set a condition to determine whether encryption is optional in the face of a missing key, etc.
+ *
+ * @param condition condition to set
+ */
+ public void setEncryptionOptionalPredicate(@Nonnull final Predicate<ProfileRequestContext> condition) {
+ encryptionOptionalPredicate = Constraint.isNotNull(condition, "Encryption optional predicate cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ public boolean isEncryptNameIDs(@Nullable final ProfileRequestContext profileRequestContext) {
+ return encryptNameIDsPredicate.test(profileRequestContext);
+ }
+
+ /**
+ * Set whether name identifiers should be encrypted.
+ *
+ * @param flag flag to set
+ */
+ public void setEncryptNameIDs(final boolean flag) {
+ encryptNameIDsPredicate = PredicateSupport.constant(flag);
+ }
+
+ /**
+ * Set the predicate used to determine if name identifiers should be encrypted.
+ *
+ * @param predicate predicate used to determine if name identifiers should be encrypted
+ */
+ public void setEncryptNameIDsPredicate(@Nonnull final Predicate<ProfileRequestContext> predicate) {
+ encryptNameIDsPredicate = Constraint.isNotNull(predicate, "Condition cannot be null");
+ }
+
+}
\ No newline at end of file
diff --git a/sp-saml-api/src/main/java/net/shibboleth/sp/saml2/config/BrowserSSOProfileConfiguration.java b/sp-saml-api/src/main/java/net/shibboleth/sp/saml2/config/BrowserSSOProfileConfiguration.java
new file mode 100644
index 0000000..73d6578
--- /dev/null
+++ b/sp-saml-api/src/main/java/net/shibboleth/sp/saml2/config/BrowserSSOProfileConfiguration.java
@@ -0,0 +1,501 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.sp.saml2.config;
+
+import java.time.Duration;
+import java.util.Collection;
+import java.util.List;
+import java.util.function.BiConsumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import net.shibboleth.shared.annotation.constraint.NonNegative;
+import net.shibboleth.shared.annotation.constraint.NonnullElements;
+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 org.opensaml.profile.context.ProfileRequestContext;
+import org.opensaml.saml.saml2.core.AuthnContextClassRef;
+import org.opensaml.saml.saml2.core.AuthnContextComparisonTypeEnumeration;
+import org.opensaml.saml.saml2.core.AuthnRequest;
+import org.opensaml.saml.saml2.core.SubjectLocality;
+import org.opensaml.saml.saml2.metadata.RequestedAttribute;
+
+/** Configuration support for SAML 2 Browser SSO. */
+public class BrowserSSOProfileConfiguration extends AbstractSAML2AssertionConsumerProfileConfiguration
+ implements SAML2ArtifactConsumerProfileConfiguration {
+
+ /** ID for this profile configuration. */
+ @Nonnull @NotEmpty public static final String PROFILE_ID = "http://shibboleth.net/ns/profiles/saml2/sso/browser";
+
+ /** Bit constant for RequestedAuthnContext feature. */
+ public static final int FEATURE_AUTHNCONTEXT = 0x1;
+
+ /** Bit constant for NameIDPolicy Format feature. */
+ public static final int FEATURE_NAMEIDFORMAT = 0x2;
+
+ /** Bit constant for NameIDPolicy SPNameQualifier feature. */
+ public static final int FEATURE_SPNAMEQUALIFIER = 0x4;
+
+ /** Bit constant for ForceAuthn feature. */
+ public static final int FEATURE_FORCEAUTHN = 0x8;
+
+ /** Whether to mandate forced authentication for the request. */
+ @Nonnull private Predicate<ProfileRequestContext> forceAuthnPredicate;
+
+ /** Whether to compare client and assertion addresses on inbound SSO. */
+ @Nonnull private Predicate<ProfileRequestContext> checkAddressPredicate;
+
+ /** Lookup function to supply maximum time since inbound AuthnInstant. */
+ @Nonnull private Function<ProfileRequestContext,Duration> maximumTimeSinceAuthnLookupStrategy;
+
+ /** Lookup function to supply ProxyCount. */
+ @Nonnull private Function<ProfileRequestContext,Integer> proxyCountLookupStrategy;
+
+ /** Lookup function for requested AC operator. */
+ @Nonnull private Function<ProfileRequestContext,String> authnContextComparisonLookupStrategy;
+
+ /** Lookup function to supply default authentication methods. */
+ @Nonnull private Function<ProfileRequestContext,Collection<String>> authnContextClassRefLookupStrategy;
+
+ /** Lookup function to supply NameID format. */
+ @Nonnull private Function<ProfileRequestContext,String> nameIDFormatLookupStrategy;
+
+ /** Lookup function to supply SPNameQualifier. */
+ @Nonnull private Function<ProfileRequestContext,String> nameQualifierLookupStrategy;
+
+ /** Lookup function to supply AttributeConsumingServiceIndex. */
+ @Nonnull private Function<ProfileRequestContext,String> attributeIndexLookupStrategy;
+
+ /** Lookup function to supply RequestedAttributes. */
+ @Nonnull private Function<ProfileRequestContext,Collection<RequestedAttribute>> requestedAttributesLookupStrategy;
+
+ /** Lookup function to supply a decorator for the {@link AuthnRequest}. */
+ @Nonnull private Function<ProfileRequestContext,BiConsumer<ProfileRequestContext,AuthnRequest>>
+ requestDecoratorLookupStrategy;
+
+ /** Constructor. */
+ public BrowserSSOProfileConfiguration() {
+ this(PROFILE_ID);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param profileId unique ID for this profile
+ */
+ protected BrowserSSOProfileConfiguration(@Nonnull @NotEmpty final String profileId) {
+ super(profileId);
+ setEncryptNameIDs(true);
+ forceAuthnPredicate = PredicateSupport.alwaysFalse();
+ checkAddressPredicate = PredicateSupport.alwaysTrue();
+ maximumTimeSinceAuthnLookupStrategy = FunctionSupport.constant(null);
+ proxyCountLookupStrategy = FunctionSupport.constant(null);
+ authnContextComparisonLookupStrategy = FunctionSupport.constant(null);
+ authnContextClassRefLookupStrategy = FunctionSupport.constant(null);
+ nameIDFormatLookupStrategy = FunctionSupport.constant(null);
+ nameQualifierLookupStrategy = FunctionSupport.constant(null);
+ attributeIndexLookupStrategy = FunctionSupport.constant(null);
+ requestedAttributesLookupStrategy = FunctionSupport.constant(null);
+ requestDecoratorLookupStrategy = FunctionSupport.constant(null);
+ }
+
+ /**
+ * Get whether a fresh user presence proof should be required for this request.
+ *
+ * @param profileRequestContext current profile request context
+ *
+ * @return true iff a fresh user presence proof should be required for this request
+ */
+ public boolean isForceAuthn(@Nullable final ProfileRequestContext profileRequestContext) {
+ return forceAuthnPredicate.test(profileRequestContext);
+ }
+
+ /**
+ * Set whether a fresh user presence proof should be required for this request.
+ *
+ * @param flag flag to set
+ */
+ public void setForceAuthn(final boolean flag) {
+ forceAuthnPredicate = PredicateSupport.constant(flag);
+ }
+
+ /**
+ * Set a condition to determine whether a fresh user presence proof should be required for this request.
+ *
+ * @param condition condition to set
+ */
+ public void setForceAuthnPredicate(@Nonnull final Predicate<ProfileRequestContext> condition) {
+ forceAuthnPredicate = Constraint.isNotNull(condition, "Forced authentication predicate cannot be null");
+ }
+
+ /**
+ * Get whether the client's address must match the address in an inbound {@link SubjectLocality}
+ * element during inbound SSO.
+ *
+ * @param profileRequestContext current profile request context
+ *
+ * @return whether to compare addresses
+ */
+ public boolean isCheckAddress(@Nullable final ProfileRequestContext profileRequestContext) {
+ return checkAddressPredicate.test(profileRequestContext);
+ }
+
+ /**
+ * Set whether the client's address must match the address in an inbound {@link SubjectLocality}
+ * element during inbound SSO.
+ *
+ * @param flag flag to set
+ */
+ public void setCheckAddress(final boolean flag) {
+ checkAddressPredicate = PredicateSupport.constant(flag);
+ }
+
+ /**
+ * Set a condition to determine whether the client's address must match the address in an inbound
+ * {@link SubjectLocality} element during inbound SSO.
+ *
+ * @param condition condition to set
+ */
+ public void setCheckAddressPredicate(@Nonnull final Predicate<ProfileRequestContext> condition) {
+ checkAddressPredicate = Constraint.isNotNull(condition, "Address checking predicate cannot be null");
+ }
+
+ /**
+ * Get the maximum amount of time allowed to have elapsed since an incoming AuthnInstant.
+ *
+ * <p>A null or 0 is interpreted as an unlimited amount.</p>
+ *
+ * @param profileRequestContext current profile request context
+ *
+ * @return max time since inbound AuthnInstant
+ */
+ @Nullable public Duration getMaximumTimeSinceAuthn(@Nullable final ProfileRequestContext profileRequestContext) {
+ final Duration amount = maximumTimeSinceAuthnLookupStrategy.apply(profileRequestContext);
+ Constraint.isFalse(amount != null && amount.isNegative(),
+ "Maximum time since authentication must be greater than or equal to 0");
+ return amount;
+ }
+
+ /**
+ * Set the maximum amount of time allowed to have elapsed since an incoming AuthnInstant.
+ *
+ * <p>A null or 0 is interpreted as an unlimited amount.</p>
+ *
+ * @param amount max time to allow
+ */
+ public void setMaximumTimeSinceAuthn(@Nullable final Duration amount) {
+ Constraint.isFalse(amount != null && amount.isNegative(),
+ "Maximum time since authentication must be greater than or equal to 0");
+
+ maximumTimeSinceAuthnLookupStrategy = FunctionSupport.constant(amount);
+ }
+
+ /**
+ * Set a lookup strategy for the maximum amount of time allowed to have elapsed since an incoming AuthnInstant.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setMaximumTimeSinceAuthnLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext,Duration> strategy) {
+ maximumTimeSinceAuthnLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null");
+ }
+
+ /**
+ * Gets the maximum number of times an assertion may be proxied to signal in the SAML request.
+ *
+ * @param profileRequestContext current profile request context
+ *
+ * @return maximum number of times an assertion may be proxied
+ */
+ @NonNegative @Nullable Integer getProxyCount(@Nullable final ProfileRequestContext profileRequestContext) {
+ final Integer count = proxyCountLookupStrategy.apply(profileRequestContext);
+ if (count != null) {
+ Constraint.isGreaterThanOrEqual(0, count, "Proxy count must be greater than or equal to 0");
+ }
+ return count;
+ }
+
+ /**
+ * Set the maximum number of times an assertion may be proxied to signal in the SAML request.
+ *
+ * @param count maximum number of times an assertion may be proxied
+ */
+ public void setProxyCount(@Nullable @NonNegative final Integer count) {
+ if (count != null) {
+ Constraint.isGreaterThanOrEqual(0, count, "Proxy count must be greater than or equal to 0");
+ }
+ proxyCountLookupStrategy = FunctionSupport.constant(count);
+ }
+
+ /**
+ * Set a lookup strategy for the maximum number of times an assertion may be proxied to signal
+ * in the SAML request.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setProxyCountLookupStrategy(@Nonnull final Function<ProfileRequestContext,Integer> strategy) {
+ proxyCountLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null");
+ }
+
+ /**
+ * Get the comparison operator to use when issuing SAML requests containing requested context classes.
+ *
+ * @param profileRequestContext profile request context
+ *
+ * @return comparison value or null
+ */
+ @Nullable public AuthnContextComparisonTypeEnumeration getAuthnContextComparison(
+ @Nullable final ProfileRequestContext profileRequestContext) {
+
+ final String comparison = authnContextComparisonLookupStrategy.apply(profileRequestContext);
+ if (comparison != null) {
+ return AuthnContextComparisonTypeEnumeration.valueOf(comparison.toUpperCase());
+ }
+
+ return null;
+ }
+
+ /**
+ * Set the comparison operator to use when issuing SAML requests containing requested context classes.
+ *
+ * @param comparison comparison value or null
+ *
+ * @since 4.0.0
+ */
+ public void setAuthnContextComparison(@Nullable final AuthnContextComparisonTypeEnumeration comparison) {
+ authnContextComparisonLookupStrategy =
+ FunctionSupport.constant(comparison != null ? comparison.toString() : null);
+ }
+
+ /**
+ * Set a lookup strategy for the comparison operator to use when issuing SAML requests containing
+ * requested context classes.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setAuthnContextComparisonLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext,String> strategy) {
+ authnContextComparisonLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null");
+ }
+
+ /**
+ * Get the {@link AuthnContextClassRef} values to include in SAML request.
+ *
+ * @param profileRequestContext current profile request context
+ *
+ * @return list of class references
+ */
+ @Nonnull @NonnullElements @NotLive @Unmodifiable public List<String> getAuthnContextClassRefs(
+ @Nullable final ProfileRequestContext profileRequestContext) {
+ final Collection<String> refs = authnContextClassRefLookupStrategy.apply(profileRequestContext);
+ if (refs != null) {
+ return CollectionSupport.copyToList(refs);
+ }
+ return CollectionSupport.emptyList();
+ }
+
+ /**
+ * Set the {@link AuthnContextClassRef} values to include in SAML request.
+ *
+ * @param contexts default authentication context class references to use
+ */
+ public void setAuthnContextClassRefs(@Nullable @NonnullElements final Collection<String> contexts) {
+ if (contexts != null) {
+ authnContextClassRefLookupStrategy = FunctionSupport.constant(CollectionSupport.copyToList(contexts));
+ } else {
+ authnContextClassRefLookupStrategy = FunctionSupport.constant(null);
+ }
+ }
+
+ /**
+ * Set a lookup strategy for the {@link AuthnContextClassRef} values to include in SAML request.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setAuthnContextClassRefsLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext,Collection<String>> strategy) {
+ authnContextClassRefLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null");
+ }
+
+ /**
+ * Get the name identifier format to require via the SAML request.
+ *
+ * @param profileRequestContext current profile request context
+ *
+ * @return required format
+ */
+ @Nullable public String getNameIDFormat(@Nullable final ProfileRequestContext profileRequestContext) {
+ return nameIDFormatLookupStrategy.apply(profileRequestContext);
+ }
+
+ /**
+ * Set the name identifier format to require via the SAML request.
+ *
+ * @param format required format
+ */
+ public void setNameIDFormat(@Nullable final String format) {
+ nameIDFormatLookupStrategy = FunctionSupport.constant(format);
+ }
+
+ /**
+ * Set a lookup strategy for the name identifier format to require via the SAML request.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setNameIDFormatLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext,String> strategy) {
+ nameIDFormatLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null");
+ }
+
+ /**
+ * Get the SPNameQualifier to include in the SAML request.
+ *
+ * @param profileRequestContext current profile request context
+ *
+ * @return requested SPNameQualifier
+ */
+ @Nullable public String getNameQualifier(@Nullable final ProfileRequestContext profileRequestContext) {
+ return nameQualifierLookupStrategy.apply(profileRequestContext);
+ }
+
+ /**
+ * Set the SPNameQualifier to include in the SAML request.
+ *
+ * @param qualifier requested SPNameQualifier
+ */
+ public void setNameQualifier(@Nullable final String qualifier) {
+ nameQualifierLookupStrategy = FunctionSupport.constant(qualifier);
+ }
+
+ /**
+ * Set a lookup strategy for the SPNameQualifier to include in the SAML request.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setNameQualifierLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext,String> strategy) {
+ nameQualifierLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null");
+ }
+
+ /**
+ * Get the AttributeConsumingServiceIndex to include in the SAML request.
+ *
+ * @param profileRequestContext current profile request context
+ *
+ * @return the AttributeConsumingServiceIndex
+ */
+ @Nullable public String getAttributeIndex(@Nullable final ProfileRequestContext profileRequestContext) {
+ return attributeIndexLookupStrategy.apply(profileRequestContext);
+ }
+
+ /**
+ * Set the AttributeConsumingServiceIndex to include in the SAML request.
+ *
+ * @param index the AttributeConsumingServiceIndex
+ */
+ public void setAttributeIndex(@Nullable final String index) {
+ attributeIndexLookupStrategy = FunctionSupport.constant(index);
+ }
+
+ /**
+ * Set a lookup strategy for the AttributeConsumingServiceIndex to include in the SAML request.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setAttributeIndexLookupStrategy(@Nonnull final Function<ProfileRequestContext,String> strategy) {
+ attributeIndexLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null");
+ }
+
+ /**
+ * Get the list of {@link RequestedAttribute} objects to include in the SAML request (via extension).
+ *
+ * @param profileRequestContext current profile request context
+ *
+ * @return the requested attributes
+ */
+ @Nonnull @NonnullElements @Unmodifiable @NotLive public Collection<RequestedAttribute> getRequestedAttributes(
+ @Nullable final ProfileRequestContext profileRequestContext) {
+ final Collection<RequestedAttribute> attrs = requestedAttributesLookupStrategy.apply(profileRequestContext);
+ if (attrs != null) {
+ return CollectionSupport.copyToList(attrs);
+ } else {
+ return CollectionSupport.emptyList();
+ }
+ }
+
+ /**
+ * Set the list of {@link RequestedAttribute} objects to include in the SAML request (via extension).
+ *
+ * @param attrs requested attributes
+ */
+ public void setRequestedAttributes(@Nullable @NonnullElements final Collection<RequestedAttribute> attrs) {
+ requestedAttributesLookupStrategy = FunctionSupport.constant(attrs);
+ }
+
+ /**
+ * Set a lookup strategy for the list of {@link RequestedAttribute} objects to include in the SAML request
+ * (via extension).
+ *
+ * @param strategy lookup strategy
+ */
+ public void setRequestedAttributesLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext,Collection<RequestedAttribute>> strategy) {
+ requestedAttributesLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null");
+ }
+
+ /**
+ * Get a decorator for the SAML request.
+ *
+ * @param profileRequestContext current profile request context
+ *
+ * @return request decorator
+ */
+ @Nullable public BiConsumer<ProfileRequestContext,AuthnRequest> getRequestDecorator(
+ @Nullable final ProfileRequestContext profileRequestContext) {
+ return requestDecoratorLookupStrategy.apply(profileRequestContext);
+ }
+
+ /**
+ * Set a decorator for the SAML request.
+ *
+ * @param decorator request decorator
+ */
+ public void setRequestDecorator(@Nullable final BiConsumer<ProfileRequestContext,AuthnRequest> decorator) {
+ requestDecoratorLookupStrategy = FunctionSupport.constant(decorator);
+ }
+
+ /**
+ * Set a lookup strategy for a decorator for the SAML request.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setRequestDecoratorLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext,BiConsumer<ProfileRequestContext,AuthnRequest>> strategy) {
+ requestDecoratorLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null");
+ }
+
+}
\ No newline at end of file
diff --git a/sp-saml-api/src/main/java/net/shibboleth/sp/saml2/config/SAML2ArtifactConsumerProfileConfiguration.java b/sp-saml-api/src/main/java/net/shibboleth/sp/saml2/config/SAML2ArtifactConsumerProfileConfiguration.java
new file mode 100644
index 0000000..558b3e7
--- /dev/null
+++ b/sp-saml-api/src/main/java/net/shibboleth/sp/saml2/config/SAML2ArtifactConsumerProfileConfiguration.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.sp.saml2.config;
+
+import javax.annotation.Nullable;
+
+import org.opensaml.messaging.context.MessageContext;
+
+/**
+ * Common interface for SAML profile configurations involving artifact consumption, for example artifact
+ * resolution requests.
+ *
+ * <p>This is {@link MessageContext}-driven.</p>
+ */
+public interface SAML2ArtifactConsumerProfileConfiguration extends SAML2ProfileConfiguration {
+
+ /**
+ * Get whether artifact resolution requests should be signed.
+ *
+ * @param messageContext current message context
+ *
+ * @return whether artifact resolution requests should be signed
+ */
+ boolean isSignArtifactRequests(@Nullable final MessageContext messageContext);
+
+ /**
+ * Get whether artifact resolution requests should use client TLS.
+ *
+ * @param messageContext current message context
+ *
+ * @return whether artifact resolution requests should use client TLS
+ */
+ boolean isClientTLSArtifactRequests(@Nullable final MessageContext messageContext);
+
+}
\ No newline at end of file
diff --git a/sp-saml-api/src/main/java/net/shibboleth/sp/saml2/config/SAML2AssertionConsumerProfileConfiguration.java b/sp-saml-api/src/main/java/net/shibboleth/sp/saml2/config/SAML2AssertionConsumerProfileConfiguration.java
new file mode 100644
index 0000000..f505491
--- /dev/null
+++ b/sp-saml-api/src/main/java/net/shibboleth/sp/saml2/config/SAML2AssertionConsumerProfileConfiguration.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.sp.saml2.config;
+
+import java.time.Duration;
+import java.util.Set;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import net.shibboleth.shared.annotation.constraint.NonNegative;
+import net.shibboleth.shared.annotation.constraint.NonnullElements;
+import net.shibboleth.shared.annotation.constraint.NotLive;
+import net.shibboleth.shared.annotation.constraint.Unmodifiable;
+
+/**
+ * Interface for configuration of profiles that consume SAML Assertions.
+ */
+public interface SAML2AssertionConsumerProfileConfiguration extends SAML2ProfileConfiguration {
+
+ /**
+ * Get the predicate used to determine if assertions must be signed.
+ *
+ * @param profileRequestContext current profile request context
+ *
+ * @return predicate used to determine if assertions must be signed
+ */
+ boolean isRequireSignedAssertions(@Nullable final ProfileRequestContext profileRequestContext);
+
+ /**
+ * Get the maximum lifetime of the assertions.
+ *
+ * @param profileRequestContext current profile request context
+ *
+ * @return maximum lifetime of the assertions
+ */
+ @Nullable @NonNegative Duration getAssertionLifetime(@Nullable final ProfileRequestContext profileRequestContext);
+
+ /**
+ * Get set of audiences to include when validating assertion, in addition to our own entityID.
+ *
+ * @param profileRequestContext current profile request context
+ *
+ * @return additional audiences
+ */
+ @Nonnull @NonnullElements @NotLive @Unmodifiable Set<String> getAdditionalAudiences(
+ @Nullable final ProfileRequestContext profileRequestContext);
+
+}
\ No newline at end of file
diff --git a/sp-saml-api/src/main/java/net/shibboleth/sp/saml2/config/SAML2ProfileConfiguration.java b/sp-saml-api/src/main/java/net/shibboleth/sp/saml2/config/SAML2ProfileConfiguration.java
new file mode 100644
index 0000000..3511804
--- /dev/null
+++ b/sp-saml-api/src/main/java/net/shibboleth/sp/saml2/config/SAML2ProfileConfiguration.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.sp.saml2.config;
+
+import javax.annotation.Nullable;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.sp.config.ProfileConfiguration;
+
+/** Common interface for SAML 2.0 profile configurations. */
+public interface SAML2ProfileConfiguration extends ProfileConfiguration {
+
+ /**
+ * Get the entityID assigned to this system.
+ *
+ * @param profileRequestContext current profile request context
+ *
+ * @return our own entityID
+ */
+ @Nullable @NotEmpty String getEntityID(@Nullable final ProfileRequestContext profileRequestContext);
+
+ /**
+ * Get the predicate used to determine if generated requests should be signed.
+ *
+ * @param profileRequestContext current profile request context
+ *
+ * @return predicate used to determine if generated requests should be signed
+ */
+ boolean isSignRequests(@Nullable final ProfileRequestContext profileRequestContext);
+
+ /**
+ * Get the predicate used to determine if generated responses should be signed.
+ *
+ * @param profileRequestContext current profile request context
+ *
+ * @return predicate used to determine if generated responses should be signed
+ */
+ boolean isSignResponses(@Nullable final ProfileRequestContext profileRequestContext);
+
+ /**
+ * Gets whether to ignore an inability to encrypt due to external factors.
+ *
+ * <p>This allows a deployer to signal that encryption is "best effort" and
+ * can be omitted if an asserting party doesn't possess a key, support a compatible
+ * algorithm, etc.</p>
+ *
+ * <p>Defaults to false.</p>
+ *
+ * @param profileRequestContext current profile request context
+ *
+ * @return true iff encryption should be treated as optional
+ */
+ boolean isEncryptionOptional(@Nullable final ProfileRequestContext profileRequestContext);
+
+ /**
+ * Gets the predicate used to determine if name identifiers should be encrypted.
+ *
+ * @param profileRequestContext current profile request context
+ *
+ * @return predicate used to determine if name identifiers should be encrypted
+ */
+ boolean isEncryptNameIDs(@Nullable final ProfileRequestContext profileRequestContext);
+
+}
\ No newline at end of file
diff --git a/sp-server-api/src/main/java/net/shibboleth/sp/config/ProfileConfiguration.java b/sp-saml-api/src/main/java/net/shibboleth/sp/saml2/config/package-info.java
similarity index 53%
copy from sp-server-api/src/main/java/net/shibboleth/sp/config/ProfileConfiguration.java
copy to sp-saml-api/src/main/java/net/shibboleth/sp/saml2/config/package-info.java
index 0f5f78c..09937f8 100644
--- a/sp-server-api/src/main/java/net/shibboleth/sp/config/ProfileConfiguration.java
+++ b/sp-saml-api/src/main/java/net/shibboleth/sp/saml2/config/package-info.java
@@ -15,28 +15,7 @@
* limitations under the License.
*/
-package net.shibboleth.sp.config;
-
-import javax.annotation.Nullable;
-
-import org.opensaml.profile.context.ProfileRequestContext;
-import org.opensaml.security.config.SecurityConfiguration;
-
-import net.shibboleth.shared.component.IdentifiedComponent;
-
/**
- * Interface for profile-specific configuration used to customize SP behavior.
+ * Configuration of SAML support in SP.
*/
-public interface ProfileConfiguration extends IdentifiedComponent {
-
- /**
- * Gets the applicable {@link SecurityConfiguration}.
- *
- * @param profileRequestContext profile request context
- *
- * @return the profile's security configuration
- */
- @Nullable SecurityConfiguration getSecurityConfiguration(
- @Nullable final ProfileRequestContext profileRequestContext);
-
-}
\ No newline at end of file
+package net.shibboleth.sp.saml2.config;
\ No newline at end of file
diff --git a/sp-server-api/src/main/java/net/shibboleth/sp/config/AbstractProfileConfiguration.java b/sp-server-api/src/main/java/net/shibboleth/sp/config/AbstractProfileConfiguration.java
index 9b7567a..2a0b713 100644
--- a/sp-server-api/src/main/java/net/shibboleth/sp/config/AbstractProfileConfiguration.java
+++ b/sp-server-api/src/main/java/net/shibboleth/sp/config/AbstractProfileConfiguration.java
@@ -36,9 +36,15 @@ import org.opensaml.security.config.SecurityConfiguration;
public abstract class AbstractProfileConfiguration extends AbstractIdentifiableInitializableComponent
implements ProfileConfiguration {
+ /** Default value for disallowedFeatures property. */
+ @Nonnull public static final Integer DEFAULT_DISALLOWED_FEATURES = 0;
+
/** Lookup function to supply securityConfiguration property. */
@Nonnull private Function<ProfileRequestContext,SecurityConfiguration> securityConfigurationLookupStrategy;
+ /** Lookup function to return a bitmask of request features to disallow. */
+ @Nonnull private Function<ProfileRequestContext,Integer> disallowedFeaturesLookupStrategy;
+
/**
* Constructor.
*
@@ -47,6 +53,7 @@ public abstract class AbstractProfileConfiguration extends AbstractIdentifiableI
public AbstractProfileConfiguration(@Nonnull @NotEmpty @ParameterName(name="id") final String id) {
setId(id);
securityConfigurationLookupStrategy = FunctionSupport.constant(null);
+ disallowedFeaturesLookupStrategy = FunctionSupport.constant(DEFAULT_DISALLOWED_FEATURES);
}
/** {@inheritDoc} */
@@ -76,6 +83,35 @@ public abstract class AbstractProfileConfiguration extends AbstractIdentifiableI
securityConfigurationLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null");
}
+ /** {@inheritDoc} */
+ public boolean isFeatureDisallowed(@Nullable final ProfileRequestContext profileRequestContext, final int feature) {
+ return (getDisallowedFeatures(profileRequestContext) & feature) == feature;
+ }
+
+ /** {@inheritDoc} */
+ public int getDisallowedFeatures(@Nullable final ProfileRequestContext profileRequestContext) {
+ final Integer mask = disallowedFeaturesLookupStrategy.apply(profileRequestContext);
+ return mask != null ? mask : DEFAULT_DISALLOWED_FEATURES;
+ }
+
+ /**
+ * Set a bitmask of disallowed features to block.
+ *
+ * @param mask a bitmask of features to block
+ */
+ public void setDisallowedFeatures(final int mask) {
+ disallowedFeaturesLookupStrategy = FunctionSupport.constant(mask);
+ }
+
+ /**
+ * Set a lookup strategy for the bitmask of disallowed features to block.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setDisallowedFeaturesLookupStrategy(@Nonnull final Function<ProfileRequestContext,Integer> strategy) {
+ disallowedFeaturesLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null");
+ }
+
/** {@inheritDoc} */
@Override
public int hashCode() {
diff --git a/sp-server-api/src/main/java/net/shibboleth/sp/config/ProfileConfiguration.java b/sp-server-api/src/main/java/net/shibboleth/sp/config/ProfileConfiguration.java
index 0f5f78c..13bc699 100644
--- a/sp-server-api/src/main/java/net/shibboleth/sp/config/ProfileConfiguration.java
+++ b/sp-server-api/src/main/java/net/shibboleth/sp/config/ProfileConfiguration.java
@@ -38,5 +38,26 @@ public interface ProfileConfiguration extends IdentifiedComponent {
*/
@Nullable SecurityConfiguration getSecurityConfiguration(
@Nullable final ProfileRequestContext profileRequestContext);
+
+ /**
+ * Get a bitmask of disallowed features to block.
+ *
+ * <p>Individual profiles define their own feature constants.</p>
+ *
+ * @param profileRequestContext current profile request context
+ *
+ * @return bitmask of features to block
+ */
+ public int getDisallowedFeatures(@Nullable final ProfileRequestContext profileRequestContext);
+
+ /**
+ * Return true iff the input feature constant is disallowed.
+ *
+ * @param profileRequestContext current profile request context
+ * @param feature a bit constant
+ *
+ * @return true iff the input feature constant is disallowed
+ */
+ public boolean isFeatureDisallowed(@Nullable final ProfileRequestContext profileRequestContext, final int feature);
}
\ No newline at end of file
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list