[java-idp-oidc] branch main updated: JOIDC-196 - Enhance metadata and unregistered client policy config options
Henri Mikkonen
henri.mikkonen at iki.fi
Thu Feb 15 11:28:12 UTC 2024
This is an automated email from the git hooks/post-receive script.
hjmikkon pushed a commit to branch main
in repository java-idp-oidc.
View the commit online:
http://git.shibboleth.net/view/?p=java-idp-oidc.git;a=commit;h=efbb3313dd26b94f83c1d97ba86710ff23f9c14d
The following commit(s) were added to refs/heads/main by this push:
new efbb3313 JOIDC-196 - Enhance metadata and unregistered client policy config options
efbb3313 is described below
commit efbb3313dd26b94f83c1d97ba86710ff23f9c14d
Author: Henri Mikkonen <henri.mikkonen at iki.fi>
AuthorDate: Thu Feb 15 13:22:15 2024 +0200
JOIDC-196 - Enhance metadata and unregistered client policy config options
https://shibboleth.atlassian.net/browse/JOIDC-196
- The default map of custom metadata policy operators: shibboleth.oidc.DefaultMetadataPolicyCustomOperators
- contains the 'bean' operator in addition to the standard ones
- The configuration beans for the unregistered client policies:
- shibboleth.oidc.DefaultUnregisteredClientPolicyValidator - can be replaced via shibboleth.oidc.UnregisteredClientPolicyValidator
- shibboleth.oidc.DefaultUnregisteredClientPolicyEnforcer - can be replaced via shibboleth.oidc.UnregisteredClientPolicyEnforcer
- The default map of policy operators can be replaced via shibboleth.oidc.UnregisteredClientPolicyCustomOperators
- The configuration beans for the metadata policies used in dynamic client registration:
- shibboleth.oidc.dynreg.DefaultMetadataPolicyValidator - can be replaced via shibboleth.oidc.dynreg.MetadataPolicyValidator
- shibboleth.oidc.dynreg.DefaultMetadataPolicyEnforcer - can be replaced via shibboleth.oidc.dynreg.MetadataPolicyEnforcer
- The default map of policy operators can be replaced via shibboleth.oidc.dynreg.MetadataPolicyCustomOperators
- Refactored ValidateResponseType to apply policy enforcer directly to the requested value
- Deprecated DefaultUnregisteredClientResponseTypesLookupFunction
TODO: custom operators with registration access token + merging with the profile policy
---
.../oauth2/profile/impl/ValidateRedirectURI.java | 18 +++-
.../oauth2/profile/impl/ValidateResponseType.java | 88 +++++++++++-----
...nitializeRegistrationMetadataPolicyContext.java | 21 ++--
...registeredClientAllowedScopeLookupFunction.java | 30 +++++-
.../DefaultUnregisteredClientPolicyValidator.java | 41 ++++----
...egisteredClientResponseTypesLookupFunction.java | 2 +
.../META-INF/net.shibboleth.idp/postconfig.xml | 31 +++++-
.../oauth2/introspection/introspection-beans.xml | 3 +-
.../flows/oauth2/revocation/revocation-beans.xml | 3 +-
.../idp/flows/oidc/authorize/authorize-beans.xml | 14 +--
.../idp/flows/oidc/register/register-beans.xml | 7 +-
.../idp/flows/oidc/token/token-beans.xml | 6 +-
.../idp/flows/oidc/userinfo/userinfo-beans.xml | 3 +-
.../idp/service/relying-party/postconfig.xml | 3 -
.../profile/impl/ValidateRedirectURITest.java | 2 +
.../profile/impl/ValidateResponseTypeTest.java | 8 +-
.../AlwaysFalseCustomMetadataPolicyOperator.java | 33 ++++++
.../AlwaysTrueCustomMetadataPolicyOperator.java | 33 ++++++
.../oidc/op/profile/flow/RegistrationFlowTest.java | 20 ++++
...steredClientAllowedScopeLookupFunctionTest.java | 32 ++++++
...faultUnregisteredClientPolicyValidatorTest.java | 115 ++++++++++++++++++++-
.../net/shibboleth/idp/module/conf/global.xml | 4 +
.../idp/module/conf/metadata-policy-failing.json | 5 +
.../module/conf/metadata-policy-invalidbean.json | 5 +
.../shibboleth/idp/module/conf/relying-party.xml | 24 +++++
.../idp/module/conf/unregistered-policy.json | 3 +-
26 files changed, 470 insertions(+), 84 deletions(-)
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateRedirectURI.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateRedirectURI.java
index c6d3b719..69b47553 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateRedirectURI.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateRedirectURI.java
@@ -31,12 +31,14 @@ import net.shibboleth.idp.plugin.oidc.op.profile.context.navigate.DefaultRequest
import net.shibboleth.idp.plugin.oidc.op.profile.context.navigate.DefaultValidRedirectUrisLookupFunction;
import net.shibboleth.oidc.metadata.policy.MetadataPolicy;
import net.shibboleth.oidc.metadata.policy.UnregisteredClientPolicy;
-import net.shibboleth.oidc.metadata.policy.impl.DefaultMetadataPolicyEnforcer;
import net.shibboleth.oidc.profile.config.navigate.UnregisteredClientPolicyLookupFunction;
import net.shibboleth.oidc.profile.core.OidcEventIds;
+import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
import net.shibboleth.shared.annotation.constraint.NotEmpty;
import net.shibboleth.shared.collection.Pair;
+import net.shibboleth.shared.component.ComponentInitializationException;
import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.logic.ConstraintViolationException;
/**
* Action that validates redirect uri is expected. Validated redirect uri is stored to response context.
@@ -60,7 +62,7 @@ public class ValidateRedirectURI extends AbstractOAuthAuthorizationResponseActio
unregisteredClientPolicyLookupStrategy;
/** Enforcer function for validating redirect URI against the configured policy. */
- @Nonnull private BiFunction<Object, MetadataPolicy, Pair<Object, Boolean>> unregisteredClientPolicyEnforcer;
+ @NonnullAfterInit private BiFunction<Object, MetadataPolicy, Pair<Object, Boolean>> unregisteredClientPolicyEnforcer;
/** Whether to require redirect uri value in the request also when only single value is registered. */
private boolean requireRequestedValue = true;
@@ -73,7 +75,6 @@ public class ValidateRedirectURI extends AbstractOAuthAuthorizationResponseActio
validRedirectURIsLookupStrategy = new DefaultValidRedirectUrisLookupFunction();
registeredRedirectURIsLookupStrategy = new DefaultValidRedirectUrisLookupFunction();
unregisteredClientPolicyLookupStrategy = new UnregisteredClientPolicyLookupFunction();
- unregisteredClientPolicyEnforcer = new DefaultMetadataPolicyEnforcer();
}
/**
@@ -145,6 +146,15 @@ public class ValidateRedirectURI extends AbstractOAuthAuthorizationResponseActio
unregisteredClientPolicyEnforcer = Constraint.isNotNull(enforcer, "Unregistered client policy cannot be null");
}
+ /** {@inheritDoc} */
+ @Override
+ protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+ if (unregisteredClientPolicyEnforcer == null) {
+ throw new ConstraintViolationException("Unregistered client policy enforcer cannot be null");
+ }
+ }
+
/** {@inheritDoc} */
@Override
protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
@@ -205,7 +215,7 @@ public class ValidateRedirectURI extends AbstractOAuthAuthorizationResponseActio
* @param profileRequestContext profile request context
* @param validRedirectionURIs set of valid redirection uris
*/
- protected void handleNullRequestedURI(final ProfileRequestContext profileRequestContext,
+ protected void handleNullRequestedURI(@Nonnull final ProfileRequestContext profileRequestContext,
@Nonnull @NotEmpty final Set<URI> validRedirectionURIs) {
if (requireRequestedValue) {
log.warn("{} Redirection URI of the request not located for verification", getLogPrefix());
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateResponseType.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateResponseType.java
index 21fc6523..a44bbebe 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateResponseType.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateResponseType.java
@@ -14,7 +14,9 @@
package net.shibboleth.idp.plugin.oidc.op.oauth2.profile.impl;
+import java.util.Map;
import java.util.Set;
+import java.util.function.BiFunction;
import java.util.function.Function;
import javax.annotation.Nonnull;
@@ -23,18 +25,23 @@ import org.opensaml.profile.action.ActionSupport;
import org.opensaml.profile.context.ProfileRequestContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+
import com.nimbusds.oauth2.sdk.ResponseType;
-import net.shibboleth.idp.plugin.oidc.op.profile.logic.DefaultUnregisteredClientResponseTypesLookupFunction;
+import net.shibboleth.idp.profile.IdPEventIds;
import net.shibboleth.idp.plugin.oidc.op.profile.context.navigate.DefaultRequestResponseTypeLookupFunction;
import net.shibboleth.idp.plugin.oidc.op.profile.context.navigate.DefaultValidResponseTypesLookupFunction;
+import net.shibboleth.oidc.metadata.policy.MetadataPolicy;
+import net.shibboleth.oidc.metadata.policy.UnregisteredClientPolicy;
+import net.shibboleth.oidc.metadata.policy.impl.DefaultMetadataPolicyEnforcer;
+import net.shibboleth.oidc.profile.config.navigate.UnregisteredClientPolicyLookupFunction;
import net.shibboleth.oidc.profile.core.OidcEventIds;
-import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.collection.Pair;
import net.shibboleth.shared.logic.Constraint;
/**
- * An action that validates the requested response_type is (1) registered to the requesting RP and (2) valid for the
- * protocol used for request.
+ * An action that validates the requested response_type is (1) registered to the requesting RP (or accepted in the
+ * policy for unregistered clients) and (2) valid for the protocol used for request.
*/
public class ValidateResponseType extends AbstractOAuthAuthorizationResponseAction {
@@ -42,14 +49,17 @@ public class ValidateResponseType extends AbstractOAuthAuthorizationResponseActi
@Nonnull private Logger log = LoggerFactory.getLogger(ValidateResponseType.class);
/** Lookup strategy for fetching the requested response type. */
- @NonnullAfterInit private Function<ProfileRequestContext, ResponseType> requestedResponseTypeLookupStrategy;
+ @Nonnull private Function<ProfileRequestContext, ResponseType> requestedResponseTypeLookupStrategy;
/** Lookup strategy for fetching the valid response types matching the request message. */
- @NonnullAfterInit private Function<ProfileRequestContext, Set<ResponseType>> validResponseTypesLookupStrategy;
+ @Nonnull private Function<ProfileRequestContext, Set<ResponseType>> validResponseTypesLookupStrategy;
+
+ /** Strategy used to locate the unregistered client policy configured for the profile. */
+ @Nonnull private Function<ProfileRequestContext, Map<String, UnregisteredClientPolicy>>
+ unregisteredClientPolicyLookupStrategy;
- /** Lookup strategy for fetching the valid response types for unregistered clients. */
- @NonnullAfterInit private Function<ProfileRequestContext, Set<ResponseType>>
- unregisteredClientValidResponseTypesLookupStrategy;
+ /** Enforcer function for validating response type against the configured policy. */
+ @Nonnull private BiFunction<Object, MetadataPolicy, Pair<Object, Boolean>> unregisteredClientPolicyEnforcer;
/**
* Constructor.
@@ -57,8 +67,8 @@ public class ValidateResponseType extends AbstractOAuthAuthorizationResponseActi
public ValidateResponseType() {
requestedResponseTypeLookupStrategy = new DefaultRequestResponseTypeLookupFunction();
validResponseTypesLookupStrategy = new DefaultValidResponseTypesLookupFunction();
- unregisteredClientValidResponseTypesLookupStrategy =
- new DefaultUnregisteredClientResponseTypesLookupFunction();
+ unregisteredClientPolicyLookupStrategy = new UnregisteredClientPolicyLookupFunction();
+ unregisteredClientPolicyEnforcer = new DefaultMetadataPolicyEnforcer();
}
/**
@@ -84,30 +94,60 @@ public class ValidateResponseType extends AbstractOAuthAuthorizationResponseActi
}
/**
- * Set the lookup strategy for fetching the valid response types for unregistered clients.
+ * Set the strategy used to locate the unregistered client policy configured for the profile.
*
- * @param strategy What to set.
+ * @param strategy lookup strategy
*/
- public void setUnregisteredClientValidResponseTypesLookupStrategy(@Nonnull final
- Function<ProfileRequestContext, Set<ResponseType>> strategy) {
+ public void setUnregisteredClientPolicyLookupStrategy(
+ final Function<ProfileRequestContext, Map<String, UnregisteredClientPolicy>> strategy) {
checkSetterPreconditions();
- unregisteredClientValidResponseTypesLookupStrategy = Constraint.isNotNull(strategy,
- "Validation strategy cannot be null");
+
+ unregisteredClientPolicyLookupStrategy = Constraint.isNotNull(strategy,
+ "Unregistered client policy lookup strategy cannot be null");
+ }
+
+ /**
+ * Set the enforcer function for validating response type against the configured policy.
+ *
+ * @param enforcer policy enforcer
+ */
+ public void setUnregisteredClientPolicyEnforcer(
+ final BiFunction<Object, MetadataPolicy, Pair<Object, Boolean>> enforcer) {
+ checkSetterPreconditions();
+
+ unregisteredClientPolicyEnforcer = Constraint.isNotNull(enforcer, "Unregistered client policy cannot be null");
}
/** {@inheritDoc} */
@Override
protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
- final Set<ResponseType> registeredTypes = getMetadataContext() != null
- ? getMetadataContext().getClientInformation().getMetadata().getResponseTypes()
- : unregisteredClientValidResponseTypesLookupStrategy.apply(profileRequestContext);
-
final ResponseType requestedType = requestedResponseTypeLookupStrategy.apply(profileRequestContext);
- if (registeredTypes == null || registeredTypes.isEmpty() || !registeredTypes.contains(requestedType)) {
- log.warn("{} The response type {} is not registered for this RP", getLogPrefix(), requestedType);
- ActionSupport.buildEvent(profileRequestContext, OidcEventIds.INVALID_RESPONSE_TYPE);
+ if (getMetadataContext() != null) {
+ final Set<ResponseType> registeredTypes =
+ getMetadataContext().getClientInformation().getMetadata().getResponseTypes();
+ if (registeredTypes == null || registeredTypes.isEmpty() || !registeredTypes.contains(requestedType)) {
+ log.warn("{} The response type {} is not registered for this RP", getLogPrefix(), requestedType);
+ ActionSupport.buildEvent(profileRequestContext, OidcEventIds.INVALID_RESPONSE_TYPE);
+ return;
+ }
+ } else {
+ final Map<String, UnregisteredClientPolicy> policies =
+ unregisteredClientPolicyLookupStrategy.apply(profileRequestContext);
+ if (policies == null || policies.isEmpty()) {
+ log.warn("{} No policy was resolved even though the RP was not registered", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, IdPEventIds.INVALID_PROFILE_CONFIG);
+ return;
+ }
+ final Pair<Object, Boolean> enforcerResult =
+ unregisteredClientPolicyEnforcer.apply(requestedType == null ? "" : requestedType.toString(),
+ policies.get("response_type"));
+ if (!enforcerResult.getSecond()) {
+ log.warn("{} The response type {} is not compliant with the policy", getLogPrefix(), requestedType);
+ ActionSupport.buildEvent(profileRequestContext, OidcEventIds.INVALID_RESPONSE_TYPE);
+ return;
+ }
}
final Set<ResponseType> validTypes = validResponseTypesLookupStrategy.apply(profileRequestContext);
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/InitializeRegistrationMetadataPolicyContext.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/InitializeRegistrationMetadataPolicyContext.java
index af3fff85..1f650623 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/InitializeRegistrationMetadataPolicyContext.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/InitializeRegistrationMetadataPolicyContext.java
@@ -35,10 +35,10 @@ import net.shibboleth.idp.plugin.oidc.op.profile.context.navigate.DefaultOIDCCli
import net.shibboleth.idp.plugin.oidc.op.profile.logic.DefaultMetadataPolicyMergingStrategy;
import net.shibboleth.idp.profile.AbstractProfileAction;
import net.shibboleth.oidc.metadata.policy.MetadataPolicy;
-import net.shibboleth.oidc.metadata.policy.impl.DefaultMetadataPolicyValidator;
import net.shibboleth.oidc.profile.config.navigate.RegistrationMetadataPolicyLookupFunction;
import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
import net.shibboleth.shared.collection.Pair;
+import net.shibboleth.shared.component.ComponentInitializationException;
import net.shibboleth.shared.logic.Constraint;
/**
@@ -52,19 +52,19 @@ public class InitializeRegistrationMetadataPolicyContext extends AbstractProfile
@Nonnull private final Logger log = LoggerFactory.getLogger(InitializeRegistrationMetadataPolicyContext.class);
/** The strategy used to locate the request metadata policy configured for the profile. */
- @NonnullAfterInit private Function<ProfileRequestContext, Map<String, MetadataPolicy>>
+ @Nonnull private Function<ProfileRequestContext, Map<String, MetadataPolicy>>
profileMetadataPolicyLookupStrategy;
/** The strategy used to locate the request metadata policy encoded in the access token. */
- @NonnullAfterInit private Function<ProfileRequestContext, Map<String, MetadataPolicy>>
+ @Nonnull private Function<ProfileRequestContext, Map<String, MetadataPolicy>>
tokenMetadataPolicyLookupStrategy;
/** The strategy used to create or locate the metadata policy context. */
- @NonnullAfterInit private Function<ProfileRequestContext,OIDCClientRegistrationMetadataPolicyContext>
+ @Nonnull private Function<ProfileRequestContext,OIDCClientRegistrationMetadataPolicyContext>
registrationPolicyContextCreationStrategy;
/** The strategy used for merging profile and token based metadata policies. */
- @NonnullAfterInit private BiFunction<Map<String, MetadataPolicy>, Map<String, MetadataPolicy>,
+ @Nonnull private BiFunction<Map<String, MetadataPolicy>, Map<String, MetadataPolicy>,
Pair<Map<String, MetadataPolicy>, Boolean>> metadataPolicyMergingStrategy;
/** The strategy used for validating token and merged metadata policies. */
@@ -83,7 +83,6 @@ public class InitializeRegistrationMetadataPolicyContext extends AbstractProfile
new ChildContextLookup<>(OIDCClientRegistrationMetadataPolicyContext.class, true).compose(
new InboundMessageContextLookup());
metadataPolicyMergingStrategy = new DefaultMetadataPolicyMergingStrategy();
- metadataPolicyValidationStrategy = new DefaultMetadataPolicyValidator();
}
/**
@@ -149,7 +148,15 @@ public class InitializeRegistrationMetadataPolicyContext extends AbstractProfile
metadataPolicyValidationStrategy = Constraint.isNotNull(strategy,
"Metadata policy validation strategy cannot be null");
}
-
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doInitialize() throws ComponentInitializationException {
+ if (metadataPolicyValidationStrategy == null) {
+ throw new ComponentInitializationException("Metadata policy validation strategy cannot be null");
+ }
+ }
+
/** {@inheritDoc} */
@Override
protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/logic/DefaultUnregisteredClientAllowedScopeLookupFunction.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/logic/DefaultUnregisteredClientAllowedScopeLookupFunction.java
index c2f23003..cae215ab 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/logic/DefaultUnregisteredClientAllowedScopeLookupFunction.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/logic/DefaultUnregisteredClientAllowedScopeLookupFunction.java
@@ -16,6 +16,7 @@ package net.shibboleth.idp.plugin.oidc.op.profile.logic;
import java.util.Map;
import java.util.Optional;
+import java.util.function.BiFunction;
import java.util.function.Function;
import javax.annotation.Nonnull;
@@ -27,8 +28,9 @@ import com.nimbusds.oauth2.sdk.Scope;
import net.shibboleth.oidc.metadata.policy.MetadataPolicy;
import net.shibboleth.oidc.metadata.policy.UnregisteredClientPolicy;
+import net.shibboleth.oidc.metadata.policy.impl.DefaultMetadataPolicyEnforcer;
import net.shibboleth.oidc.profile.config.navigate.UnregisteredClientPolicyLookupFunction;
-import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.collection.Pair;
import net.shibboleth.shared.logic.Constraint;
/**
@@ -40,14 +42,18 @@ import net.shibboleth.shared.logic.Constraint;
public class DefaultUnregisteredClientAllowedScopeLookupFunction implements Function<ProfileRequestContext, Scope> {
/** Strategy used to locate the unregistered client policy. */
- @NonnullAfterInit private Function<ProfileRequestContext, Map<String, UnregisteredClientPolicy>>
+ @Nonnull private Function<ProfileRequestContext, Map<String, UnregisteredClientPolicy>>
unregisteredClientPolicyLookupStrategy;
+ /** Enforcer function for fetching allowed scope via the configured policy. */
+ @Nonnull private BiFunction<Object, MetadataPolicy, Pair<Object, Boolean>> unregisteredClientPolicyEnforcer;
+
/**
* Constructor.
*/
public DefaultUnregisteredClientAllowedScopeLookupFunction() {
unregisteredClientPolicyLookupStrategy = new UnregisteredClientPolicyLookupFunction();
+ unregisteredClientPolicyEnforcer = new DefaultMetadataPolicyEnforcer();
}
/**
@@ -60,18 +66,32 @@ public class DefaultUnregisteredClientAllowedScopeLookupFunction implements Func
unregisteredClientPolicyLookupStrategy = Constraint.isNotNull(strategy,
"Unregistered client policy lookup strategy cannot be null");
}
-
+
+ /**
+ * Set the enforcer function for fetching the allowed scope via the configured policy.
+ *
+ * @param enforcer policy enforcer
+ */
+ public void setUnregisteredClientPolicyEnforcer(
+ final BiFunction<Object, MetadataPolicy, Pair<Object, Boolean>> enforcer) {
+ unregisteredClientPolicyEnforcer = Constraint.isNotNull(enforcer, "Unregistered client policy cannot be null");
+ }
+
@Override @Nonnull
public Scope apply(@Nullable final ProfileRequestContext input) {
final Map<String, UnregisteredClientPolicy> policies = unregisteredClientPolicyLookupStrategy.apply(input);
if (policies == null || policies.isEmpty()) {
return new Scope();
}
- return Optional.ofNullable((MetadataPolicy) policies.get("scope"))
- .map(policy -> policy.getValue())
+ final Scope scope = Optional.ofNullable((MetadataPolicy) policies.get("scope"))
+ .map(policy -> unregisteredClientPolicyEnforcer.apply(null, policy))
+ .filter(value -> value != null)
+ .filter(value -> value.getSecond())
+ .map(value -> value.getFirst())
.filter(value -> value != null)
.map(value -> value.toString())
.map(Scope::parse)
.orElse(new Scope());
+ return scope == null ? new Scope() : scope;
}
}
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/logic/DefaultUnregisteredClientPolicyValidator.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/logic/DefaultUnregisteredClientPolicyValidator.java
index 4737d435..0f201f09 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/logic/DefaultUnregisteredClientPolicyValidator.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/logic/DefaultUnregisteredClientPolicyValidator.java
@@ -32,9 +32,9 @@ import net.shibboleth.shared.component.AbstractInitializableComponent;
import net.shibboleth.shared.logic.Constraint;
/**
- * Default validator for the unregistered client policies. Scope must be specified vie value -operator. Response types
- * must be specified via one_of -operator. Client ID and redirect URIs must be specified via one_of or regexp
- * -operators.
+ * Default validator for the unregistered client policies. Scope must be specified via value and/or custom operators.
+ * Response types must be specified via one_of and/or custom operators. Client ID and redirect URIs must be specified
+ * via one_of, regexp or custom operators.
*
* @since 3.0.0
*/
@@ -98,16 +98,16 @@ public class DefaultUnregisteredClientPolicyValidator extends AbstractInitializa
break;
case "redirect_uri":
if (!Optional.ofNullable(policy)
- .filter(responseType -> preChecksForMandatoryKey(responseType, "redirect_uri"))
- .filter(responseType -> verifyRedirectUriPolicy(responseType))
+ .filter(redirectUri -> preChecksForMandatoryKey(redirectUri, "redirect_uri"))
+ .filter(redirectUri -> verifyRedirectUriPolicy(redirectUri))
.isPresent()) {
return false;
}
break;
case "client_id":
if (!Optional.ofNullable(policy)
- .filter(responseType -> preChecksForMandatoryKey(responseType, "client_id"))
- .filter(responseType -> verifyClientIdPolicy(responseType))
+ .filter(clientId -> preChecksForMandatoryKey(clientId, "client_id"))
+ .filter(clientId -> verifyClientIdPolicy(clientId))
.isPresent()) {
return false;
}
@@ -126,12 +126,12 @@ public class DefaultUnregisteredClientPolicyValidator extends AbstractInitializa
* @return true if verified, false otherwise.
*/
protected boolean verifyScopePolicy(@Nonnull final MetadataPolicy policy) {
- if (policy.getOneOfValues() != null || policy.getRegexp() != null || policy.getValue() == null) {
- log.error("Only 'value' should be used together with 'scope' in the policy");
+ if (policy.getOneOfValues() != null || policy.getRegexp() != null) {
+ log.error("Only 'value' or custom operators should be used together with 'scope' in the policy");
return false;
}
- if (!(policy.getValue() instanceof String)) {
- log.error("Only string values can be specified for 'scope' in the policy");
+ if (!(policy.getValue() instanceof String) && policy.getCustomOperators().isEmpty() ) {
+ log.error("Only string 'value' or custom operators can be specified for 'scope' in the policy");
return false;
}
return true;
@@ -143,12 +143,13 @@ public class DefaultUnregisteredClientPolicyValidator extends AbstractInitializa
* @return true if verified, false otherwise.
*/
protected boolean verifyResponseTypePolicy(@Nonnull final MetadataPolicy policy) {
- if (policy.getRegexp() != null || policy.getValue() != null || policy.getOneOfValues() == null) {
- log.error("Only 'one_of' should be used together with 'response_type' in the policy");
+ if (policy.getRegexp() != null || policy.getValue() != null) {
+ log.error("Only 'one_of' or custom operators should be used together with 'response_type' in the policy");
return false;
}
- if (policy.getOneOfValues().isEmpty()) {
- log.error("No 'one_of' values specified for 'response_type' in the policy");
+ if ((policy.getOneOfValues() == null || policy.getOneOfValues().isEmpty())
+ && policy.getCustomOperators().isEmpty()) {
+ log.error("No 'one_of' or custom operator values specified for 'response_type' in the policy");
return false;
}
return true;
@@ -164,8 +165,9 @@ public class DefaultUnregisteredClientPolicyValidator extends AbstractInitializa
log.error("'value' cannot be specified for 'redirect_uri' in the policy");
return false;
}
- if ((policy.getOneOfValues() == null || policy.getOneOfValues().isEmpty()) && policy.getRegexp() == null) {
- log.error("No 'one_of' or 'regexp' values specified for 'redirect_uri' in the policy");
+ if ((policy.getOneOfValues() == null || policy.getOneOfValues().isEmpty()) && policy.getRegexp() == null
+ && policy.getCustomOperators().isEmpty()) {
+ log.error("No 'one_of' or 'regexp' or custom operator values specified for 'redirect_uri' in the policy");
return false;
}
return true;
@@ -181,8 +183,9 @@ public class DefaultUnregisteredClientPolicyValidator extends AbstractInitializa
log.error("'value' cannot be specified for 'client_id' in the policy");
return false;
}
- if ((policy.getOneOfValues() == null || policy.getOneOfValues().isEmpty()) && policy.getRegexp() == null) {
- log.error("No 'one_of' or 'regexp' values specified for 'client_id' in the policy");
+ if ((policy.getOneOfValues() == null || policy.getOneOfValues().isEmpty()) && policy.getRegexp() == null
+ && policy.getCustomOperators().isEmpty()) {
+ log.error("No 'one_of' or 'regexp' or custom operator values specified for 'client_id' in the policy");
return false;
}
return true;
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/logic/DefaultUnregisteredClientResponseTypesLookupFunction.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/logic/DefaultUnregisteredClientResponseTypesLookupFunction.java
index 8b223561..26dbc593 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/logic/DefaultUnregisteredClientResponseTypesLookupFunction.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/logic/DefaultUnregisteredClientResponseTypesLookupFunction.java
@@ -38,7 +38,9 @@ import net.shibboleth.shared.primitive.StringSupport;
* Default function for fetching allowed response types via unregistered client policy.
*
* @since 3.0.0
+ * @deprecated The response type validation is handled against the policy in the SWF action
*/
+ at Deprecated(forRemoval = true)
public class DefaultUnregisteredClientResponseTypesLookupFunction extends AbstractInitializableComponent
implements Function<ProfileRequestContext, Set<ResponseType>> {
diff --git a/idp-oidc-extension-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml b/idp-oidc-extension-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
index 0e158895..919dbf7f 100644
--- a/idp-oidc-extension-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
+++ b/idp-oidc-extension-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
@@ -233,7 +233,8 @@
<bean id="shibboleth.oidc.DefaultAllowedScopeStrategy"
class="net.shibboleth.idp.plugin.oidc.op.profile.logic.DefaultAllowedScopeLookupFunction">
<property name="unregisteredClientAllowedScopeLookupStrategy">
- <bean class="net.shibboleth.idp.plugin.oidc.op.profile.logic.DefaultUnregisteredClientAllowedScopeLookupFunction">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.profile.logic.DefaultUnregisteredClientAllowedScopeLookupFunction"
+ p:unregisteredClientPolicyEnforcer="#{getObject('shibboleth.oidc.UnregisteredClientPolicyEnforcer') ?: getObject('shibboleth.oidc.DefaultUnregisteredClientPolicyEnforcer')}">
<property name="unregisteredClientPolicyLookupStrategy">
<bean class="net.shibboleth.oidc.profile.config.navigate.UnregisteredClientPolicyLookupFunction" />
</property>
@@ -705,10 +706,15 @@
p:criteriaToIdentifierStrategy-ref="shibboleth.oidc.UnregisteredDefaultMetadataCriteriaToIdentifierStrategy"
p:sourceMetadataExpiryStrategy-ref="shibboleth.oidc.UnregisteredDefaultExpirationTimeStrategy"
p:identifierExtractionStrategy-ref="shibboleth.oidc.DefaultUnregisteredClientPolicyIdentifierExtractionStrategy"
- p:metadataValidPredicate-ref="shibboleth.oidc.DefaultUnregisteredClientPolicyValidator"/>
+ p:metadataValidPredicate="#{getObject('shibboleth.oidc.UnregisteredClientPolicyValidator') ?: getObject('shibboleth.oidc.DefaultUnregisteredClientPolicyValidator')}"/>
<bean id="shibboleth.oidc.DefaultUnregisteredClientPolicyValidator"
- class="net.shibboleth.idp.plugin.oidc.op.profile.logic.DefaultUnregisteredClientPolicyValidator" />
+ class="net.shibboleth.idp.plugin.oidc.op.profile.logic.DefaultUnregisteredClientPolicyValidator">
+ <property name="syntaxValidator">
+ <bean class="net.shibboleth.oidc.metadata.policy.impl.DefaultMetadataPolicyValidator"
+ p:customMetadataPolicyOperators="#{getObject('shibboleth.oidc.UnregisteredClientPolicyCustomOperators') ?: getObject('shibboleth.oidc.DefaultMetadataPolicyCustomOperators')}"/>
+ </property>
+ </bean>
<bean id="shibboleth.oidc.UnregisteredDefaultJSONMapParsingStrategy"
class="net.shibboleth.oidc.metadata.cache.impl.DefaultJSONMapParsingStrategy"
@@ -752,4 +758,23 @@
</constructor-arg>
</bean>
+ <bean id="shibboleth.oidc.dynreg.DefaultMetadataPolicyValidator"
+ class="net.shibboleth.oidc.metadata.policy.impl.DefaultMetadataPolicyValidator"
+ p:customMetadataPolicyOperators="#{getObject('shibboleth.oidc.dynreg.MetadataPolicyCustomOperators') ?: getObject('shibboleth.oidc.DefaultMetadataPolicyCustomOperators')}"/>
+
+ <bean id="shibboleth.oidc.dynreg.DefaultMetadataPolicyEnforcer"
+ class="net.shibboleth.oidc.metadata.policy.impl.DefaultMetadataPolicyEnforcer"
+ p:customMetadataPolicyOperators="#{getObject('shibboleth.oidc.dynreg.MetadataPolicyCustomOperators') ?: getObject('shibboleth.oidc.DefaultMetadataPolicyCustomOperators')}"/>
+
+ <bean id="shibboleth.oidc.DefaultUnregisteredClientPolicyEnforcer"
+ class="net.shibboleth.oidc.metadata.policy.impl.DefaultMetadataPolicyEnforcer"
+ p:customMetadataPolicyOperators="#{getObject('shibboleth.oidc.UnregisteredClientPolicyCustomOperators') ?: getObject('shibboleth.oidc.DefaultMetadataPolicyCustomOperators')}"/>
+
+ <util:map id="shibboleth.oidc.DefaultMetadataPolicyCustomOperators"
+ value-type="net.shibboleth.oidc.metadata.policy.impl.CustomMetadataPolicyOperator">
+ <entry key="bean">
+ <bean class="net.shibboleth.oidc.metadata.policy.impl.BeanMetadataPolicyOperator" />
+ </entry>
+ </util:map>
+
</beans>
diff --git a/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oauth2/introspection/introspection-beans.xml b/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oauth2/introspection/introspection-beans.xml
index 7a64d20d..ddd835d9 100644
--- a/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oauth2/introspection/introspection-beans.xml
+++ b/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oauth2/introspection/introspection-beans.xml
@@ -34,7 +34,8 @@
<bean id="ValidateClientIDAgainstPolicy"
class="net.shibboleth.idp.plugin.oidc.op.oauth2.profile.impl.ValidateClientIDAgainstPolicy"
p:clientIDLookupStrategy-ref="shibboleth.ClientIDLookupStrategy"
- scope="prototype" />
+ scope="prototype"
+ p:unregisteredClientPolicyEnforcer="#{getObject('shibboleth.oidc.UnregisteredClientPolicyEnforcer') ?: getObject('shibboleth.oidc.DefaultUnregisteredClientPolicyEnforcer')}"/>
<bean id="ProcessTokenForIntrospection"
class="net.shibboleth.idp.plugin.oidc.op.oauth2.profile.impl.ProcessTokenForIntrospection" scope="prototype"
diff --git a/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oauth2/revocation/revocation-beans.xml b/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oauth2/revocation/revocation-beans.xml
index 6872ef61..28236519 100644
--- a/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oauth2/revocation/revocation-beans.xml
+++ b/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oauth2/revocation/revocation-beans.xml
@@ -34,7 +34,8 @@
<bean id="ValidateClientIDAgainstPolicy"
class="net.shibboleth.idp.plugin.oidc.op.oauth2.profile.impl.ValidateClientIDAgainstPolicy"
p:clientIDLookupStrategy-ref="shibboleth.ClientIDLookupStrategy"
- scope="prototype" />
+ scope="prototype"
+ p:unregisteredClientPolicyEnforcer="#{getObject('shibboleth.oidc.UnregisteredClientPolicyEnforcer') ?: getObject('shibboleth.oidc.DefaultUnregisteredClientPolicyEnforcer')}"/>
<bean id="ProcessTokenForRevocation"
class="net.shibboleth.idp.plugin.oidc.op.oauth2.profile.impl.ProcessTokenForRevocation" scope="prototype"
diff --git a/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/authorize/authorize-beans.xml b/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/authorize/authorize-beans.xml
index 51fc17f5..e2ce0c4f 100644
--- a/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/authorize/authorize-beans.xml
+++ b/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/authorize/authorize-beans.xml
@@ -75,7 +75,8 @@
<bean id="ValidateClientIDAgainstPolicy"
class="net.shibboleth.idp.plugin.oidc.op.oauth2.profile.impl.ValidateClientIDAgainstPolicy"
p:clientIDLookupStrategy-ref="shibboleth.ClientIDLookupStrategy"
- scope="prototype" />
+ scope="prototype"
+ p:unregisteredClientPolicyEnforcer="#{getObject('shibboleth.oidc.UnregisteredClientPolicyEnforcer') ?: getObject('shibboleth.oidc.DefaultUnregisteredClientPolicyEnforcer')}"/>
<bean id="ValidateAuthorizationRequestType"
class="net.shibboleth.idp.plugin.oidc.op.oauth2.profile.impl.ValidateAuthorizationRequestType"
@@ -310,14 +311,13 @@
</util:list>
<bean id="ValidateRedirectURI" class="net.shibboleth.idp.plugin.oidc.op.oauth2.profile.impl.ValidateRedirectURI"
- scope="prototype" p:requireRequestedValue="true" />
+ scope="prototype"
+ p:requireRequestedValue="true"
+ p:unregisteredClientPolicyEnforcer="#{getObject('shibboleth.oidc.UnregisteredClientPolicyEnforcer') ?: getObject('shibboleth.oidc.DefaultUnregisteredClientPolicyEnforcer')}"/>
<bean id="ValidateResponseType" class="net.shibboleth.idp.plugin.oidc.op.oauth2.profile.impl.ValidateResponseType"
- scope="prototype">
- <property name="unregisteredClientValidResponseTypesLookupStrategy">
- <bean class="net.shibboleth.idp.plugin.oidc.op.profile.logic.DefaultUnregisteredClientResponseTypesLookupFunction" />
- </property>
- </bean>
+ scope="prototype"
+ p:unregisteredClientPolicyEnforcer="#{getObject('shibboleth.oidc.UnregisteredClientPolicyEnforcer') ?: getObject('shibboleth.oidc.DefaultUnregisteredClientPolicyEnforcer')}"/>
<bean id="ValidateCodeChallenge" class="net.shibboleth.idp.plugin.oidc.op.oauth2.profile.impl.ValidateCodeChallenge"
scope="prototype" />
diff --git a/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/register/register-beans.xml b/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/register/register-beans.xml
index fd228730..48fe8013 100644
--- a/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/register/register-beans.xml
+++ b/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/register/register-beans.xml
@@ -53,10 +53,13 @@
<bean id="InitializeRegistrationMetadataPolicyContext"
class="net.shibboleth.idp.plugin.oidc.op.profile.impl.InitializeRegistrationMetadataPolicyContext"
- scope="prototype" />
+ scope="prototype"
+ p:metadataPolicyValidationStrategy="#{getObject('shibboleth.oidc.dynreg.MetadataPolicyValidator') ?: getObject('shibboleth.oidc.dynreg.DefaultMetadataPolicyValidator')}" />
<bean id="ValidateRegistrationRequestMetadata"
- class="net.shibboleth.idp.plugin.oidc.op.profile.impl.ValidateRegistrationRequestMetadata" scope="prototype" />
+ class="net.shibboleth.idp.plugin.oidc.op.profile.impl.ValidateRegistrationRequestMetadata"
+ scope="prototype"
+ p:metadataPolicyEnforcer="#{getObject('shibboleth.oidc.dynreg.MetadataPolicyEnforcer') ?: getObject('shibboleth.oidc.dynreg.DefaultMetadataPolicyEnforcer')}"/>
<bean id="CheckRedirectURIs"
class="net.shibboleth.idp.plugin.oidc.op.profile.impl.CheckRedirectURIs"
diff --git a/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/token/token-beans.xml b/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/token/token-beans.xml
index 056d204b..a6667518 100644
--- a/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/token/token-beans.xml
+++ b/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/token/token-beans.xml
@@ -43,7 +43,8 @@
<bean id="ValidateClientIDAgainstPolicy"
class="net.shibboleth.idp.plugin.oidc.op.oauth2.profile.impl.ValidateClientIDAgainstPolicy"
p:clientIDLookupStrategy-ref="shibboleth.ClientIDLookupStrategy"
- scope="prototype" />
+ scope="prototype"
+ p:unregisteredClientPolicyEnforcer="#{getObject('shibboleth.oidc.UnregisteredClientPolicyEnforcer') ?: getObject('shibboleth.oidc.DefaultUnregisteredClientPolicyEnforcer')}"/>
<bean id="ValidateGrantType" class="net.shibboleth.idp.plugin.oidc.op.profile.impl.ValidateGrantType"
scope="prototype" />
@@ -86,7 +87,8 @@
p:activationCondition-ref="AuthorizationCodeGrantCondition"
p:redirectURILookupStrategy-ref="shibboleth.TokenRequestRedirectURILookupStrategy"
p:validRedirectURIsLookupStrategy-ref="shibboleth.TokenRequestValidRequestUrisLookupStrategy"
- p:requireRequestedValue="false" />
+ p:requireRequestedValue="false"
+ p:unregisteredClientPolicyEnforcer="#{getObject('shibboleth.oidc.UnregisteredClientPolicyEnforcer') ?: getObject('shibboleth.oidc.DefaultUnregisteredClientPolicyEnforcer')}"/>
<bean id="shibboleth.TokenRequestRedirectURILookupStrategy"
class="net.shibboleth.idp.plugin.oidc.op.profile.context.navigate.TokenRequestRedirectURILookupFunction" />
diff --git a/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/userinfo/userinfo-beans.xml b/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/userinfo/userinfo-beans.xml
index 5ca1ec48..87445bf6 100644
--- a/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/userinfo/userinfo-beans.xml
+++ b/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/userinfo/userinfo-beans.xml
@@ -45,7 +45,8 @@
<bean id="ValidateClientIDAgainstPolicy"
class="net.shibboleth.idp.plugin.oidc.op.oauth2.profile.impl.ValidateClientIDAgainstPolicy"
p:clientIDLookupStrategy-ref="shibboleth.ClientIDLookupStrategy"
- scope="prototype" />
+ scope="prototype"
+ p:unregisteredClientPolicyEnforcer="#{getObject('shibboleth.oidc.UnregisteredClientPolicyEnforcer') ?: getObject('shibboleth.oidc.DefaultUnregisteredClientPolicyEnforcer')}"/>
<bean id="ValidateAccessToken"
class="net.shibboleth.idp.plugin.oidc.op.userinfo.profile.impl.ValidateAccessToken" scope="prototype" />
diff --git a/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/service/relying-party/postconfig.xml b/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/service/relying-party/postconfig.xml
index b64bec47..94e42913 100644
--- a/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/service/relying-party/postconfig.xml
+++ b/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/service/relying-party/postconfig.xml
@@ -772,9 +772,6 @@
p:identifierExtractionStrategy-ref="shibboleth.oidc.dynreg.DefaultMetadataPolicyIdentifierExtractionStrategy"
p:metadataValidPredicate-ref="shibboleth.oidc.dynreg.DefaultMetadataPolicyValidator"/>
- <bean id="shibboleth.oidc.dynreg.DefaultMetadataPolicyValidator"
- class="net.shibboleth.oidc.metadata.policy.impl.DefaultMetadataPolicyValidator" />
-
<bean id="shibboleth.oidc.dynreg.DefaultJSONMapParsingStrategy"
class="net.shibboleth.oidc.metadata.cache.impl.DefaultJSONMapParsingStrategy"
c:valueClass="net.shibboleth.oidc.metadata.policy.MetadataPolicy"/>
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateRedirectURITest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateRedirectURITest.java
index d9946619..4d5c7fb4 100644
--- a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateRedirectURITest.java
+++ b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateRedirectURITest.java
@@ -25,6 +25,7 @@ import net.shibboleth.idp.profile.testing.ActionTestingSupport;
import net.shibboleth.oidc.metadata.context.OIDCMetadataContext;
import net.shibboleth.oidc.metadata.policy.MetadataPolicy;
import net.shibboleth.oidc.metadata.policy.UnregisteredClientPolicy;
+import net.shibboleth.oidc.metadata.policy.impl.DefaultMetadataPolicyEnforcer;
import net.shibboleth.oidc.profile.core.OidcEventIds;
import net.shibboleth.shared.component.ComponentInitializationException;
@@ -66,6 +67,7 @@ public class ValidateRedirectURITest extends BaseOIDCResponseActionTest {
if (policies != null) {
action.setUnregisteredClientPolicyLookupStrategy(prc -> policies);
}
+ action.setUnregisteredClientPolicyEnforcer(new DefaultMetadataPolicyEnforcer());
action.initialize();
}
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateResponseTypeTest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateResponseTypeTest.java
index 6772563b..b8ea993f 100644
--- a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateResponseTypeTest.java
+++ b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateResponseTypeTest.java
@@ -17,11 +17,14 @@ package net.shibboleth.idp.plugin.oidc.op.oauth2.profile.impl;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashSet;
+import java.util.Map;
import java.util.Set;
import net.shibboleth.idp.plugin.oidc.op.profile.impl.BaseOIDCResponseActionTest;
import net.shibboleth.idp.profile.testing.ActionTestingSupport;
import net.shibboleth.oidc.metadata.context.OIDCMetadataContext;
+import net.shibboleth.oidc.metadata.policy.MetadataPolicy;
+import net.shibboleth.oidc.metadata.policy.UnregisteredClientPolicy;
import net.shibboleth.oidc.profile.core.OidcEventIds;
import net.shibboleth.shared.component.ComponentInitializationException;
@@ -83,7 +86,10 @@ public class ValidateResponseTypeTest extends BaseOIDCResponseActionTest {
private void initPolicy(final Set<ResponseType> responseTypes) {
action = new ValidateResponseType();
- action.setUnregisteredClientValidResponseTypesLookupStrategy(prc -> responseTypes);
+ action.setUnregisteredClientPolicyLookupStrategy(prc -> Map.of("response_type",
+ new UnregisteredClientPolicy(new MetadataPolicy.Builder()
+ .withOneOfValues(responseTypes.stream().map(rt -> (Object) rt.toString()).toList())
+ .build())));
try {
action.initialize();
} catch (ComponentInitializationException e) {
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/AlwaysFalseCustomMetadataPolicyOperator.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/AlwaysFalseCustomMetadataPolicyOperator.java
new file mode 100644
index 00000000..396d846e
--- /dev/null
+++ b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/AlwaysFalseCustomMetadataPolicyOperator.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed 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.idp.plugin.oidc.op.profile.flow;
+
+import net.shibboleth.oidc.metadata.policy.MetadataPolicy;
+import net.shibboleth.oidc.metadata.policy.impl.CustomMetadataPolicyOperator;
+import net.shibboleth.shared.logic.ConstraintViolationException;
+
+public class AlwaysFalseCustomMetadataPolicyOperator implements CustomMetadataPolicyOperator {
+
+ @Override
+ public boolean validate(MetadataPolicy policy) {
+ return false;
+ }
+
+ @Override
+ public Object apply(Object inputValue, MetadataPolicy policy) throws ConstraintViolationException {
+ throw new ConstraintViolationException("Cannot accept " + inputValue);
+ }
+
+}
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/AlwaysTrueCustomMetadataPolicyOperator.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/AlwaysTrueCustomMetadataPolicyOperator.java
new file mode 100644
index 00000000..5f0234bc
--- /dev/null
+++ b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/AlwaysTrueCustomMetadataPolicyOperator.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed 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.idp.plugin.oidc.op.profile.flow;
+
+import net.shibboleth.oidc.metadata.policy.MetadataPolicy;
+import net.shibboleth.oidc.metadata.policy.impl.CustomMetadataPolicyOperator;
+import net.shibboleth.shared.logic.ConstraintViolationException;
+
+public class AlwaysTrueCustomMetadataPolicyOperator implements CustomMetadataPolicyOperator {
+
+ @Override
+ public boolean validate(MetadataPolicy policy) {
+ return true;
+ }
+
+ @Override
+ public Object apply(Object inputValue, MetadataPolicy policy) throws ConstraintViolationException {
+ return inputValue;
+ }
+
+}
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/RegistrationFlowTest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/RegistrationFlowTest.java
index bdbafc2d..6a34b070 100644
--- a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/RegistrationFlowTest.java
+++ b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/RegistrationFlowTest.java
@@ -251,6 +251,26 @@ public class RegistrationFlowTest extends AbstractOidcFlowTest {
Assert.assertTrue(parsedResponse.getOIDCClientInformation().getOIDCMetadata().getGrantTypes().contains(GrantType.IMPLICIT));
}
+ @Test
+ public void testAccessToken_nonDefaultPolicyActive_failsWhenAlwaysFailingPolicy() throws Exception {
+ setJsonRequest("POST", buildRequestMessage(redirectUri, "\"grant_types\":[\"authorization_code\"]"));
+ rpId = "alwaysFailingMetadataPolicy";
+ request.addHeader("Authorization", buildRegistrationAccessToken(false, (String) null,
+ (String[]) null).toAuthorizationHeader());
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ assertErrorCode(result, "invalid_client_metadata");
+ }
+
+ @Test
+ public void testAccessToken_nonDefaultPolicyActive_failsWhenInvalidBeanInPolicy() throws Exception {
+ setJsonRequest("POST", buildRequestMessage(redirectUri, "\"grant_types\":[\"authorization_code\"]"));
+ rpId = "invalidBeanMetadataPolicy";
+ request.addHeader("Authorization", buildRegistrationAccessToken(false, (String) null,
+ (String[]) null).toAuthorizationHeader());
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ assertErrorCode(result, "invalid_client_metadata");
+ }
+
protected void assertSuccessfulResponse(final FlowExecutionResult result, final String clientId) throws Exception {
final OIDCClientInformationResponse parsedResponse =
parseSuccessResponse(result, OIDCClientInformationResponse.class);
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/logic/DefaultUnregisteredClientAllowedScopeLookupFunctionTest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/logic/DefaultUnregisteredClientAllowedScopeLookupFunctionTest.java
index a70ef7f8..dd83d04f 100644
--- a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/logic/DefaultUnregisteredClientAllowedScopeLookupFunctionTest.java
+++ b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/logic/DefaultUnregisteredClientAllowedScopeLookupFunctionTest.java
@@ -27,6 +27,10 @@ import com.nimbusds.openid.connect.sdk.OIDCScopeValue;
import net.shibboleth.oidc.metadata.policy.MetadataPolicy;
import net.shibboleth.oidc.metadata.policy.UnregisteredClientPolicy;
+import net.shibboleth.oidc.metadata.policy.impl.CustomMetadataPolicyOperator;
+import net.shibboleth.oidc.metadata.policy.impl.DefaultMetadataPolicyEnforcer;
+import net.shibboleth.shared.collection.CollectionSupport;
+import net.shibboleth.shared.logic.ConstraintViolationException;
/**
* Unit tests for {@link DefaultUnregisteredClientAllowedScopeLookupFunction}.
@@ -38,6 +42,22 @@ public class DefaultUnregisteredClientAllowedScopeLookupFunctionTest {
public void setup(final Map<String, UnregisteredClientPolicy> policies) {
function = new DefaultUnregisteredClientAllowedScopeLookupFunction();
function.setUnregisteredClientPolicyLookupStrategy(prc -> policies);
+ final DefaultMetadataPolicyEnforcer enforcer = new DefaultMetadataPolicyEnforcer();
+ enforcer.setCustomMetadataPolicyOperators(CollectionSupport.singletonMap(
+ "customOperator", new CustomMetadataPolicyOperator() {
+
+ @Override
+ public boolean validate(MetadataPolicy policy) {
+ return true;
+ }
+
+ @Override
+ public Object apply(Object inputValue, MetadataPolicy policy) throws ConstraintViolationException {
+ return "openid email";
+ }
+
+ }));
+ function.setUnregisteredClientPolicyEnforcer(enforcer);
}
@Test
@@ -76,4 +96,16 @@ public class DefaultUnregisteredClientAllowedScopeLookupFunctionTest {
Assert.assertTrue(result.contains(OIDCScopeValue.OPENID));
Assert.assertTrue(result.contains(OIDCScopeValue.PROFILE));
}
+
+ @Test
+ public void testWithScopeCustomOperator() {
+ setup(Map.of("scope", new UnregisteredClientPolicy(new MetadataPolicy.Builder()
+ .withCustomOperator("customOperator", "nomatter").build())));
+ final Scope result = function.apply(new ProfileRequestContext());
+ Assert.assertNotNull(result);
+ Assert.assertEquals(result.size(), 2);
+ Assert.assertTrue(result.contains(OIDCScopeValue.OPENID));
+ Assert.assertTrue(result.contains(OIDCScopeValue.EMAIL));
+ }
+
}
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/logic/DefaultUnregisteredClientPolicyValidatorTest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/logic/DefaultUnregisteredClientPolicyValidatorTest.java
index 05cb6080..28b8c006 100644
--- a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/logic/DefaultUnregisteredClientPolicyValidatorTest.java
+++ b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/logic/DefaultUnregisteredClientPolicyValidatorTest.java
@@ -18,23 +18,35 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import org.mockito.Mockito;
import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import net.shibboleth.oidc.metadata.policy.MetadataPolicy;
import net.shibboleth.oidc.metadata.policy.UnregisteredClientPolicy;
+import net.shibboleth.oidc.metadata.policy.impl.CustomMetadataPolicyOperator;
+import net.shibboleth.oidc.metadata.policy.impl.DefaultMetadataPolicyValidator;
/**
* Unit tests for {@link DefaultUnregisteredClientPolicyValidator}.
*/
public class DefaultUnregisteredClientPolicyValidatorTest {
- DefaultUnregisteredClientPolicyValidator predicate = new DefaultUnregisteredClientPolicyValidator();
+ DefaultUnregisteredClientPolicyValidator predicate;
- public void setup(final Map<String, UnregisteredClientPolicy> policies) {
-
+ @BeforeMethod
+ public void init() {
+ predicate = new DefaultUnregisteredClientPolicyValidator();
}
+ public void setupOperators(final Map<String, CustomMetadataPolicyOperator> operators) {
+ final DefaultMetadataPolicyValidator syntaxValidator = new DefaultMetadataPolicyValidator();
+ assert operators != null;
+ syntaxValidator.setCustomMetadataPolicyOperators(operators);
+ predicate.setSyntaxValidator(syntaxValidator);
+ }
+
@Test
public void testNull() {
Assert.assertFalse(predicate.test(null));
@@ -50,6 +62,25 @@ public class DefaultUnregisteredClientPolicyValidatorTest {
Assert.assertTrue(predicate.test(validPolicies()));
}
+ @Test
+ public void testValidWithValidCustomOperators() {
+ setupOperators(Map.of("mockOperator", mockOperator(true)));
+ Assert.assertTrue(predicate.test(validWithCustomOperators()));
+ }
+
+ @Test
+ public void testCustomOperatorsFailingValidation() {
+ setupOperators(Map.of("mockOperator", mockOperator(false)));
+ Assert.assertFalse(predicate.test(validWithCustomOperators()));
+ }
+
+ @SuppressWarnings("null")
+ protected CustomMetadataPolicyOperator mockOperator(final boolean validationResult) {
+ CustomMetadataPolicyOperator operator = Mockito.mock(CustomMetadataPolicyOperator.class);
+ Mockito.when(operator.validate(Mockito.any())).thenReturn(validationResult);
+ return operator;
+ }
+
@Test
public void testMissingScope() {
Map<String, UnregisteredClientPolicy> map = validPolicies();
@@ -64,6 +95,22 @@ public class DefaultUnregisteredClientPolicyValidatorTest {
Assert.assertFalse(predicate.test(map));
}
+ @Test
+ public void testScopeSuccessWithCustomOperator() {
+ setupOperators(Map.of("mockOperator", mockOperator(true)));
+ Map<String, UnregisteredClientPolicy> map = validPolicies();
+ map.put("scope", customOperator());
+ Assert.assertTrue(predicate.test(map));
+ }
+
+ @Test
+ public void testScopeFailureWithCustomOperator() {
+ setupOperators(Map.of("mockOperator", mockOperator(false)));
+ Map<String, UnregisteredClientPolicy> map = validPolicies();
+ map.put("scope", customOperator());
+ Assert.assertFalse(predicate.test(map));
+ }
+
@Test
public void testMissingResponseType() {
Map<String, UnregisteredClientPolicy> map = validPolicies();
@@ -78,6 +125,22 @@ public class DefaultUnregisteredClientPolicyValidatorTest {
Assert.assertFalse(predicate.test(map));
}
+ @Test
+ public void testResponseTypeSuccessWithCustomOperator() {
+ setupOperators(Map.of("mockOperator", mockOperator(true)));
+ Map<String, UnregisteredClientPolicy> map = validPolicies();
+ map.put("response_type", customOperator());
+ Assert.assertTrue(predicate.test(map));
+ }
+
+ @Test
+ public void testResponseTypeFailureWithCustomOperator() {
+ setupOperators(Map.of("mockOperator", mockOperator(false)));
+ Map<String, UnregisteredClientPolicy> map = validPolicies();
+ map.put("response_type", customOperator());
+ Assert.assertFalse(predicate.test(map));
+ }
+
@Test
public void testMissingRedirectUri() {
Map<String, UnregisteredClientPolicy> map = validPolicies();
@@ -92,6 +155,22 @@ public class DefaultUnregisteredClientPolicyValidatorTest {
Assert.assertFalse(predicate.test(map));
}
+ @Test
+ public void testRedirectUriSuccessWithCustomOperator() {
+ setupOperators(Map.of("mockOperator", mockOperator(true)));
+ Map<String, UnregisteredClientPolicy> map = validPolicies();
+ map.put("redirect_uri", customOperator());
+ Assert.assertTrue(predicate.test(map));
+ }
+
+ @Test
+ public void testRedirectUriFailureWithCustomOperator() {
+ setupOperators(Map.of("mockOperator", mockOperator(false)));
+ Map<String, UnregisteredClientPolicy> map = validPolicies();
+ map.put("redirect_uri", customOperator());
+ Assert.assertFalse(predicate.test(map));
+ }
+
@Test
public void testMissingClientId() {
Map<String, UnregisteredClientPolicy> map = validPolicies();
@@ -106,6 +185,22 @@ public class DefaultUnregisteredClientPolicyValidatorTest {
Assert.assertFalse(predicate.test(map));
}
+ @Test
+ public void testClientIdSuccessWithCustomOperator() {
+ setupOperators(Map.of("mockOperator", mockOperator(true)));
+ Map<String, UnregisteredClientPolicy> map = validPolicies();
+ map.put("client_id", customOperator());
+ Assert.assertTrue(predicate.test(map));
+ }
+
+ @Test
+ public void testClientIdFailureWithCustomOperator() {
+ setupOperators(Map.of("mockOperator", mockOperator(false)));
+ Map<String, UnregisteredClientPolicy> map = validPolicies();
+ map.put("client_id", customOperator());
+ Assert.assertFalse(predicate.test(map));
+ }
+
protected Map<String, UnregisteredClientPolicy> validPolicies() {
final Map<String, UnregisteredClientPolicy> map = new HashMap<>( Map.of("scope", validScope(),
"response_type", validResponseType(),
@@ -114,6 +209,20 @@ public class DefaultUnregisteredClientPolicyValidatorTest {
return map;
}
+ protected Map<String, UnregisteredClientPolicy> validWithCustomOperators() {
+ final Map<String, UnregisteredClientPolicy> map = new HashMap<>( Map.of("scope", customOperator(),
+ "response_type", customOperator(),
+ "redirect_uri", customOperator(),
+ "client_id", customOperator()));
+ return map;
+ }
+
+ protected UnregisteredClientPolicy customOperator() {
+ return new UnregisteredClientPolicy(new MetadataPolicy.Builder()
+ .withCustomOperator("mockOperator", "mockValue")
+ .build());
+ }
+
protected UnregisteredClientPolicy validScope() {
return new UnregisteredClientPolicy(new MetadataPolicy.Builder().withValue("openid profile").build());
}
diff --git a/idp-oidc-extension-impl/src/test/resources/net/shibboleth/idp/module/conf/global.xml b/idp-oidc-extension-impl/src/test/resources/net/shibboleth/idp/module/conf/global.xml
index 6ae6e990..707f855f 100644
--- a/idp-oidc-extension-impl/src/test/resources/net/shibboleth/idp/module/conf/global.xml
+++ b/idp-oidc-extension-impl/src/test/resources/net/shibboleth/idp/module/conf/global.xml
@@ -102,4 +102,8 @@
</property>
</bean>
+ <bean id="alwaysTruePolicyOperator" class="net.shibboleth.idp.plugin.oidc.op.profile.flow.AlwaysTrueCustomMetadataPolicyOperator" />
+
+ <bean id="alwaysFalsePolicyOperator" class="net.shibboleth.idp.plugin.oidc.op.profile.flow.AlwaysFalseCustomMetadataPolicyOperator" />
+
</beans>
diff --git a/idp-oidc-extension-impl/src/test/resources/net/shibboleth/idp/module/conf/metadata-policy-failing.json b/idp-oidc-extension-impl/src/test/resources/net/shibboleth/idp/module/conf/metadata-policy-failing.json
new file mode 100644
index 00000000..53013be1
--- /dev/null
+++ b/idp-oidc-extension-impl/src/test/resources/net/shibboleth/idp/module/conf/metadata-policy-failing.json
@@ -0,0 +1,5 @@
+{
+ "grant_types": {
+ "bean": "alwaysFalsePolicyOperator"
+ }
+}
\ No newline at end of file
diff --git a/idp-oidc-extension-impl/src/test/resources/net/shibboleth/idp/module/conf/metadata-policy-invalidbean.json b/idp-oidc-extension-impl/src/test/resources/net/shibboleth/idp/module/conf/metadata-policy-invalidbean.json
new file mode 100644
index 00000000..274b4bb6
--- /dev/null
+++ b/idp-oidc-extension-impl/src/test/resources/net/shibboleth/idp/module/conf/metadata-policy-invalidbean.json
@@ -0,0 +1,5 @@
+{
+ "grant_types": {
+ "bean": "thisBeanNotFound"
+ }
+}
\ No newline at end of file
diff --git a/idp-oidc-extension-impl/src/test/resources/net/shibboleth/idp/module/conf/relying-party.xml b/idp-oidc-extension-impl/src/test/resources/net/shibboleth/idp/module/conf/relying-party.xml
index 89255cec..1d96c81f 100644
--- a/idp-oidc-extension-impl/src/test/resources/net/shibboleth/idp/module/conf/relying-party.xml
+++ b/idp-oidc-extension-impl/src/test/resources/net/shibboleth/idp/module/conf/relying-party.xml
@@ -302,6 +302,20 @@
</list>
</property>
</bean>
+ <bean parent="RelyingPartyByName" c:relyingPartyIds="alwaysFailingMetadataPolicy">
+ <property name="profileConfigurations">
+ <list>
+ <bean parent="OIDC.Registration" p:metadataPolicyLookupStrategy-ref="shibboleth.oidc.dynreg.AlwaysFailingMetadataPolicyLookupStrategy"/>
+ </list>
+ </property>
+ </bean>
+ <bean parent="RelyingPartyByName" c:relyingPartyIds="invalidBeanMetadataPolicy">
+ <property name="profileConfigurations">
+ <list>
+ <bean parent="OIDC.Registration" p:metadataPolicyLookupStrategy-ref="shibboleth.oidc.dynreg.InvalidBeanMetadataPolicyLookupStrategy"/>
+ </list>
+ </property>
+ </bean>
</util:list>
<bean id="shibboleth.oidc.dynreg.AnotherMetadataPolicyLookupStrategy"
@@ -309,4 +323,14 @@
c:resource="classpath:net/shibboleth/idp/module/conf/metadata-policy2.json"
c:id="AnotherProfileMetadataPolicyCache" />
+ <bean id="shibboleth.oidc.dynreg.AlwaysFailingMetadataPolicyLookupStrategy"
+ parent="shibboleth.oidc.dynreg.MetadataPolicyLookupStrategy"
+ c:resource="classpath:net/shibboleth/idp/module/conf/metadata-policy-failing.json"
+ c:id="AlwaysFailingUnregisteredClientPolicyCache" />
+
+ <bean id="shibboleth.oidc.dynreg.InvalidBeanMetadataPolicyLookupStrategy"
+ parent="shibboleth.oidc.dynreg.MetadataPolicyLookupStrategy"
+ c:resource="classpath:net/shibboleth/idp/module/conf/metadata-policy-invalidbean.json"
+ c:id="InvalidBeanUnregisteredClientPolicyCache" />
+
</beans>
diff --git a/idp-oidc-extension-impl/src/test/resources/net/shibboleth/idp/module/conf/unregistered-policy.json b/idp-oidc-extension-impl/src/test/resources/net/shibboleth/idp/module/conf/unregistered-policy.json
index 6ac45565..dd896844 100644
--- a/idp-oidc-extension-impl/src/test/resources/net/shibboleth/idp/module/conf/unregistered-policy.json
+++ b/idp-oidc-extension-impl/src/test/resources/net/shibboleth/idp/module/conf/unregistered-policy.json
@@ -6,7 +6,8 @@
"value": "openid info"
},
"redirect_uri": {
- "regexp": "^https:\/\/(?:([^.]+).)?example.org\/(.*)"
+ "regexp": "^https:\/\/(?:([^.]+).)?example.org\/(.*)",
+ "bean": "alwaysTruePolicyOperator"
},
"response_type": {
"one_of": ["code"]
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list