[java-idp-plugin-oidc-op-oidfed] branch main updated: Initial commit.
Henri Mikkonen
henri.mikkonen at iki.fi
Wed Sep 10 14:14:02 UTC 2025
This is an automated email from the git hooks/post-receive script.
hjmikkon pushed a commit to branch main
in repository java-idp-plugin-oidc-op-oidfed.
View the commit online:
http://git.shibboleth.net/view/?p=java-idp-plugin-oidc-op-oidfed.git;a=commit;h=8059db9ee80cc15ac102b41e408cbfdc7e3e38ae
The following commit(s) were added to refs/heads/main by this push:
new 8059db9 Initial commit.
8059db9 is described below
commit 8059db9ee80cc15ac102b41e408cbfdc7e3e38ae
Author: Henri Mikkonen <henri.mikkonen at iki.fi>
AuthorDate: Wed Sep 10 16:57:52 2025 +0300
Initial commit.
The code is mainly taken from the dev/JOIDC-222 branch of OP (java-idp-oidc). WIP.
---
.gitignore | 4 +-
idp-oidfed-op-api/.gitignore | 1 +
idp-oidfed-op-api/pom.xml | 126 +
.../config/RelyingPartyTrustChainContext.java | 212 +
.../oidfed/support/ClaimsSetExtensionSupport.java | 87 +
.../idp/plugin/oidc/op/oidfed/tbd/RequestUtil.java | 198 +
.../plugin/oidc/op/oidfed/tbd/ResponseUtil.java | 294 +
idp-oidfed-op-dist/.check-m2 | 1 +
idp-oidfed-op-dist/pom.xml | 87 +
.../src/main/assembly/assembly-tgz.xml | 72 +
.../src/main/enforcer/shibbolethKeys.gpg | Bin 0 -> 55669 bytes
.../src/main/resources/bootstrap/id.property | 1 +
.../src/main/resources/bootstrap/keys.txt | 375 +
idp-oidfed-op-impl/.gitignore | 1 +
idp-oidfed-op-impl/pom.xml | 515 +
.../idp/plugin/oidc/op/oidfed/OIDFedOPModule.java | 37 +
.../idp/plugin/oidc/op/oidfed/OIDFedOPPlugin.java | 49 +
...FederationRegistrationProfileConfiguration.java | 163 +
...erationResponseCachingProfileConfiguration.java | 89 +
.../CachedErrorResponseLifetimeLookupFunction.java | 45 +
...achedSuccessResponseLifetimeLookupFunction.java | 45 +
...nAutomaticRegistrationProfileConfiguration.java | 47 +
...ionEntityConfigurationProfileConfiguration.java | 199 +
...onExplicitRegistrationProfileConfiguration.java | 262 +
...ederationResolveEntityProfileConfiguration.java | 123 +
...nAutomaticRegistrationProfileConfiguration.java | 25 +
...ionEntityConfigurationProfileConfiguration.java | 68 +
...tityStatementProducingProfileConfiguration.java | 43 +
...onExplicitRegistrationProfileConfiguration.java | 52 +
.../config/OIDFederationProfileConfiguration.java | 23 +
...FederationRegistrationProfileConfiguration.java | 66 +
...ederationResolveEntityProfileConfiguration.java | 52 +
...erationResponseCachingProfileConfiguration.java | 47 +
.../config/RelyingPartyConfigurationSupport.java | 60 +
.../TokenEndpointAuthMethodLookupFunction.java | 55 +
.../oidfed/config/TrustAnchorIdLookupFunction.java | 74 +
.../op/oidfed/config/TrustAnchorIdPredicate.java | 96 +
.../decoding/impl/BaseOAuth2RequestDecoder.java | 117 +
.../ExplicitClientRegistrationRequestDecoder.java | 134 +
.../decoding/impl/ResolveEntityRequestDecoder.java | 98 +
.../impl/ExplicitClientRegistrationRequest.java | 100 +
.../impl/ExplicitClientRegistrationResponse.java | 97 +
.../messaging/impl/ResolveEntityRequest.java | 135 +
.../messaging/impl/ResolveEntityResponse.java | 99 +
...actTrustEngineSignatureValidationComponent.java | 104 +
...mbinedMetadataFromTrustChainLookupStrategy.java | 109 +
...faultEntityConfigurationCredentialResolver.java | 87 +
...ityConfigurationEndpointExtractionStrategy.java | 82 +
...onfigurationMetadataSkeletonLookupStrategy.java | 84 +
...ionResponseContainerExpirationTimeStrategy.java | 59 +
...ntityConfigurationResponseFetchingStrategy.java | 59 +
...faultEntityStatementExpirationTimeStrategy.java | 48 +
.../DefaultEntityStatementFetchingStrategy.java | 155 +
...StatementSignatureValidationFilterStrategy.java | 62 +
...atementSubjectIdentifierExtractionStrategy.java | 40 +
...IssuerEntityIDCriteriaToIdentifierStrategy.java | 42 +
.../DefaultLocalTrustAnchorCredentialResolver.java | 107 +
.../DefaultLocalTrustAnchorsValidator.java | 58 +
...DefaultPayloadJOSEObjectCredentialResolver.java | 71 +
...efaultProvidedTrustChainValidationStrategy.java | 159 +
...eEntityRequestCriteriaToIdentifierStrategy.java | 42 +
...ityResponseContainerExpirationTimeStrategy.java | 59 +
...faultResolveEntityResponseFetchingStrategy.java | 65 +
...EntityResponseIdentifierExtractionStrategy.java | 38 +
...ubjectEntityIDCriteriaToIdentifierStrategy.java | 42 +
...aultSubordinateStatementCredentialResolver.java | 103 +
...inateStatementCriteriaToIdentifierStrategy.java | 93 +
...rdinateStatementEndpointExtractionStrategy.java | 149 +
...inateStatementIdentifierExtractionStrategy.java | 43 +
...StatementSignatureValidationFilterStrategy.java | 116 +
...ustAnchorSignatureValidationFilterStrategy.java | 100 +
.../DefaultTrustChainExpirationTimeStrategy.java | 60 +
.../DefaultTrustChainFetchingStrategy.java | 382 +
...stChainSubjectIdentifierExtractionStrategy.java | 45 +
...DefaultTrustChainTrustMarksParsingStrategy.java | 109 +
...ChainTrustedTrustMarkIssuersLookupStrategy.java | 114 +
...tChainTrustedTrustMarkOwnersLookupStrategy.java | 103 +
.../DefaultTrustMarkOwnerCredentialResolver.java | 97 +
.../op/oidfed/metadata/EntityStatementHelper.java | 163 +
.../oidfed/metadata/IssuerEntityIDCriterion.java | 77 +
.../metadata/IssuerEntityStatementCriterion.java | 79 +
.../op/oidfed/metadata/JWKSetDeserializer.java | 57 +
.../oidc/op/oidfed/metadata/LocalKeyContainer.java | 53 +
.../oidfed/metadata/NimbusResponseContainer.java | 70 +
.../oidfed/metadata/NimbusResponseCriterion.java | 80 +
.../metadata/PreSelectedTrustChainCriterion.java | 80 +
.../metadata/ResolveEntityRequestCriterion.java | 80 +
.../metadata/ResolveEntityResponseContainer.java | 60 +
.../ResponseContainerExpirationCriterion.java | 79 +
.../oidfed/metadata/SubjectEntityIDCriterion.java | 79 +
.../metadata/SubjectEntityStatementCriterion.java | 79 +
.../SubjectLocallyTrustedKeysCriterion.java | 79 +
.../metadata/TrustAnchorEntityIDsCriterion.java | 80 +
.../oidfed/metadata/TrustMarkOwnersCriterion.java | 80 +
.../constraints/FederationPolicyConstraint.java | 37 +
.../FederationPolicyConstraintHelper.java | 73 +
.../impl/AbstractFederationPolicyConstraint.java | 79 +
.../impl/DefaultAllowedEntityTypesConstraint.java | 106 +
.../impl/DefaultMaxPathLengthConstraint.java | 66 +
.../impl/DefaultNamingConstraintsConstraint.java | 118 +
.../FederationMetadataPolicyDeserializer.java | 159 +
.../policy/FederationMetadataPolicyHelper.java | 80 +
.../policy/FederationMetadataPolicyOperator.java | 49 +
.../AbstractFederationMetadataPolicyOperator.java | 56 +
...DefaultFederationMetadataPolicyAddOperator.java | 109 +
...ultFederationMetadataPolicyDefaultOperator.java | 38 +
.../DefaultFederationMetadataPolicyEnforcer.java | 95 +
...tFederationMetadataPolicyEssentialOperator.java | 40 +
...ultFederationMetadataPolicyMergingStrategy.java | 102 +
...faultFederationMetadataPolicyOneOfOperator.java | 66 +
...ltFederationMetadataPolicySubsetOfOperator.java | 88 +
...FederationMetadataPolicySupersetOfOperator.java | 86 +
...faultFederationMetadataPolicyValueOperator.java | 82 +
.../idp/plugin/oidc/op/oidfed/package-info.java | 18 +
.../impl/AbstractBuildEntityStatementAction.java | 309 +
.../impl/AbstractTrustChainResolutionAction.java | 312 +
...stChainAuthorizationCodeClaimsSetDecorator.java | 75 +
...eredTrustChainRequestUriClaimsSetDecorator.java | 73 +
.../profile/impl/BuildEntityConfiguration.java | 148 +
.../impl/BuildExplicitRegistrationResponse.java | 223 +
.../BuildResolveEntityErrorResponseFromEvent.java | 269 +
.../profile/impl/BuildResolveEntityResponse.java | 226 +
.../profile/impl/EntityStatementContext.java | 109 +
.../impl/EntityStatementUpdateStrategy.java | 59 +
.../impl/FormExplicitRegistrationResponse.java | 118 +
...ormOutboundFederationConfigurationResponse.java | 225 +
.../impl/FormOutboundResolveEntityResponse.java | 231 +
.../op/oidfed/profile/impl/GenerateClientID.java | 140 +
.../impl/InitializeEntityStatementContext.java | 197 +
...ClaimsSetFromEntityStatementLookupFunction.java | 87 +
.../LookupCachedEntityConfigurationResponse.java | 142 +
.../impl/LookupCachedResolveEntityResponse.java | 158 +
.../oidfed/profile/impl/OidFederationEventIds.java | 67 +
.../impl/RelyingPartyCachedMessageContext.java | 77 +
.../impl/RelyingPartyTrustChainContext.java | 212 +
.../op/oidfed/profile/impl/ResolveTrustChains.java | 263 +
.../op/oidfed/profile/impl/ResolveTrustMarks.java | 553 +
.../op/oidfed/profile/impl/SelectTrustChain.java | 174 +
.../profile/impl/StoreAutomaticRegistration.java | 190 +
...eAutomaticRegistrationProfileConfiguration.java | 265 +
.../profile/impl/ValidateProvidedTrustChain.java | 144 +
.../profile/impl/ValidateResolveEntityRequest.java | 187 +
.../profile/impl/ValidateSelectedTrustChain.java | 231 +
...ltAutomaticRegistrationActivationCondition.java | 87 +
.../AbstractTrustChainContextLookupFunction.java | 83 +
.../navigate/AuthorityHintsLookupFunction.java | 48 +
...rizePreSelectedTrustChainIDsLookupStrategy.java | 49 +
.../navigate/DefaultEntityTypesLookupFunction.java | 46 +
.../DefaultLocalMetadataPolicyMergingStrategy.java | 112 +
.../DefaultMetadataValidationCondition.java | 81 +
...aultPreSelectedTrustChainIDsLookupStrategy.java | 119 +
...DefaultSelectedTrustChainIDsLookupStrategy.java | 64 +
...dTrustChainImmediateSuperiorLookupStrategy.java | 42 +
...ltSelectedTrustChainMetadataLookupStrategy.java | 54 +
...electedTrustChainTrustAnchorLookupStrategy.java | 41 +
.../DefaultTrustChainIDsLookupStrategy.java | 43 +
...ultTrustChainMetadataPolicyMergingStrategy.java | 200 +
.../DefaultTrustChainSelectionStrategy.java | 93 +
...laimsSetManipulationStrategyLookupFunction.java | 52 +
.../EntityStatementLifetimeLookupFunction.java | 51 +
...tRegistrationRequestClientIDLookupFunction.java | 68 +
...entRegistrationRequestJWKSetLookupFunction.java | 69 +
...egistrationRequestTrustChainLookupFunction.java | 50 +
.../LocalMetadataPolicyLookupFunction.java | 49 +
.../MandatoryTrustMarksLookupFunction.java | 48 +
.../MaximumTrustMarkLifetimeLookupFunction.java | 52 +
.../META-INF/net.shibboleth.idp/postconfig.xml | 514 +
.../oidfed/metadata-lookup-ext-oidfed-beans.xml | 126 +
.../oidfed/metadata-lookup-ext-oidfed-flow.xml | 50 +
.../entity-configuration-beans.xml | 165 +
.../entity-configuration-flow.xml | 39 +
.../idp/flows/oidfed/register/register-beans.xml | 360 +
.../idp/flows/oidfed/register/register-flow.xml | 60 +
.../oidfed/resolve-entity/resolve-entity-beans.xml | 216 +
.../oidfed/resolve-entity/resolve-entity-flow.xml | 77 +
.../idp/service/relying-party/postconfig.xml | 85 +
.../services/net.shibboleth.idp.module.IdPModule | 1 +
.../services/net.shibboleth.idp.plugin.IdPPlugin | 2 +
.../op/oidfed/conf/attributes/oidc-claim-rules.xml | 428 +
.../oidc/op/oidfed/conf/authn/oidc-credentials.xml | 68 +
.../authn/oidc-rp-client-secret-credential.xml | 20 +
.../oidc/op/oidfed/conf/authn/oidc-rp-config.xml | 14 +
.../authn/oidc-rp-providermetadata-resolvers.xml | 34 +
.../oidc/op/oidfed/conf/authn/oidc-rp.properties | 82 +
.../authn/providermetadata-resolver-system.xml | 87 +
.../idp/plugin/oidc/op/oidfed/module.properties | 13 +
.../idp/plugin/oidc/op/oidfed/plugin.properties | 6 +
.../resources/templates/oidc-request-form-post.vm | 62 +
.../plugin/oidc/op/oidfed/TrustChainTestUtil.java | 124 +
.../flow/oidfed/AbstractFederationFlowTest.java | 574 +
.../profile/flow/oidfed/AbstractOidcFlowTest.java | 724 +
.../AuthorizeFlowAutomaticRegistrationTest.java | 480 +
.../flow/oidfed/EntityConfigurationFlowTest.java | 116 +
...shedAuthorizeFlowAutomaticRegistrationTest.java | 489 +
.../profile/flow/oidfed/RegistrationFlowTest.java | 342 +
.../profile/flow/oidfed/ResolveEntityFlowTest.java | 122 +
.../resources/credentials/fed-local-anchor.jwk | 13 +
.../resources/credentials/fed-signing-es256.jwk | 10 +
.../resources/credentials/fed-signing-es384.jwk | 9 +
.../resources/credentials/fed-signing-es521.jwk | 9 +
.../test/resources/credentials/fed-signing-rs.jwk | 8 +
.../idp/module/conf/attribute-filter.xml | 188 +
.../idp/module/conf/attribute-registry.xml | 28 +
.../idp/module/conf/attribute-resolver.xml | 111 +
.../module/conf/attributes/custom/mail.properties | 4 +
.../conf/authn/oauth2client-authn-config.xml | 30 +
.../net/shibboleth/idp/module/conf/credentials.xml | 70 +
.../net/shibboleth/idp/module/conf/global.xml | 92 +
.../net/shibboleth/idp/module/conf/idp.properties | 209 +
.../net/shibboleth/idp/module/conf/logback.xml | 197 +
.../idp/module/conf/metadata-policy1.json | 21 +
.../idp/module/conf/metadata-providers.xml | 28 +
.../idp/module/conf/oidc-clientinfo-resolvers.xml | 22 +
.../idp/module/conf/oidc-credentials.xml | 101 +
.../net/shibboleth/idp/module/conf/oidc.properties | 40 +
.../conf/oidfed-entity-configuration-metadata.json | 7 +
.../module/conf/oidfed/oidfed-trust-anchors.json | 13 +
.../idp/module/conf/openid-configuration.json | 41 +
.../shibboleth/idp/module/conf/relying-party.xml | 100 +
.../net/shibboleth/idp/module/conf/services.xml | 92 +
.../idp/module/conf/unregistered-policy.json | 15 +
.../idp/module/credentials/ldap-server.crt | 13 +
.../metadata-policy-test-vectors-2025-02-13.json | 50299 +++++++++++++++++++
pom.xml | 216 +
resources/checkstyle/checkstyle.xml | 122 +
225 files changed, 75034 insertions(+), 1 deletion(-)
diff --git a/.gitignore b/.gitignore
index d886f26..4a7ddca 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,9 +5,11 @@
.DS_store
# Simulated Subversion default ignores end here
# The contents of the svn:ignore property on the branch root.
-/test-output
+*/test-output
/target
+/idp-oidfed-op-impl/classpath:
.vscode
.classpath
.project
.settings
+/idp-oidfed-op-impl/src/test/resources/conf/local-log-config.properties
diff --git a/idp-oidfed-op-api/.gitignore b/idp-oidfed-op-api/.gitignore
new file mode 100644
index 0000000..b83d222
--- /dev/null
+++ b/idp-oidfed-op-api/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/idp-oidfed-op-api/pom.xml b/idp-oidfed-op-api/pom.xml
new file mode 100644
index 0000000..3fa65ef
--- /dev/null
+++ b/idp-oidfed-op-api/pom.xml
@@ -0,0 +1,126 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>net.shibboleth.idp.plugin.oidfed</groupId>
+ <artifactId>idp-plugin-oidfed-op-parent</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>idp-plugin-oidfed-op-api</artifactId>
+ <packaging>jar</packaging>
+ <name>Shibboleth IdP :: Plugins :: OpenID Federation plugin for OpenID Provider API</name>
+ <description>IdP OIDFED plugin for OP API.</description>
+
+ <properties>
+ <checkstyle.configLocation>${project.basedir}/../resources/checkstyle/checkstyle.xml</checkstyle.configLocation>
+ <automatic.module.name>net.shibboleth.idp.plugin.authn.oidfed.op.api</automatic.module.name>
+ </properties>
+
+ <dependencies>
+ <!-- Provided dependencies -->
+ <dependency>
+ <groupId>${oidc-op.groupId}</groupId>
+ <artifactId>idp-plugin-oidc-op-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${oidc-common.groupId}</groupId>
+ <artifactId>oidc-common-crypto-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${oidc-common.groupId}</groupId>
+ <artifactId>oidc-common-profile-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${oidc-common.groupId}</groupId>
+ <artifactId>oidc-common-metadata-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${idp.groupId}</groupId>
+ <artifactId>idp-authn-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${shib-profile.groupId}</groupId>
+ <artifactId>shib-profile-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${opensaml.groupId}</groupId>
+ <artifactId>opensaml-messaging-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${opensaml.groupId}</groupId>
+ <artifactId>opensaml-security-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${opensaml.groupId}</groupId>
+ <artifactId>opensaml-profile-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${shib-shared.groupId}</groupId>
+ <artifactId>shib-support</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.nimbusds</groupId>
+ <artifactId>content-type</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.nimbusds</groupId>
+ <artifactId>nimbus-jose-jwt</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.google.code.findbugs</groupId>
+ <artifactId>jsr305</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>net.minidev</groupId>
+ <artifactId>json-smart</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-core</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.nimbusds</groupId>
+ <artifactId>oauth2-oidc-sdk</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${oidc-common.groupId}</groupId>
+ <artifactId>oidc-common-profile-impl</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>jakarta.servlet</groupId>
+ <artifactId>jakarta.servlet-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+
+</project>
diff --git a/idp-oidfed-op-api/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/RelyingPartyTrustChainContext.java b/idp-oidfed-op-api/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/RelyingPartyTrustChainContext.java
new file mode 100644
index 0000000..11995c3
--- /dev/null
+++ b/idp-oidfed-op-api/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/RelyingPartyTrustChainContext.java
@@ -0,0 +1,212 @@
+/*
+ * 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.oidfed.config;
+
+import java.time.Instant;
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.messaging.context.BaseContext;
+
+import com.nimbusds.jwt.SignedJWT;
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import net.shibboleth.shared.collection.Pair;
+
+/**
+ * Subcontext carrying information for trust chains related to a relying party.
+ *
+ * @since 4.3.0
+ */
+public final class RelyingPartyTrustChainContext extends BaseContext {
+
+ /** All resolved trust chains for the relying party. */
+ @Nullable private List<List<EntityStatement>> resolvedTrustChains;
+
+ /** Policy-compliant trust chains for the relying party. */
+ @Nullable private List<Pair<List<EntityStatement>,Map<String,Map<String,Object>>>> policyCompliantTrustChains;
+
+ /** Selected trust chain for the relying party. */
+ @Nullable private Pair<List<EntityStatement>,Map<String,Map<String,Object>>> selectedTrustChain;
+
+ /** Expiration instant for the selected metadata. */
+ @Nullable private Instant selectedMetadataExpiration;
+
+ /** Verified trust mark IDs for the selected trust chain. */
+ @Nullable private Map<String, List<String>> verifiedTrustMarkIds;
+
+ /** Verified trust marks for the selected trust chain. */
+ @Nullable private Map<String, List<SignedJWT>> verifiedTrustMarks;
+
+ /** All previously selected but rejected trust chains. */
+ @Nullable private List<List<EntityStatement>> rejectedTrustChains;
+
+ /**
+ * Get the resolved trust chains for the relying party.
+ *
+ * @return the trust chains
+ */
+ @Nullable public List<List<EntityStatement>> getResolvedTrustChains() {
+ return resolvedTrustChains;
+ }
+
+ /**
+ * Set the resolved trust chains for the relying party.
+ *
+ * @param trustChains the trust chains
+ *
+ * @return this context
+ */
+ @Nonnull public RelyingPartyTrustChainContext setResolvedTrustChains(
+ @Nullable final List<List<EntityStatement>> trustChains) {
+ resolvedTrustChains = trustChains;
+ return this;
+ }
+
+ /**
+ * Get the policy-compliant trust chains for the relying party.
+ *
+ * @return the trust chains
+ */
+ @Nullable public List<Pair<List<EntityStatement>,Map<String,Map<String,Object>>>> getPolicyCompliantTrustChains() {
+ return policyCompliantTrustChains;
+ }
+
+ /**
+ * Set the policy-compliant trust chains for the relying party.
+ *
+ * @param chains the trust chains and client informations
+ *
+ * @return this context
+ */
+ @Nonnull public RelyingPartyTrustChainContext setPolicyCompliantTrustChains(
+ @Nullable final List<Pair<List<EntityStatement>,Map<String,Map<String,Object>>>> chains) {
+ policyCompliantTrustChains = chains;
+ return this;
+ }
+
+ /**
+ * Get the selected trust chain for the relying party.
+ *
+ * @return the trust chain
+ */
+ @Nullable public Pair<List<EntityStatement>,Map<String,Map<String,Object>>> getSelectedTrustChain() {
+ return selectedTrustChain;
+ }
+
+ /**
+ * Set the selected trust chain for the relying party.
+ *
+ * @param chain the selected trust chain
+ *
+ * @return this context
+ */
+ @Nonnull public RelyingPartyTrustChainContext setSelectedTrustChains(
+ @Nullable final Pair<List<EntityStatement>,Map<String,Map<String,Object>>> chain) {
+ selectedTrustChain = chain;
+ return this;
+ }
+
+ /**
+ * Get the expiration instant for the selected metadata.
+ *
+ * @return the expiration instant
+ */
+ @Nullable public Instant getSelectedMetadataExpiration() {
+ return selectedMetadataExpiration;
+ }
+
+ /**
+ * Set the expiration instant for the selected metadata.
+ *
+ * @param expiration the expiration instant
+ *
+ * @return this context
+ */
+ @Nonnull public RelyingPartyTrustChainContext setSelectedMetadataExpiration(@Nullable final Instant expiration) {
+ selectedMetadataExpiration = expiration;
+ return this;
+ }
+
+ /**
+ * Get the verified trust mark IDs for the selected trust chain.
+ *
+ * @return verified trust mark IDs
+ */
+ @Nullable public Map<String, List<String>> getVerifiedTrustMarkIds() {
+ return verifiedTrustMarkIds;
+ }
+
+ /**
+ * Set the verified trust mark IDs for the selected trust chain.
+ *
+ * @param ids verified trust mark IDs
+ *
+ * @return this context
+ */
+ @Nonnull public RelyingPartyTrustChainContext setVerifiedTrustMarkIds(
+ @Nullable final Map<String, List<String>> ids) {
+ verifiedTrustMarkIds = ids;
+ return this;
+ }
+
+ /**
+ * Get the verified trust marks for the selected trust chain.
+ *
+ * @return verified trust marks
+ */
+ @Nullable public Map<String, List<SignedJWT>> getVerifiedTrustMarks() {
+ return verifiedTrustMarks;
+ }
+
+ /**
+ * Set the verified trust marks for the selected trust chain.
+ *
+ * @param trustMarks verified trust marks
+ *
+ * @return this context
+ */
+ @Nonnull public RelyingPartyTrustChainContext setVerifiedTrustMarks(
+ @Nullable final Map<String, List<SignedJWT>> trustMarks) {
+ verifiedTrustMarks = trustMarks;
+ return this;
+ }
+
+ /**
+ * Get the previously selected but rejected trust chains for the relying party.
+ *
+ * @return the trust chains
+ */
+ @Nullable public List<List<EntityStatement>> getRejectedTrustChains() {
+ return rejectedTrustChains;
+ }
+
+ /**
+ * Set the previously selected but rejected trust chains for the relying party.
+ *
+ * @param trustChains the trust chains
+ *
+ * @return this context
+ */
+ @Nonnull public RelyingPartyTrustChainContext setRejectedTrustChains(
+ @Nullable final List<List<EntityStatement>> trustChains) {
+ rejectedTrustChains = trustChains;
+ return this;
+ }
+
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-api/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/support/ClaimsSetExtensionSupport.java b/idp-oidfed-op-api/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/support/ClaimsSetExtensionSupport.java
new file mode 100644
index 0000000..8b2a154
--- /dev/null
+++ b/idp-oidfed-op-api/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/support/ClaimsSetExtensionSupport.java
@@ -0,0 +1,87 @@
+/*
+ * 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.oidfed.support;
+
+import java.text.ParseException;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+
+import com.nimbusds.jwt.JWTClaimsSet;
+
+import net.shibboleth.idp.plugin.oidc.op.token.support.TokenClaimsSet;
+import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+/**
+ * Helper methods for claims set extensions related to OpenID federation.
+ */
+public class ClaimsSetExtensionSupport {
+
+ /** Identifier for trust chain used when client was registered via OID federation. */
+ @Nonnull @NotEmpty public static final String KEY_AUTO_REGISTERED_TRUST_CHAIN = "oidfed_artc";
+
+ /** Class logger. */
+ @Nonnull private static Logger log = LoggerFactory.getLogger(ClaimsSetExtensionSupport.class);
+
+ /**
+ * Parse automatically registered trust chain from the given token claims set.
+ *
+ * @param claimsSet token claims set
+ * @return automatically registered trust chain
+ */
+ @Nullable public static List<String> parseAutoRegisteredTrustChain(@Nonnull final TokenClaimsSet claimsSet) {
+ return parseAutoRegisteredTrustChain(claimsSet.getClaimsSet());
+ }
+
+ /**
+ * Parse automatically registered trust chain from the given JWT claims set.
+ *
+ * @param claimsSet JWT claims set
+ * @return automatically registered trust chain
+ */
+ @Nullable public static List<String> parseAutoRegisteredTrustChain(@Nonnull final JWTClaimsSet claimsSet) {
+ try {
+ return claimsSet.getStringListClaim(KEY_AUTO_REGISTERED_TRUST_CHAIN);
+ } catch (final ParseException e) {
+ log.warn("Could not parse auto registered trust chain from the claims set", e);
+ }
+ return null;
+ }
+
+ /**
+ * Parse automatically registered trust chain from the given map pf claims
+ *
+ * @param claimsSet map of claims
+ * @return automatically registered trust chain
+ */
+ @Nullable public static List<String> parseAutoRegisteredTrustChain(@Nonnull final Map<String,Object> claimsSet) {
+ return Optional.ofNullable(claimsSet.get(KEY_AUTO_REGISTERED_TRUST_CHAIN))
+ .filter(List.class::isInstance)
+ .map(List.class::cast)
+ .map(list -> ((List<?>)list).stream()
+ .filter(Objects::nonNull)
+ .map(Objects::toString)
+ .toList())
+ .orElse(null);
+ }
+
+}
diff --git a/idp-oidfed-op-api/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/tbd/RequestUtil.java b/idp-oidfed-op-api/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/tbd/RequestUtil.java
new file mode 100644
index 0000000..6730570
--- /dev/null
+++ b/idp-oidfed-op-api/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/tbd/RequestUtil.java
@@ -0,0 +1,198 @@
+/*
+ * 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.oidfed.tbd;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.annotation.Nullable;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.base.MoreObjects;
+import com.nimbusds.oauth2.sdk.AuthorizationCodeGrant;
+import com.nimbusds.oauth2.sdk.AuthorizationGrant;
+import com.nimbusds.oauth2.sdk.ClientCredentialsGrant;
+import com.nimbusds.oauth2.sdk.RefreshTokenGrant;
+import com.nimbusds.oauth2.sdk.auth.ClientAuthentication;
+import com.nimbusds.oauth2.sdk.http.HTTPRequest;
+import com.nimbusds.oauth2.sdk.token.AccessToken;
+import com.nimbusds.oauth2.sdk.token.RefreshToken;
+
+/** Request logging helper class. */
+public final class RequestUtil {
+
+ /** Private constructor. */
+ private RequestUtil() {
+
+ }
+
+ /**
+ * Helper method to print request to string for logging.
+ *
+ * @param httpReq request to be printed
+ * @return request as formatted string.
+ */
+ @Nullable public static String toString(@Nullable final HTTPRequest httpReq) {
+ if (httpReq == null) {
+ return null;
+ }
+ final String nl = System.lineSeparator();
+ String ret = httpReq.getMethod().toString() + nl;
+ final Map<String, List<String>> headers = httpReq.getHeaderMap();
+ if (headers != null) {
+ ret += "Headers:" + nl;
+ for (final Entry<String, List<String>> entry : headers.entrySet()) {
+ ret += "\t" + entry.getKey() + ":" + entry.getValue() + nl;
+ }
+ }
+ final Map<String, List<String>> parameters = httpReq.getQueryParameters();
+ if (parameters != null) {
+ ret += "Parameters:" + nl;
+ for (final Entry<String, List<String>> entry : parameters.entrySet()) {
+ final List<String> values = entry.getValue();
+ for (int i = 0; values != null && i < values.size(); i++) {
+ ret += "\t" + entry.getKey() + ":" + values.get(i) + nl;
+ }
+ }
+ }
+ return ret;
+ }
+
+ /**
+ * Helper method to print request to string for logging.
+ *
+ * @param httpReq request to be printed
+ * @param objectMapper object mapper used for pretty printing JSON content
+ * @return request as formatted string.
+ *
+ * @since 4.1.0
+ */
+ @Nullable public static String toString(@Nullable final HTTPRequest httpReq,
+ @Nullable final ObjectMapper objectMapper) {
+ if (httpReq == null) {
+ return null;
+ }
+ final String nl = System.lineSeparator();
+ String ret = httpReq.getMethod().toString() + nl;
+ final Map<String, List<String>> headers = httpReq.getHeaderMap();
+ if (headers != null) {
+ ret += "Headers:" + nl;
+ for (final Entry<String, List<String>> entry : headers.entrySet()) {
+ ret += "\t" + entry.getKey() + ":" + entry.getValue() + nl;
+ }
+ }
+ final Map<String, List<String>> parameters = httpReq.getQueryParameters();
+ if (parameters != null) {
+ if (objectMapper != null && !parameters.isEmpty()) {
+ final String rawValue = parameters.keySet().iterator().next();
+ try {
+ final Object jsonObject = objectMapper.readValue(rawValue, Object.class);
+ final String content = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonObject);
+ return ret + "Content:" + content.replace("\n", "\n\t");
+ } catch (JsonProcessingException e) {
+ // fall-back into not using object mapper
+ }
+
+ }
+ ret += "Parameters:" + nl;
+ for (final Entry<String, List<String>> entry : parameters.entrySet()) {
+ ret += "\t" + entry.getKey() + ":" + entry.getValue().get(0) + nl;
+ }
+ }
+ return ret;
+ }
+
+ /**
+ * Helper method for getting protocol log message for client authentication object.
+ *
+ * @param authentication The client authentication object
+ * @return The log message
+ */
+ @Nullable public static String getClientAuthenticationLog(@Nullable final ClientAuthentication authentication) {
+ return authentication == null ? null : MoreObjects.toStringHelper("ClientAuthentication").omitNullValues()
+ .add("clientId", authentication.getClientID())
+ .add("method", authentication.getMethod())
+ .toString();
+ }
+
+ /**
+ * Helper method for getting protocol log message for access token object.
+ *
+ * @param accessToken The access token object
+ * @return The log message
+ */
+ @Nullable public static String getAccessTokenLog(@Nullable final AccessToken accessToken) {
+ return accessToken == null ? null : MoreObjects.toStringHelper("AccessToken").omitNullValues()
+ .add("lifetime", accessToken.getLifetime())
+ .add("issuedTokenType", accessToken.getIssuedTokenType())
+ .add("parameterNames", accessToken.getParameterNames())
+ .add("scope", accessToken.getScope())
+ .add("value", accessToken.getValue())
+ .add("type", accessToken.getType())
+ .toString();
+ }
+
+ /**
+ * Helper method for getting protocol log message for authorization grant object.
+ *
+ * @param grant The authorization grant object
+ * @return The log message
+ */
+ @Nullable public static String getAuthorizationGrantLog(@Nullable final AuthorizationGrant grant) {
+ if (grant == null) {
+ return null;
+ }
+ if (grant instanceof AuthorizationCodeGrant) {
+ final AuthorizationCodeGrant codeGrant = (AuthorizationCodeGrant) grant;
+ return MoreObjects.toStringHelper(codeGrant).omitNullValues()
+ .add("authorizationCode", codeGrant.getAuthorizationCode())
+ .add("codeVerifier", codeGrant.getCodeVerifier())
+ .add("redirectionURI", codeGrant.getRedirectionURI())
+ .add("type", codeGrant.getType())
+ .toString();
+ } else if (grant instanceof RefreshTokenGrant) {
+ final RefreshTokenGrant refreshGrant = (RefreshTokenGrant) grant;
+ return MoreObjects.toStringHelper(refreshGrant).omitNullValues()
+ .add("refreshToken", getRefreshTokenLog(refreshGrant.getRefreshToken()))
+ .add("type", refreshGrant.getType())
+ .toString();
+ } else if (grant instanceof ClientCredentialsGrant) {
+ final ClientCredentialsGrant credentialsGrant = (ClientCredentialsGrant) grant;
+ return MoreObjects.toStringHelper(credentialsGrant).omitNullValues()
+ .add("type", credentialsGrant.getType())
+ .toString();
+
+ }
+ return MoreObjects.toStringHelper(grant).omitNullValues()
+ .add("type", grant.getType())
+ .toString();
+ }
+
+ /**
+ * Helper method for getting protocol log message for refresh token object.
+ *
+ * @param refreshToken The refresh token object
+ * @return The log message
+ */
+ @Nullable public static String getRefreshTokenLog(@Nullable final RefreshToken refreshToken) {
+ return refreshToken == null ? null : MoreObjects.toStringHelper("RefreshToken").omitNullValues()
+ .add("parameterNames", refreshToken.getParameterNames())
+ .add("value", refreshToken.getValue())
+ .toString();
+ }
+
+}
diff --git a/idp-oidfed-op-api/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/tbd/ResponseUtil.java b/idp-oidfed-op-api/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/tbd/ResponseUtil.java
new file mode 100644
index 0000000..f993d1b
--- /dev/null
+++ b/idp-oidfed-op-api/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/tbd/ResponseUtil.java
@@ -0,0 +1,294 @@
+/*
+ * 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.oidfed.tbd;
+
+import java.text.ParseException;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.base.MoreObjects;
+import com.nimbusds.jwt.JWT;
+import com.nimbusds.jwt.JWTClaimsSet;
+import com.nimbusds.oauth2.sdk.AccessTokenResponse;
+import com.nimbusds.oauth2.sdk.ErrorObject;
+import com.nimbusds.oauth2.sdk.ErrorResponse;
+import com.nimbusds.oauth2.sdk.Response;
+import com.nimbusds.oauth2.sdk.TokenErrorResponse;
+import com.nimbusds.oauth2.sdk.TokenResponse;
+import com.nimbusds.oauth2.sdk.http.HTTPResponse;
+import com.nimbusds.openid.connect.sdk.claims.IDTokenClaimsSet;
+import com.nimbusds.openid.connect.sdk.claims.LogoutTokenClaimsSet;
+
+import jakarta.servlet.http.HttpServletResponse;
+import net.shibboleth.oidc.profile.messaging.JSONSuccessResponse;
+
+/** Response logging helper class. */
+public final class ResponseUtil {
+
+ /** Private constructor. */
+ private ResponseUtil() {
+
+ }
+
+ /**
+ * Helper method to print response to string for logging.
+ *
+ * @param httpResponse response to be printed
+ * @return response as formatted string.
+ */
+ protected static String toString(@Nullable final HTTPResponse httpResponse) {
+ return toString(httpResponse, null);
+ }
+
+ /**
+ * Helper method to print response to string for logging.
+ *
+ * @param httpResponse response to be printed
+ * @param objectMapper object mapper used for pretty printing JSON content
+ * @return response as formatted string
+ *
+ * @since 4.1.0
+ */
+ protected static String toString(@Nullable final HTTPResponse httpResponse,
+ @Nullable final ObjectMapper objectMapper) {
+ if (httpResponse == null) {
+ return null;
+ }
+ final String nl = System.lineSeparator();
+ String ret = nl;
+ final Map<String, List<String>> headers = httpResponse.getHeaderMap();
+ if (headers != null) {
+ ret += "Headers:" + nl;
+ for (final Entry<String, List<String>> entry : headers.entrySet()) {
+ ret += "\t" + entry.getKey() + ":" + entry.getValue().get(0) + nl;
+ }
+ }
+ final String rawContent = httpResponse.getContent();
+ if (rawContent != null) {
+ if (objectMapper != null) {
+ try {
+ final Object jsonObject = objectMapper.readValue(rawContent, Object.class);
+ final String content = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonObject);
+ ret += "Content:" + content.replace("\n", "\n\t");
+ return ret;
+ } catch (JsonProcessingException e) {
+ // fall-back into not using object mapper
+ }
+ }
+ ret += "Content:" + rawContent;
+ }
+ return ret;
+ }
+
+ /**
+ * Helper method to print response to string for logging.
+ *
+ * @param httpServletResponse response to be printed
+ * @param content message content
+ *
+ * @return response as formatted string.
+ */
+ @Nullable protected static String toString(@Nullable final HttpServletResponse httpServletResponse,
+ @Nullable final String content) {
+ if (httpServletResponse == null) {
+ return null;
+ }
+ final String nl = System.lineSeparator();
+ String ret = nl;
+ final Collection<String> headerNames = httpServletResponse.getHeaderNames();
+ if (headerNames != null) {
+ ret += "Headers:" + nl;
+ for (final String headerName : headerNames) {
+ ret += "\t" + headerName + ":" + httpServletResponse.getHeader(headerName) + nl;
+ }
+ }
+ if (content != null) {
+ ret += "Content:" + content;
+ }
+ return ret;
+ }
+
+ // Checkstyle: CyclomaticComplexity|ReturnCount OFF
+
+ /**
+ * Helper method for getting protocol message for a Nimbus response object. This method can currently
+ * recognize success and error responses for OIDC authentication, token, userinfo, introspection and
+ * revocation.
+ *
+ * @param response The response message
+ * @return The response message specific log message
+ */
+ @Nullable public static String getProtocolMessage(@Nullable final Response response) {
+ if (response == null) {
+ return null;
+ }
+ if (response instanceof JSONSuccessResponse) {
+ return getProtocolMessageForJSONSuccessResponse(response);
+ } else if (response instanceof ErrorResponse) {
+ final ErrorResponse genericError = (ErrorResponse) response;
+ return MoreObjects.toStringHelper(genericError).omitNullValues()
+ .add("errorObject", genericError.getErrorObject())
+ .toString();
+ }
+ return MoreObjects.toStringHelper(response).toString();
+ }
+ // Checkstyle: CyclomaticComplexity|ReturnCount ON
+
+ /**
+ * Helper method for getting protocol message for token response.
+ *
+ * @param response The response message
+ * @return The response message specific log message
+ */
+ @Nullable public static String getProtocolMessageForTokenResponse(@Nonnull final TokenResponse response) {
+ if (response.indicatesSuccess()) {
+ final AccessTokenResponse successResponse = response.toSuccessResponse();
+ return MoreObjects.toStringHelper(successResponse).omitNullValues()
+ .add("customParameters", successResponse.getCustomParameters())
+ .add("tokens", successResponse.getTokens())
+ .toString();
+ } else {
+ final TokenErrorResponse errorResponse = response.toErrorResponse();
+ return MoreObjects.toStringHelper(errorResponse).omitNullValues()
+ .add("errorObject", getProtocolMessageForErrorObject(errorResponse.getErrorObject()))
+ .toString();
+ }
+ }
+
+ /**
+ * Helper method for getting protocol message for error object.
+ *
+ * @param errorObject The error object
+ * @return The log message
+ */
+ @Nullable public static String getProtocolMessageForErrorObject(@Nullable final ErrorObject errorObject) {
+ return errorObject == null ? null : MoreObjects.toStringHelper(errorObject).omitNullValues()
+ .add("httpStatusCode", errorObject.getHTTPStatusCode())
+ .add("code", errorObject.getCode())
+ .add("description", errorObject.getDescription())
+ .add("uri", errorObject.getURI())
+ .toString();
+ }
+
+
+ /**
+ * Helper method for getting protocol message for JSON success response.
+ *
+ * @param response The response message
+ * @return The response message specific log message
+ */
+ @Nullable public static String getProtocolMessageForJSONSuccessResponse(final @Nonnull Response response) {
+ if (response instanceof JSONSuccessResponse) {
+ final JSONSuccessResponse successResponse = (JSONSuccessResponse) response;
+ return successResponse.toString();
+ }
+ return null;
+ }
+
+ /**
+ * Helper method for getting protocol message for JWT payload.
+ *
+ * @param jwt The JWT whose payload is included in the message
+ * @param objectMapper object mapper used for pretty printing JSON content
+ * @return The protocol message containing JWT payload
+ * @throws ParseException IF the protocol message cannot be constructed
+ *
+ * @since 4.1.0
+ */
+ @Nonnull public static String getJwtProtocolMessage(@Nonnull final JWT jwt,
+ @Nonnull final ObjectMapper objectMapper) throws ParseException {
+ return getJwtProtocolMessage(jwt.getJWTClaimsSet(), objectMapper);
+ }
+
+ /**
+ * Helper method for getting protocol message for ID token payload.
+ *
+ * @param idToken The ID token whose payload is included in the message
+ * @param objectMapper object mapper used for pretty printing JSON content
+ * @return The protocol message containing JWT payload
+ * @throws ParseException IF the protocol message cannot be constructed
+ *
+ * @since 4.1.0
+ */
+ @Nonnull public static String getIdTokenProtocolMessage(@Nonnull final IDTokenClaimsSet idToken,
+ @Nonnull final ObjectMapper objectMapper) throws ParseException {
+ try {
+ return getJwtProtocolMessage(idToken.toJWTClaimsSet(), objectMapper);
+ } catch (final com.nimbusds.oauth2.sdk.ParseException e) {
+ final Throwable cause = e.getCause();
+ if (cause instanceof ParseException parseException) {
+ throw parseException;
+ }
+ throw new ParseException(e.getMessage(), 0);
+ }
+ }
+
+ /**
+ * Helper method for getting protocol message for logout token payload.
+ *
+ * @param logoutToken logout token whose payload is included in the message
+ * @param objectMapper object mapper used for pretty printing JSON content
+ * @return The protocol message containing logout token payload
+ * @throws ParseException IF the protocol message cannot be constructed
+ *
+ * @since 4.1.0
+ */
+ @Nonnull public static String getLogoutTokenProtocolMessage(@Nonnull final LogoutTokenClaimsSet logoutToken,
+ @Nonnull final ObjectMapper objectMapper) throws ParseException {
+ try {
+ return getJwtProtocolMessage(logoutToken.toJWTClaimsSet(), objectMapper);
+ } catch (final com.nimbusds.oauth2.sdk.ParseException e) {
+ final Throwable cause = e.getCause();
+ if (cause instanceof ParseException parseException) {
+ throw parseException;
+ }
+ throw new ParseException(e.getMessage(), 0);
+ }
+ }
+
+ /**
+ * Helper method for getting protocol message for JWT payload.
+ *
+ * @param claimsSet The claims set to be included in the message
+ * @param objectMapper object mapper used for pretty printing JSON content
+ * @return The protocol message containing JWT payload
+ * @throws ParseException IF the protocol message cannot be constructed
+ *
+ * @since 4.1.0
+ */
+ @Nonnull public static String getJwtProtocolMessage(@Nullable final JWTClaimsSet claimsSet,
+ @Nonnull final ObjectMapper objectMapper) throws ParseException {
+ if (claimsSet == null) {
+ return "<encrypted>";
+ }
+ try {
+ final Object jsonObject = objectMapper.readValue(claimsSet.toString(), Object.class);
+ final String content = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonObject);
+ if (content != null) {
+ return content;
+ }
+ } catch (final JsonProcessingException e) {
+ }
+ throw new ParseException("Could not parse the JSON output from the claims set", 0);
+ }
+
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-dist/.check-m2 b/idp-oidfed-op-dist/.check-m2
new file mode 100644
index 0000000..048849a
--- /dev/null
+++ b/idp-oidfed-op-dist/.check-m2
@@ -0,0 +1 @@
+This file provokes a signature check of the maven repository unless overridden by the no-check-m2 property.
\ No newline at end of file
diff --git a/idp-oidfed-op-dist/pom.xml b/idp-oidfed-op-dist/pom.xml
new file mode 100644
index 0000000..49c91bc
--- /dev/null
+++ b/idp-oidfed-op-dist/pom.xml
@@ -0,0 +1,87 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>net.shibboleth.idp.plugin.oidfed</groupId>
+ <artifactId>idp-plugin-oidfed-op-parent</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>idp-plugin-oidfed-op-dist</artifactId>
+ <packaging>pom</packaging>
+ <name>Shibboleth IdP :: Plugins :: OpenID Federation plugin for OpenID Provider Distribution</name>
+ <description>IdP OIDFED plugin for OP packaging.</description>
+
+ <properties>
+ <checkstyle.configLocation>${project.basedir}/../resources/checkstyle/checkstyle.xml</checkstyle.configLocation>
+ <dist.plugin.finalName>shibboleth-idp-plugin-oidfed-op-${project.version}</dist.plugin.finalName>
+ </properties>
+
+ <build>
+ <plugins>
+ <!-- Assemble -->
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>make-assembly</id>
+ <phase>package</phase>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ <configuration>
+ <appendAssemblyId>false</appendAssemblyId>
+ <descriptors>
+ <descriptor>src/main/assembly/assembly-tgz.xml</descriptor>
+ </descriptors>
+ <finalName>${dist.plugin.finalName}</finalName>
+ <overrideUid>1000</overrideUid>
+ <overrideGid>1000</overrideGid>
+ <tarLongFileMode>gnu</tarLongFileMode>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-enforcer-plugin</artifactId>
+ <dependencies>
+ <dependency>
+ <groupId>net.shibboleth.maven.enforcer.rules</groupId>
+ <artifactId>maven-dist-enforcer</artifactId>
+ <version>${maven-dist-enforcer.version}</version>
+ </dependency>
+ </dependencies>
+ <executions>
+ <execution>
+ <id>oidfed-op-enforce</id>
+ <phase>verify</phase>
+ <goals>
+ <goal>enforce</goal>
+ </goals>
+ <configuration>
+ <rules>
+ <jarEnforcer implementation="net.shibboleth.mvn.enforcer.impl.JarEnforcer">
+ <dataGroupId>net.shibboleth.maven.enforcer.rules</dataGroupId>
+ <dataArtifactId>maven-dist-enforcer-data</dataArtifactId>
+ <dataVersion>${maven-dist-enforcer-data.version}</dataVersion>
+ <dataKeyRing>${basedir}/src/main/enforcer/shibbolethKeys.gpg</dataKeyRing>
+ <parentPomDir>${basedir}/..</parentPomDir>
+ <tgzFiles>${project.build.directory}/${dist.plugin.finalName}.tar.gz</tgzFiles>
+ <checkSignatures>true</checkSignatures>
+ <checkDependencies>true</checkDependencies>
+ <listJarSources>true</listJarSources>
+ <checkM2>${net.shibboleth.maven.enforcer.rules.checkM2}</checkM2>
+ </jarEnforcer>
+ </rules>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+
+ </build>
+
+
+</project>
diff --git a/idp-oidfed-op-dist/src/main/assembly/assembly-tgz.xml b/idp-oidfed-op-dist/src/main/assembly/assembly-tgz.xml
new file mode 100644
index 0000000..b9e0086
--- /dev/null
+++ b/idp-oidfed-op-dist/src/main/assembly/assembly-tgz.xml
@@ -0,0 +1,72 @@
+<assembly
+ xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
+ <id>bin-gz</id>
+ <formats>
+ <format>tar.gz</format>
+ </formats>
+
+ <fileSets>
+ <fileSet>
+ <directory>src/main/resources/</directory>
+ <outputDirectory></outputDirectory>
+ </fileSet>
+
+ <!-- The plugin property file -->
+ <fileSet>
+ <directory>../idp-oidfed-op-impl/target/classes/net/shibboleth/idp/plugin/oidfed/op/</directory>
+ <outputDirectory>bootstrap</outputDirectory>
+ <includes>
+ <include>plugin.properties</include>
+ </includes>
+ </fileSet>
+
+ <!-- The implementation jar -->
+ <fileSet>
+ <directory>../idp-oidfed-op-impl/target</directory>
+ <outputDirectory>webapp/WEB-INF/lib</outputDirectory>
+ <includes>
+ <include>idp-plugin-oidfed-op-impl-*.jar</include>
+ </includes>
+ <excludes>
+ <exclude>*test*.jar</exclude>
+ <exclude>*javadoc.jar</exclude>
+ <exclude>*sources.jar</exclude>
+ </excludes>
+ </fileSet>
+
+ <!-- The API jar -->
+ <fileSet>
+ <directory>../idp-oidfed-op-api/target</directory>
+ <outputDirectory>webapp/WEB-INF/lib</outputDirectory>
+ <includes>
+ <include>idp-plugin-oidfed-op-api-*.jar</include>
+ </includes>
+ <excludes>
+ <exclude>*test*.jar</exclude>
+ <exclude>*javadoc.jar</exclude>
+ <exclude>*sources.jar</exclude>
+ </excludes>
+ </fileSet>
+
+ <!-- The dependencies -->
+ <fileSet>
+ <directory>../idp-oidfed-op-impl/target/dependency</directory>
+ <outputDirectory>webapp/WEB-INF/lib</outputDirectory>
+ <includes>
+ <include>*.jar</include>
+ </includes>
+ </fileSet>
+
+ <!-- The signing certificates -->
+ <fileSet>
+ <directory>src/main/resources/bootstrap</directory>
+ <outputDirectory>bootstrap</outputDirectory>
+ <includes>
+ <include>keys.txt</include>
+ </includes>
+ </fileSet>
+ </fileSets>
+
+</assembly>
diff --git a/idp-oidfed-op-dist/src/main/enforcer/shibbolethKeys.gpg b/idp-oidfed-op-dist/src/main/enforcer/shibbolethKeys.gpg
new file mode 100644
index 0000000..6d8fc48
Binary files /dev/null and b/idp-oidfed-op-dist/src/main/enforcer/shibbolethKeys.gpg differ
diff --git a/idp-oidfed-op-dist/src/main/resources/bootstrap/id.property b/idp-oidfed-op-dist/src/main/resources/bootstrap/id.property
new file mode 100644
index 0000000..3da1559
--- /dev/null
+++ b/idp-oidfed-op-dist/src/main/resources/bootstrap/id.property
@@ -0,0 +1 @@
+plugin.id=net.shibboleth.idp.plugin.oidfed.op
diff --git a/idp-oidfed-op-dist/src/main/resources/bootstrap/keys.txt b/idp-oidfed-op-dist/src/main/resources/bootstrap/keys.txt
new file mode 100644
index 0000000..53a8f43
--- /dev/null
+++ b/idp-oidfed-op-dist/src/main/resources/bootstrap/keys.txt
@@ -0,0 +1,375 @@
+Henri Mikkonen PGP key
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mQINBF46zL0BEACUeQllAAViSlyL8uFBCjlCXdH12GpDL9y8fubm+N50ofonIloA
+YLbJtETVrqpxfeh+SDiERbEG5W02fbM1y3wdSjef0jzAEP3PoXydv/SdNKvomvBP
+U7I9eALgHJI4Nkqzf8ggTrOBHcWbRIRGbVXFRhOE1Z86akmVz3fe3aQzddvzAS7I
+YYX0RxbKiNt8iaxUXUo+P1LopD9Zo2I1NTY8u27RuhtxBr5tnHnsuf38mzjG/l6U
+RzJ8qhHJr6D4E+MLqRo9ndTREOT/d1TeJUvQddXC59VEL75TrYCEc2v/NZ5m9fD6
+yg0+oqgyrQHmZhPVOqoJiz0lkd3rl7lUqCH9yjREr1H5PUchiuhBKBOogwtirqw3
+NMKH6bs0Bu6qUy5fIJRqjxKVv+6fOEty/xnp0xN7xoBEUPEt1M/V3ewwH1zhOwTo
+g4cr4zhTT9RNno3eM0eenEQYapQZ8dFmrNVmhvx9VJlshYGyakrxPwrF3coyC3hh
+HjWE9SzmoyGmmbRgvJVt//SqoGpDyaM+d1hPys9tX2N/E1TlwZiD2brWAtjr2K49
+NC9Skizw4qHAbphq4EMGCKzrp9ksnBvwZAY9JjL0JvdjAabqkyRFVh2Mpm5xSxbw
+d+Twryh5hXaT/EQXsKMC1WlQnIDREjHpm1UOXTzcsFPa9tEW8XUftPWbQQARAQAB
+tCZIZW5yaSBNaWtrb25lbiA8aGVucmkubWlra29uZW5AaWtpLmZpPokCVAQTAQgA
+PhYhBG0Y/WNwj8ygebaMzgJmkYOTVevKBQJeOsy9AhsDBQkHhh+ABQsJCAcCBhUK
+CQgLAgQWAgMBAh4BAheAAAoJEAJmkYOTVevKwWcP+gLrjnrNxqwEx7/Ly/KdjkGD
+0W7aMiQc8acvC9oo74/XXpAD0W1jkK/BXyLH1q/o5Lyjymmm6w7VvEWLSY1Q0+gC
+l+hUOqccH572767UrGEeZeJV8+tNhziTU2S7NagK2A0BelHoA3hIhfGmWLJ+ooJe
+HZXFCov4ThZOpGzu5d04dEYoOv2jVaWwnrjOBzoKcgws9J6RLX+6gOFhZ3Dh5Rxs
+UGhl0ZJuEBQCDT7X9jI4mHsA0Ngo27inb3gxfeCm/ziZhHDV2gZtl777dKVc/sQN
+fqGaRGVi1p37La6KKpfIA3KHRjGf4jfg17AQ1Ix+ZgRIpbPXb7fXQHtBElhIbbn/
+VR2CG0Jdchdc4UozelKU6WNsNlcMn3kfTNFosW7+gTiYEGSxZQC9ylSSl1s9oIFM
+dvk70u4AgTY6w+27TrTRuEpdARoNZG4NhBTJ8g0BkiX6cHVyc5ir5IOVpmewsxN5
+yLg0ed6OwpcK5V8SwGT60hgkkJp71OeBsnLzyzO3/YoI5GVAIgcwtdzptRUt0iL8
+GUccO3mO6Hm4EfJAZHFWRbxX3ITTfCzw4blbXURlIXkPefprptAYX2+rn/z4iC1F
+mJUANl+4WilKuPoAimKGDNi6CvlbckQW2i2i5gsoM3iMxRMsExoZUnoMpfY70Trg
+ToF/jwURMQSCsJnZvyQDuQINBF46zL0BEAD9AuFJ7J1R5AOW9OzFTRdyMh4bCOtt
+p761l0UmaW5tkgtmKH977E/xB+RhgXTTL7tqWZD3rAt+/uP/4/kAzO9WpaiRnFIC
+oZcE1O6BU4+jbl16PJRf20LOfZlsGT5nEmYvTGTIsZYcTalE+iNiFbK3ehe2MOeZ
+96GTH+r10zcOI6j0k8fKnkKzs1BeqdbgxBQlqOy4fBoS2tgGYHsqyH4/IHqfQbxM
+QPQPxgNE8WMh7CqA3jkOw6tNj/RmsQ1Y8qjVmyQjNFt5p49+UEx2lRkYHfSSQADd
+uCbs0D1ccyI3vlvIy5Hn+aLqKR7Y2LpLgCUkXqPWDNv/nTzvbIkbKy6ZNrDyiuq1
+7L/HOnE5nR964zR5fhEMTDBAi/TwT454xkNnnTHhvGKlP2VCe30J8z4O1XoCCy3r
+BFImgU0t10lpxnIXiZFu8GeFT2ddgLph8EHXk5M/IjrKGW9I1JV2HgWF5T13Izff
+k9dvHETijvGyFpFezJfjRuDP3dzPCsXR4FJJiClXm0S3H+bLYLf0rrWDQzPU3c14
+fdh7HIZsRaZIPM0PjM3as1DMjm5TtuZi089Q78Yi5WdEwivZlvPfVckvTJUGcWhe
+sYR6ynQ749ORLz8jjbrhT6DDkjjvzVCepRLsARKRAvVF+I00ddeH0JxvPjHpyyUc
+zhKXqTzD813SJwARAQABiQI7BBgBCAAmFiEEbRj9Y3CPzKB5tozOAmaRg5NV68oF
+Al46zL0CGwwFCQeGH4AACgkQAmaRg5NV68pV3g/0C7clD4qsIU3TOLMZcWRHzvgp
+Z+yhSf80B3TYPempR6aOntqkDWsqVmt7D4nIehdCHfVDyW+PF+Jf17iot7AfsrSy
+lTQsOKwMM5Rw05VfqKIZBlJsHnKUmprC3yDV0CdidC9Cq0pQdiVeHzvS7R9HmMPG
+da30HikBHiFsYMIS+1hJKa//X75ncKiPc8ypoM7O6HrtArXZiWRjLfpcHBBHbVea
+ixOotHM271C3KsWTqURgzCX+GrumMS7QvXnHq4xketuBsVD6X/rlHzLjxSE0p7Tj
+G/B2VV1WPkb+QgPDC/1rXIi6NMm9GE/tzbPXTcGHX2irHlvGvotg32vWwehRnqNF
+exLuW4t30p+8E27+l03kGILCNLhhAFjjjPp4Vza/E3ZaQprSVBr9gH1HwZKUTThM
+EqGmypTmvnmx3Kw6pG0tia4wdLSxfyZh5XltUnwVSqptWdvt5tlceMFJlGxvIuw1
+ubDr97aIVM7kME6E5D59IXDWnxkIbdoAtaeQegO2OeyvbffuKnnX0ogF4Gcu6Zed
+ap7nWr2LBEwN3S9+hDIrXfs3QMy3bZIPkVCo0ncwaJPZFIMWWqeUkkjTzOKbQ53P
+6REH0FGoCXOH3qTqbS3bPNmyD3TVtN8OwiUZsOr/zu9VdNqUW3oq+aix4tU00pu7
+A+i1fd0Gifis1HhBeA==
+=ObHY
+-----END PGP PUBLIC KEY BLOCK-----
+
+pub rsa4096 2021-02-25 [SC]
+ B5B5DD332142AD657E8D87AC7D27E610B8A3DC52
+uid [ultimate] Philip David Smart <philip.smart at jisc.ac.uk>
+sig 3 7D27E610B8A3DC52 2021-02-25 Philip David Smart <philip.smart at jisc.ac.uk>
+sig 3 B77C52EEC21771DD 2021-02-25 philsmart (gpg key) <philip.smart at jisc.ac.uk>
+sig 2 9A804E97D7079C77 2021-03-04 Ian A. Young <ian at iay.org.uk>
+uid [ultimate] [jpeg image of size 9378]
+sig 3 7D27E610B8A3DC52 2021-02-25 Philip David Smart <philip.smart at jisc.ac.uk>
+sig 3 B77C52EEC21771DD 2021-02-25 philsmart (gpg key) <philip.smart at jisc.ac.uk>
+sig 2 9A804E97D7079C77 2021-03-04 Ian A. Young <ian at iay.org.uk>
+sub rsa4096 2021-02-25 [E]
+sig 7D27E610B8A3DC52 2021-02-25 Philip David Smart <philip.smart at jisc.ac.uk>
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mQINBGA3eNkBEADXiVQf1XEUSM9gB+eMAPj4zdjtd2tflJTNI5Q6sEB2ly2rbOyg
+Yo49DF6wytQSRABAJvRY36hHkK77mbRN5Usf8Rq09aGUEv0nvKO+JVT/P4w3tFva
+MmKWiYX775/yDE7B1vu4eb1RQCjrXaye91EpHES74VR8Kb0TVeNEQXGR5/h77Gcg
+obRog+CqxT9L33Fcs4d2C+8BLo4dOaAr29rmEGWRE576NM6wGvtzHdazipM9LvtS
+POGRid4HLYuWvW5WCyAfGbkOq8xreYBtB9gGSZ8iarmcYmN50/gz3Ux3sJA/xy7Y
+vMAYWtA8Rp5hFb39uoaEwHWz8IlnAbA11OfrEkt65dMJwQAX4w89aag/LqI2lrgG
+VEoDWCvkKOlsbJalZr/SgG+m1k/4gqfYYkM09PI7IRn0Cb8uLDdXpeBZd2SJXi9E
+gdDxsrKoi0IMUYQNv8stNa/5lTK7LJkqovpdL+1aHCYRex53Ln+y8RycNbxSGl5O
+CKtFGb9ydfMnbOVX4BJ1x83OOktIkbLpVeZIsaTmUEDQ9itWmXqQ/QoIgBVFRqh8
+bhaCs7y9UPF+WtnpRY7jm3/cSL6oUXax2tT5VoU3LLxTQf90ZdWrAyWEF8auBZAP
+FRXAD2HkS4rIWCuKi/GSH0v6ILu9KREFfViy9fZXFpvwvbz199CPlCkgLQARAQAB
+tCxQaGlsaXAgRGF2aWQgU21hcnQgPHBoaWxpcC5zbWFydEBqaXNjLmFjLnVrPokC
+TQQTAQgAOBYhBLW13TMhQq1lfo2HrH0n5hC4o9xSBQJgN3jZAhsDBQsJCAcCBhUK
+CQgLAgQWAgMBAh4BAheAAAoJEH0n5hC4o9xSz4EP9Arv6WSxxkBEVzGj2XRbXAOP
+U0G5KFJ1sviO9ZGotBnivHH4HWcusDqoyDvjwIYp9jycgtwGw4TuF917QPTfFwhb
+TYma22+wSZ6Sn+OcZr+dSjLg5Ki+6I2BZaS+m2MYcPehCl1ILbtcs83p7AZf2JU1
+IgejhJMsMg93G88ZkSOO0tOAuvBbrO+f/de5AtSIk9ense1OUz9dbjI7JK6idB0a
+1yoo5FjOuyRw11qEa7nP787jcdnh6gkcfRGK9CcYOWXXcfQSRYFx0Wz6qi76bonk
+fYioCGv7LOPvsRnrjyWnM0tukS2RrDSbOfEby6ma4ZsPAhxtOrwWYOYfmjpspNbh
+yPHL/qw0Bb+t+X+mBayRO3MJ1R4l5lU3cjXF/oSCxinkL4TfX5bJ+SuPmPb6cOO4
+eHBHCwTad0jy9CEQAFIwtQP1+5QpcAUQPEhHlztPPHe5hP3X8M0x0ILTEDrh29E0
+C0CP0aG9xTONBK1JnmWT7NSXDzk+BLokdbDbZs909+fJddlzPq72u0ubRUOgKNki
+eo5Vbg5aOsaCkC0QJOzabO7xbnlOlXlg8XkGnfO8mIZ6Q0M5oEyGSpBakYi0rfQo
+zjzKwflCvRTKEl8spTkPH45Dm7LZ+o5xWSN4P2NVTh46unfCyKxuSi1Prl2tQ6OG
++ke+A9zfGa0iHsXtT8aJAjMEEwEIAB0WIQSHQCCMDpP+yA7r+RO3fFLuwhdx3QUC
+YDeIGgAKCRC3fFLuwhdx3Q0JEACRK35MbZe3mD7uKWb8pXwTxHfngDDA4TgpVLXA
+Oqvmh+ISYN1RVJUdAdws/PsTS9NgWCD3YbN57G0jtCT3Q0kCAtvXNPLPgmKxk0au
+Y2K1xaJs9iDjXysbWLIOgKdw2hs8FrD2YvYCQfm/jTQeG4TEqVJTvxcyLKVGBwud
+Hg6coVsqz0iazwXiPBE1mLlxXi9mk2wv5a3SySPYbGGF37cXEvX1ZRYG721bSaXW
+EUlZDzd2s2iv0FyM7aXjGeI77x7Ri9vG+KcCFdfoBrYjo5tQ0nm/0mWQr+uakDKr
+T4JUmFnzDCzIZcMqeSRcGRgJ8aCN55TctKcjWUMwXSI4PIUu9XjeHgTmIZVFZzSo
+OZGSxiPUuZ8HSjwb1g5RtOejLX0Sd5FCuzDUtNQmS1BIe3ZpW0D3iWtVGr6FWETc
++Ks2Dwa8T2ZbaOFfsJauqm8l1zJYcV8d45V1ASLnyqaMJdYlctlu+6rwgCgIx9LV
+pKhnvVWEdxEVmyt5UMSZwXfNF3LXW6PFrE9GSSUWcpGwF/X3XuGLpNc8a/lF6RHA
+pbRuy5RN1v10feOqfpd8sFbvxQLuN3Xfo+HFjtjqF74BxASJm+2UePPeanIifRvQ
+Hd8NCGycYaNkdlkBQH3BLaTAD6pf25Hd2Iah3iRvY4gCPE0MoUhUERgXlfwd1L0H
+LpLd+YkCMwQSAQgAHRYhBF5tbq4Ww9p1RQshnJqATpfXB5x3BQJgQPZxAAoJEJqA
+TpfXB5x3JzoP+wQO4IfR4x1Fpd4i7P1YEHp1FWX9CiVkgt8KkND2QFv9jSA1VAIn
+zE0AJps33X3vtz4An0+oWEi1zVNSsg/ShhWVcEUsRuojFZmPjzFuDBzBVBRmqqw9
+p3xGFAcFlhtpIhU4xbRgw9mImNKBX5dzJxKzP+tQcAhY36LwI+aYOfMIWnBSWvpV
+se1+vgCLmVnVB3HtzByppRK1g3nxESXtJblgbW2KvP4wvp8FGLcGdIqS5y1AXTfD
+biaZcB+cHUDQMkICrHdiCtJBN5Ds1Rer7fF2GG89zPNyxi9ODVTOed/v3kf6Fd02
+Tz8N4FLvfvzB1CvoxHXOs2vWwx4CXd5KRcqlN0bXSbuNj6iN6mwyq6rFGJiB0i8G
+9ngK1JNjcyAzTrZofPvOXKFFsiJ7WpKaRI1VnjY97X6lxMfrOMeAiO3/dGpavsHs
+mSM1YVySu6T/GqzgKvzq8hH9NRTba2MBFcEeF9nFaa9v87AhY+HpYQkj4nM2Ie2X
+4IByGVHXR0tm7YXaxbgGnANjipmIKxQjf/81UHZgKO0hLYLt51CmiqYBe1RRcnb1
+oh3REIuOPZKW5HBoVkrgBQBODW7zh5brYMf+f+fiu79xvJ/kTBn3IzhZ4Ay9m4jC
+WVefvpLdE/SLz1YjchS8SWJBCxo/vMzg5NyFq4gBg5GqNKQMBMqAumUq0f8AACS4
+/wAAJLMBEAABAQAAAAAAAAAAAAAAAP/Y/+AAEEpGSUYAAQEAAEgASAAA/+EH5kV4
+aWYAAE1NACoAAAAIAAwBDwACAAAABgAAAJ4BEAACAAAACQAAAKQBEgADAAAAAQAB
+AAABGgAFAAAAAQAAAK4BGwAFAAAAAQAAALYBKAADAAAAAQACAAABMQACAAAABQAA
+AL4BMgACAAAAFAAAAMQBQgAEAAAAAQAAAgABQwAEAAAAAQAAAgCHaQAEAAAAAQAA
+ANiIJQAEAAAAAQAABuQAAAAAQXBwbGUAaVBob25lIDcAAAAAAEgAAAABAAAASAAA
+AAExMS40AAAyMDE4OjA3OjE2IDEwOjA3OjM4AAAfgpoABQAAAAEAAAJSgp0ABQAA
+AAEAAAJaiCIAAwAAAAEAAgAAiCcAAwAAAAEAMgAAkAAABwAAAAQwMjIxkAMAAgAA
+ABQAAAJikAQAAgAAABQAAAJ2kQEABwAAAAQBAgMAkgEACgAAAAEAAAKKkgIABQAA
+AAEAAAKSkgMACgAAAAEAAAKakgQACgAAAAEAAAKikgcAAwAAAAEABQAAkgkAAwAA
+AAEAEAAAkgoABQAAAAEAAAKqkhQAAwAAAAQAAAKyknwABwAAA+IAAAK6kpEAAgAA
+AAQ3MTAAkpIAAgAAAAQ3MTAAoAAABwAAAAQwMTAwoAIABAAAAAEAAACWoAMABAAA
+AAEAAADqohcAAwAAAAEAAgAAowEABwAAAAEBAAAApAIAAwAAAAEAAAAApAMAAwAA
+AAEAAAAApAUAAwAAAAEAHAAApAYAAwAAAAEAAAAApDIABQAAAAQAAAacpDMAAgAA
+AAYAAAa8pDQAAgAAACIAAAbCAAAAAAAAAAEAAAARAAAACQAAAAUyMDE4OjA3OjE2
+IDEwOjA3OjM4ADIwMTg6MDc6MTYgMTA6MDc6MzgAAAAKdAAAApMAAAhvAAAE+QAA
+KOIAAA/BAAAAAAAAAAEAAAGPAAAAZAXXBg4DvwPBQXBwbGUgaU9TAAABTU0AEwAB
+AAkAAAABAAAACQACAAcAAAIuAAAA+AADAAcAAABoAAADJgAEAAkAAAABAAAAAQAF
+AAkAAAABAAAA6AAGAAkAAAABAAAA8QAHAAkAAAABAAAAAQAIAAoAAAADAAADjgAM
+AAoAAAACAAADpgANAAkAAAABAAAAKAAOAAkAAAABAAAABAAPAAkAAAABAAAAAgAQ
+AAkAAAABAAAAAQARAAIAAAAlAAADtgAUAAkAAAABAAAABQAXAAkAAAABAAAAAAAZ
+AAkAAAABAAAAAAAaAAIAAAAGAAAD3AAfAAkAAAABAAAAAAAAAABicGxpc3QwME8R
+AgBHAkwCUQJVAlICSwJDAjsCLAIaAnMBzgCQAIgAiAB/AEsCUgJWAlYCTgJGAj4C
+MQIgAsoBjwB/AHkAgACBAIAATgJXAloCVgJOAkQCOAIlAg8CMwFwAHcAjACKAJYA
+jwBMAlYCVwJQAkYCOgIrAhIC4wGiAGUAkgCJAI4AjQCSAEoCUgJQAkcCOgIqAhYC
+9AFqAXgAdACRAIUAhQCMAIsASQJKAvYB+gC8AOIAjgGJAbEAcQBrAIMAeQB6AH4A
+gQBFAoEBTQDQALEA4QDiAL0ArgCZAIkAYwBoAHkAdQBuAEECBAF5ABgBtADHANUA
+uQCkAN0AyQCQAIMAfABqAGUAOwL2AHIAIgEEAb0ArACYAIYAuwDQAK8AXgBmAG8A
+eAAxAgkBUADvAIsAqwC/AJ0AbQB5AF8AZABvAHwAdAB1ACYC5gG3AHUAdgCuANwA
+DAHGAGIAYQBqAHEAdwBvAHAAHQIaAv8BtAGjAZ0BhwF4ATEBcwBtAHYAdQB0AGsA
+ZwAYAhkCDQL5AegB2gHFAagBcgGtAF8AdgBzAHIAagBoABUCGQIUAgkC/AHoAc0B
+sAGPARYBZgBmAHkAagBzAGYAEwITAg8CBAL4AeUBygGzAZsBfgHNAGEAcgBpAGsA
+YQAQAg0CCQL/AfQB4gHJAbMBoAGMAXwBUwEDAeAAcAByAAAIAAAAAAAAAgEAAAAA
+AAAAAQAAAAAAAAAAAAAAAAAAAgxicGxpc3QwMNQBAgMEBQYHCFVmbGFnc1V2YWx1
+ZVl0aW1lc2NhbGVVZXBvY2gQARMAAAU6zneKsRI7msoAEAAIERcdJy0vOD0AAAAA
+AAABAQAAAAAAAAAJAAAAAAAAAAAAAAAAAAAAP///xsEAChy8//+2DAAAShH///v9
+AArWDwAAADsAAAEAAAAAZQAAAQA0MkRDQUE3RC0wMTU0LTRBNTktQjY2NS03QTZB
+QjZBRkM4OEQAAHE4MjVzAAA/1d8AD/+1AD/V3wAP/7UAAAAJAAAABQAAAAkAAAAF
+QXBwbGUAaVBob25lIDcgYmFjayBjYW1lcmEgMy45OW1tIGYvMS44AAANAAEAAgAA
+AAJOAAAAAAIABQAAAAMAAAeGAAMAAgAAAAJXAAAAAAQABQAAAAMAAAeeAAUAAQAA
+AAEAAAAAAAYABQAAAAEAAAe2AAwAAgAAAAJLAAAAAA0ABQAAAAEAAAe+ABAAAgAA
+AAJUAAAAABEABQAAAAEAAAfGABcAAgAAAAJUAAAAABgABQAAAAEAAAfOAB8ABQAA
+AAEAAAfWAAAAAAAAADMAAAABAAAAIAAAAAEAAA5QAAAAZAAAAAMAAAABAAAACwAA
+AAEAABWDAAAAZAAAWb0AAADZAAAArQAABJ4AAN2FAAABWAAA3YUAAAFYAAAACAAA
+AAH/4Q1XaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVn
+aW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBt
+ZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA2
+LjAuMCI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5
+OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFi
+b3V0PSIiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIg
+eG1sbnM6bXdnLXJzPSJodHRwOi8vd3d3Lm1ldGFkYXRhd29ya2luZ2dyb3VwLmNv
+bS9zY2hlbWFzL3JlZ2lvbnMvIiB4bWxuczpzdEFyZWE9Imh0dHA6Ly9ucy5hZG9i
+ZS5jb20veG1wL3NUeXBlL0FyZWEjIiB4bWxuczphcHBsZS1maT0iaHR0cDovL25z
+LmFwcGxlLmNvbS9mYWNlaW5mby8xLjAvIiB4bWxuczpzdERpbT0iaHR0cDovL25z
+LmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL0RpbWVuc2lvbnMjIiB4bWxuczpwaG90
+b3Nob3A9Imh0dHA6Ly9ucy5hZG9iZS5jb20vcGhvdG9zaG9wLzEuMC8iIHhtcDpD
+cmVhdGVEYXRlPSIyMDE4LTA3LTE2VDEwOjA3OjM4LjcxMCIgeG1wOkNyZWF0b3JU
+b29sPSIxMS40IiB4bXA6TW9kaWZ5RGF0ZT0iMjAxOC0wNy0xNlQxMDowNzozOCIg
+cGhvdG9zaG9wOkRhdGVDcmVhdGVkPSIyMDE4LTA3LTE2VDEwOjA3OjM4LjcxMCI+
+IDxtd2ctcnM6UmVnaW9ucyByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+IDxtd2ct
+cnM6UmVnaW9uTGlzdD4gPHJkZjpTZXE+IDxyZGY6bGk+IDxyZGY6RGVzY3JpcHRp
+b24gbXdnLXJzOlR5cGU9IkZhY2UiPiA8bXdnLXJzOkFyZWEgc3RBcmVhOnk9IjAu
+NTEyOTk5OTk5OTk5OTk5OSIgc3RBcmVhOnc9IjAuMjM3OTk5OTk5OTk5OTk5OTki
+IHN0QXJlYTp4PSIwLjM3MSIgc3RBcmVhOmg9IjAuMzE3OTk5OTk5OTk5OTk5OTUi
+IHN0QXJlYTp1bml0PSJub3JtYWxpemVkIi8+IDxtd2ctcnM6RXh0ZW5zaW9ucyBh
+cHBsZS1maTpBbmdsZUluZm9ZYXc9IjAiIGFwcGxlLWZpOkFuZ2xlSW5mb1JvbGw9
+IjI3MCIgYXBwbGUtZmk6Q29uZmlkZW5jZUxldmVsPSIxMDAwIiBhcHBsZS1maTpU
+aW1lc3RhbXA9IjEzNzk5OTkyMTQ1MCIgYXBwbGUtZmk6RmFjZUlEPSI5Ii8+IDwv
+cmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpsaT4gPC9yZGY6U2VxPiA8L213Zy1yczpS
+ZWdpb25MaXN0PiA8bXdnLXJzOkFwcGxpZWRUb0RpbWVuc2lvbnMgc3REaW06aD0i
+MzAyNCIgc3REaW06dz0iNDAzMiIgc3REaW06dW5pdD0icGl4ZWwiLz4gPC9td2ct
+cnM6UmVnaW9ucz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94Onht
+cG1ldGE+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPD94cGFja2V0
+IGVuZD0idyI/PgD/7QB4UGhvdG9zaG9wIDMuMAA4QklNBAQAAAAAAD8cAVoAAxsl
+RxwCAAACAAIcAj8ABjEwMDczOBwCPgAIMjAxODA3MTYcAjcACDIwMTgwNzE2HAI8
+AAYxMDA3MzgAOEJJTQQlAAAAAAAQOGix0QQ3mMOAExf+M5Hq4v/iAkBJQ0NfUFJP
+RklMRQABAQAAAjBBREJFAhAAAG1udHJSR0IgWFlaIAfQAAgACwATADMAO2Fjc3BB
+UFBMAAAAAG5vbmUAAAAAAAAAAAAAAAAAAAAAAAD21gABAAAAANMtQURCRQAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACmNwcnQA
+AAD8AAAAMmRlc2MAAAEwAAAAa3d0cHQAAAGcAAAAFGJrcHQAAAGwAAAAFHJUUkMA
+AAHEAAAADmdUUkMAAAHUAAAADmJUUkMAAAHkAAAADnJYWVoAAAH0AAAAFGdYWVoA
+AAIIAAAAFGJYWVoAAAIcAAAAFHRleHQAAAAAQ29weXJpZ2h0IDIwMDAgQWRvYmUg
+U3lzdGVtcyBJbmNvcnBvcmF0ZWQAAABkZXNjAAAAAAAAABFBZG9iZSBSR0IgKDE5
+OTgpAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABYWVogAAAAAAAA81EA
+AQAAAAEWzFhZWiAAAAAAAAAAAAAAAAAAAAAAY3VydgAAAAAAAAABAjMAAGN1cnYA
+AAAAAAAAAQIzAABjdXJ2AAAAAAAAAAECMwAAWFlaIAAAAAAAAJwYAABPpQAABPxY
+WVogAAAAAAAANI0AAKAsAAAPlVhZWiAAAAAAAAAmMQAAEC8AAL6c/8AAEQgA6gCW
+AwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQ
+AAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHw
+JDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hp
+anN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TF
+xsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/EAB8BAAMBAQEBAQEB
+AQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMRBAUh
+MQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4
+OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWW
+l5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp
+6vLz9PX29/j5+v/bAEMAGBgYGBgYKRgYKTopKSk6Tjo6OjpOY05OTk5OY3djY2Nj
+Y2N3d3d3d3d3d4+Pj4+Pj6enp6enu7u7u7u7u7u7u//bAEMBHR8fMCwwUiwsUsSF
+bYXExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTE
+xMTExP/dAAQACv/aAAwDAQACEQMRAD8A6KiiisiwpaSkJ4oAZK2xd3uB+fFP3CqL
+yJLbkSHG8HisFNVlKgHsNx9z7U7AdYWA6mkSRJOUIOK59NWaWHaqbpT949F/z7VU
+sbgR3u18qrZBBOMHt+FFgudLdzGC3eQdR/U4plndfaolcD6//WqvqhB0+TB5wD+R
+qvZ3QWAMdqgDCrnGcUAbmcVnS6gkc/2cAljtxj/aP9KgbVI8HjOOuCD+nWuc84rc
+iYHgMDn2z/hQkI7v2pFO5Q3rVR7qMRiUHgdacJ44lSNjzgY96Qy3RTA2VBNOBBGR
+3oAWiiigAooooA//0OiopKM1kaDZHCLk1z099I26ZT8oO1R+maXV7jcwiQ9B/Osm
+dgifZ+pRv8/zppCbFRv3ZllJI6KM9exqkW5zQWPTtTT61ZID5eRTyc1FnsacB2oE
+S+dKy7C7Y9MnH5U4TybPKzwOKreop49aBjt1OzmmH1pM8UATLM4XGSRxwfbpVn7U
+7yq7HJFZ465pwPNKwHYpdA5T0J/KpLScSbVB6Er+VctDK6knOR3rf0kFsue24/mf
+/rGpaKNyiiikAUUUUAf/0ehqmJ1G8ucYNW6x9RiIUzL34NYmhi6g+Z1kHBIz+dUC
+xJyetSzyGRuar7TWiIF69KNnekwRzTstTAYRSZqTBNBQ0AMJzQDinbDThEx7UBYY
+abVjyW9KTyW9KVwsQZpRTzGR1pmKYE0Z5ye9dZpGDbkjjnH5Vx4OK1dMuxDON5+U
+qQf5j8uaTGdlRTEdXUOpBB6EdKfUDCiiimI//9LeNU7xglu7E8AZq2TgZrldQuHe
+Z4g2VHGMYrJFsy2bJzihVJpwXJwOSa1YLcKMnrVN2ElcopbO9WksfWtFVAqUCocj
+RRKK2SCpfsielXRS0rlcqKi2kY6iphboOcVKM07mlcLFfyUHamGBSelWqaaLhYov
+aKRWbPZsvK1v1G6g1SkJxOTIIODQDg1q3duPvLWSwNaJ3MmrHW6PdRmEWxPzr0Hq
+K3M159BKY5klH8JBr0BTkAmkwQ6iiikM/9PTvLgW0Blxkjp9a493MjtK3Vjmt7WJ
+cRrF/eOfyrnh0rOJTLNsmW3GtpRxWdaKMVpgVMjSI4YpwpBTuaksdSjNIM04fWkM
+MGlwaMn1pOfWgQvNNNLk0mRQMbSGlyKQ0wK8yBl5rAnj2ua6RhkVh3Yy2auJlNFF
+CQcjgiu50+c3FqjnqBg59a4auo0OUmN4ic4OQParZmjfopKKgo//1K+sHM6DttNZ
+ArW1b/Xr/u1kjk1C2KZrWowuavCq0K7EAqcVmzVD8mnAtTBUlIoUE08ZpoFSUhiZ
+PtSZNLSgcUANyaTNPxSGgCPiilNJTAQ8isW8Ta2fWto1QvUDRFv7vNVEiS0MI8Gt
+fRiVvBjGMHP44rJYd60dLP8Apkf41ozE7SiiioKP/9WPWIsFZfwrHiGZFrodYXNs
+rf3WH68Vg2g3TAemTWa2L6mwtOLBetQySCMe9U/OYnJ61Ni7mh5oAyaVbhM4yKzy
+0j9ttHk9807BzGykit0qUc1kRqyHg1pRvxSaKTJsU7GBTAc04nApDIJZ1j6mqhvF
+PXipZVDnmqbxxCqSJbZbWZW6HNO8wd6zeF+4/wCdG6T6j2osHMaoORUTjcpHrVaO
+Q9KtZyuaQXOdbgkelWdPYLdxk9N39Krz8SsPeruloHvVHpk/lWhkdoKKQcDFFQM/
+/9a9frvtJB7VzliMyk+1dDfcwe2awrFSJGz2H9ayWxZYkXcxzUJB3bE61dI71Sfc
+WITigqxII4x985PuaUxREfKPxFUriLYFI5z3qOEFpEVMjOAfr3p2DmLoZozg8irU
+cmelQFSjbJOR605UKHjpSGa0RyKbI2KjibApshzUlFaRz0FQAKT83NWGUDk9aqyR
+M0bt3A4FUInDxDg4pTGpG5P0rHABUrjnOc+3pWgsLxojocNjkU7EqVyyq7utTKMD
+FNiORzU2Kkqxg3sZSYn15p+nytFdK6jJwR+dT6kn3X/Co7GMjMntirvoZ21Ostrg
+XAPGCvWrOKzNNHDmtSpG1qf/1714u+3YfSsm2Qo0hPritqbmJvpWXGeD9ayNUPIz
+ULJg5qegipLsVmAYYYZFIixocooB9asbAaXZTuFiH8KDyamI2iowKAJlHFBGacvS
+jvSKIskcUzOO1TY5p/lg8igViqI06hFz64qTGal2CnBR2p3FYaq4p9OApp4pDsU7
+5N0Deo5FNtVAiVfQCprk/uW9xinRrsRVPYVXQlLU0LBdqt9a0c1UtR+7OPWrVBMt
+z//Q05P9W30NZKHlhWs43KR6isjOGH5GsTVE1LTAafmkWhRS02jNBQjc02lagDNA
+iRTR3p6IO9DAUDEI70vOKapwcGpCOKAQ2lFNGaXNAx1MY0uaYxoJZBMN21PU5/Kp
+B8zZ/hFAXcTnpjFTKuflUfSmJGjajEP1JqxTUXYgT0FOpmbP/9HUNZlxHh9/Y1pG
+oyAeDWRpczgafUfQkU8Ui0OpV5NIKkXikURyEAiq3musmMZX1qw+D1qttweKaJZZ
+E1RyySkfusZ9TQExyakCfLntTC4kbMRhutWx0quuF6VMrA1LGgIppqWojQMKYadT
+DQIegOOAav28LKd78egotP8AUj6mrVUQ5dB1FJRQSf/S0mplPamVkWUJRiQimipb
+gYYN68VEDSZaJBSs2OlNB4zULS7OTRYdxSSacAOpqobjJwoNIJjn5lNOwI0D83Q0
+uVVdpNZ3m85UGnrI/XaaLFWLwIo6dKo7pT2FPDzZwoosJo0FbtQ1VkZs89asMcgU
+mhXGmm0tNwScDvQM1LcYhX86s1Eo2gKO3FPFMyHUtJRQB//T0mqOpDUZrIsilXeh
+HfqKog9q0aoyrsfI6GgaYqHsaYyAtzSr60ueaRRGVU9aQIOxqQgmmmLPTNBSY4Lj
+0p2D6ioPJb1PFOWF/wC8aY+ckCZ6mngBeBTVhYHrUoAX60hOQ0rzmnseKQ0hPGKC
+RCeKmtk3Sbz0X+dVuScVJDfQxO0Eg27OrdqaQmzXpwpikMAw5Bp4oJHUUlLQB//U
+0jURqQ1FWRYVFIocbTUlNNMCiPlO09RS5BNRswkd8fwnFR7iODSsO5aB4p2arBhU
+qsOlKw7k1ANN3cUAgcGgZLnim5pu4Gk3CiwXH0xjxURkycClCnrTsTcmQdzWLc/6
+9z6nH6VuqOM1h3IzJNzjkH9BVRCWxY0y6dbgK7Eq/BB9exrqhXKWMaYfJBJPTuPQ
+j6GunQkqC3Xv9aJEolpaZmlzUjP/1b5php1MNZFiVBOxWMlcZ7ZqY1UuwDGc+lNC
+ZnWZwHU9c1Zcd6o2f33rRbpTe41sVyvpSh2FLTT3oAeJDS+YfSoqUUAP3t0FKAzd
+aFqwoFACKoA4qULk4ph61OnSpGhTwMVh3OfMYrxmtlu9Y1x/rDQhsk09gsyhuQeC
+PWukiJBaNjll4P19axlAFohHtWhbH959VH9a0lsZrcv0tJRWRR//2YkCTgQTAQgA
+OBYhBLW13TMhQq1lfo2HrH0n5hC4o9xSBQJgN4HxAhsDBQsJCAcCBhUKCQgLAgQW
+AgMBAh4BAheAAAoJEH0n5hC4o9xSm/AQAM1VQ6ulVGptsosNJYB+HigxIMZiXtIn
+tddo1oJ2HzucgHGF2VJemu5m2NxKrckNQdlO5AvYiD3cGsx1GCcUCqrVJnpVSzn0
+x2vAUd5Iu5AO6VLuWfz6lLzLYFmR7le1eEVV9PWpiFo5JmhCxFlmzbJ/LXg2rm+b
+gGwYg9PaW4zeJR721BE0YYzAdiiyih0oYQqm1rIpp5+rzHL34UeajNU8krcViWDv
+Q6qSKnkk4RQzzWWo5ByjDxB9UBF5eX1Ls/CyFzCpsNaPooKAxC1MQy53GrQIN4Wq
+Y73BMsfEutMvdWxgL5/zWKIS5Fd+hD9wTtOotu00PzamCq+5CnsggILpJenrHWSR
+6xoSgBL6iYjAq1DaLvGUv8/+gnblLkdh3A9+lCqqb45yAbBlZS4w12Jmfov+WKLS
+e464WTG0VTySkShhrwHKWkekXzCusx8nIow1FKo257N97fMLJFWRlBhCHcgtoYmq
+3a49CUndqAmM9MT1/8RX21xUq/vI3aTSXqnjgo+y5EMKNM6Q8u0KgVvxzNRyoyh6
+cJWgW+lXM55X8M1SDBruQBfTF2lnJbxq02hXyuDhWbtuhLCs01z3AxO42PZVuwqI
+/U7chZGzC2e02DPY0TVwbGJU6SEKg6wrZEeAzH7igRWR2AHGUEX0AzEkZD72mvZZ
+TMtW3ci6/EGZiQIzBBMBCAAdFiEEh0AgjA6T/sgO6/kTt3xS7sIXcd0FAmA3iFkA
+CgkQt3xS7sIXcd26xQ//dvjcgYkVg0KdAUQWE0KWFwHgW5mJWyITZs5PcwkArIGh
+pJCns9CRq5EGwGQuLWvhWBAloH+qFI83ydptPoxztZoy7keK1tCdDTNhk2RLhp98
+4CP5oObh6xgpuMQ1hVtwwdhOErGpU/auHgIr4qtScvsfLlhoXHCttzvnBkgiGKi+
+bn7hH+mGS6XCDDTXggh4s3wRZ/snaqy8WcaprfK3dw5Tpgck0pexikVcyI6sbruu
+euGwbUZ5JwuFNnRQzmjPqJk6ZC3tYqPslZFBKi83HXq4T2liTSI2m8eK/gWU512G
+T4HeLlkiSMLYOJeX+gKI25StkzXBqQoVKQJVc6RG8wdv34hSdFT0h1T6xtGKmb6y
+W0c855yFrp2yefSS9+R3DFxBEqo7YtGF1J53v87GBeYnFMRw6vZnon+Kurttn8ah
+gZP0veyb1JtCgBWAS6HVb2q6k/Uw+nt++NAZbr69rtnyzyrMNVvMnuM/L1diYfD0
+bncHd1Oj8KTHmFj7J9He2ytelfB/MFUmnkPWtAugPtnQMTGPYyb4VsOF53QsR0+8
+bJGGI7M3tk/C03sXGfMpYMUyKK7uyGWbKg97iKXQLIoHaI3zbIYNUMh//JspxCqg
+14GbQx8yaLDdyeORn8wmgsVy9qNEsc/PHJO8644KNZJM9x1fDihztBsRbRzwjVaJ
+AjMEEgEIAB0WIQRebW6uFsPadUULIZyagE6X1wecdwUCYED2egAKCRCagE6X1wec
+d5gKD/42YYeUFgaQDABPG45afoqwyP8H1xDi6W5F47wVFwI1GdSBmIqKGhNONwYS
+toeFKcX1ed0gBbFVkwaWEFKCeo0VjWcLYE1YaxL8ybo+iVrFfd/oEHyf414uvnur
+4jNVwqUmtYQMaLlXq2a9tVAGNtsgqsZKEYBanWDXm24z5l2rDGxLlVi7xTGU3pZE
+LfTF3HvZlN3l/ggagXF+2ocT5O0vTX1OO8x0lknTqhbjTJfi+ObJxV4DyE0ifQyh
+3smBUyxZwCcF9MhRKYnEcf8gbsCPDLoiwCGz0o7cKz2blm7NsTgxZXoS0HRx0/wy
+QHS+6mIDuH1gMLeEvJUql7cdKqGAbG5QD9xGPoW6PiTpFTtVusjxD4dIvil5oth5
+r9btVNtoSysEuL13BjBkrO4JuqVZvEdHFGjNE00q6JrI/SpeBZrRR/YZvLCgUZ9J
+w9S6g/usazLEAnOs2EH37yMFA3h3Jr+8l31CkGWBlbLHWc/6ufuyYo4F98TJ7WRV
+vq2RbAMziHMkDH47iMt2PkycLhqPplzbTyVVS/2r1u1d8vfhWlznASuT0/d6cpi0
+H9L/nqe2Mkst32e/X7jr54lSfURmKC+plNn4QQY61DcaUDw5UsMvl/ieDg7OqBeI
+JVgitbDLfIC15B5oRHalAmBOE9OulvvnqxZCHdQ63XunRIbvi7kCDQRgN3jZARAA
+uiPmuwrDqHm5siU9XwHIE5XpzwQv03zgZkwXGKMDcLvPbu5bDpSKvSsRHraaIDcC
+YszGCJJI7usAxrFDeBOo1i4QlVnNcZRpd7Kt4VkZPtKovsfWnDC5qePANEMV6Qjl
+R/wrZ+gmmRwUcC6Nn7TC2IIRfZ7Z5DpFpiCxVI+Q6AdzX4L7mHA6ElWy1XCg1rg+
+SJNSA250DxnavL4jHr+ZjdHmjTIMZCKpAv+7JkEmwrvBCkNuOx0/v6zpBO7QUknU
+3t3lYoKzvBnJbrlU2JgU9OjmjmOfONtcz9e1CVbaBUH8ksmQ/XHOZwBtPcj3Ir54
+sAOUfITzD8gHU07SxAm1vKl1MOEtGPkEFLv63mbvprHRelZoBVaO38Z1s0mnukSE
+veg8vOTSc/JekE9L7AVuEyUcW0b+bpxqkdsjw8PJNETdCQRQZasXRMTXBc9eXnqJ
+KJZWgDduim6zVBoWBf4VZUBcMuhjZ61VAD3mHe/0qF03oEPohqc7iHx9y6dCwM/A
+m4Pa4vVqnBpcjtnjxeyxBiJr9MOMhBR6owWo1tij3v2slzpzYF+7qBLkOTpWDC/X
+ANzOLMhmWlR/cjmatUwVGrgfVGINp3U2nR87+2dcKQwryf2oSYqQ4CckTYeImCcW
+MpZk5/q1rmXDp9wrpRJxXm6C7VQ0uOjab0a/4h9WZAUAEQEAAYkCNgQYAQgAIBYh
+BLW13TMhQq1lfo2HrH0n5hC4o9xSBQJgN3jZAhsMAAoJEH0n5hC4o9xSR3MQAK41
+FXiGu9pBsGkDt6O1VsLXV7oRQtJdv5HzU2tgnSCMlGPt25dEWW1ZstSiJ7+w+oiZ
+nNISl+GQ2AzEbAxQw1wgVQiODNicvNwUOI9IIwaB1/ldpRLupH//OehO1zUvDIjb
+eDeIugc8jk3SanGan8oI5kIKG3bardVk3Vuts1tuaf2xRTrmR42kCaNIdWDYrYr6
+6VLXF+1nZPQr72XHal4gyrfA7EELgLcMCINehrxsPnwRPqru080tefwNIdtlLhl5
+keYuQ5qeBtXfFlYGpv80NGZg91o6LSiKTxBNHiBlACDwsOZ8yse5TaqRAwiheWQc
+WiZySqab+UmP1p6SvErDxO3zdCqv0GyA5CLrXW8LpZCVNzJPuTzV/Y68ozgNKmqx
+Fkw3ExWx/IIYf/dgRbbwhHnlPd2TDyL7btoFluEig6bKvBAkzKSRRMC9G+z+dcZl
+EqtDt2F52QyOm4iYZuXO9vCsVGuwy+2mWyB9EaS3HWctt6l8s3jMmvM+9Q9vrOjF
+J3O04ihMRvb/H47jCjDhID1rLR3umqgT2mLzR25GPrWQG83F9Aop3vIunTpC2hta
+8neA5s805aHc71bUsukzGItlzy2v9woWflZS4tayEPumasRrixQQ/QI4zjVAb7uF
+nWYitJKCbFCTTHqWL0ER7GbxvKXlzBZURQrVQaQ9
+=TFGe
+-----END PGP PUBLIC KEY BLOCK-----
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/.gitignore b/idp-oidfed-op-impl/.gitignore
new file mode 100644
index 0000000..b83d222
--- /dev/null
+++ b/idp-oidfed-op-impl/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/idp-oidfed-op-impl/pom.xml b/idp-oidfed-op-impl/pom.xml
new file mode 100644
index 0000000..e71326d
--- /dev/null
+++ b/idp-oidfed-op-impl/pom.xml
@@ -0,0 +1,515 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>net.shibboleth.idp.plugin.oidfed</groupId>
+ <artifactId>idp-plugin-oidfed-op-parent</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>idp-plugin-oidfed-op-impl</artifactId>
+ <packaging>jar</packaging>
+ <name>Shibboleth IdP :: Plugins :: OpenID Federation plugin for OpenID Provider Impl</name>
+ <description>IdP OIDFED plugin for OP implementation.</description>
+
+ <properties>
+ <checkstyle.configLocation>${project.basedir}/../resources/checkstyle/checkstyle.xml</checkstyle.configLocation>
+ <automatic.module.name>net.shibboleth.idp.plugin.oidfed.op.impl</automatic.module.name>
+ </properties>
+
+ <dependencies>
+ <!-- compile time intra project dependencies -->
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>idp-plugin-oidfed-op-api</artifactId>
+ </dependency>
+ <!-- provided dependencies -->
+ <dependency>
+ <groupId>${oidc-config.groupId}</groupId>
+ <artifactId>idp-plugin-oidc-config-impl</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${oidc-common.groupId}</groupId>
+ <artifactId>oidc-common-crypto-impl</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${oidc-common.groupId}</groupId>
+ <artifactId>oidc-common-crypto-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${oidc-common.groupId}</groupId>
+ <artifactId>oidc-common-metadata-impl</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${oidc-common.groupId}</groupId>
+ <artifactId>oidc-common-metadata-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${oidc-common.groupId}</groupId>
+ <artifactId>oidc-common-attribute-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${oidc-common.groupId}</groupId>
+ <artifactId>oidc-common-attribute-impl</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${oidc-common.groupId}</groupId>
+ <artifactId>oidc-common-profile-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${oidc-common.groupId}</groupId>
+ <artifactId>oidc-common-profile-impl</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${oidc-op.groupId}</groupId>
+ <artifactId>idp-plugin-oidc-op-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${idp.groupId}</groupId>
+ <artifactId>idp-admin-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${idp.groupId}</groupId>
+ <artifactId>idp-admin-impl</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${idp.groupId}</groupId>
+ <artifactId>idp-authn-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${idp.groupId}</groupId>
+ <artifactId>idp-authn-impl</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${idp.groupId}</groupId>
+ <artifactId>idp-profile-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${idp.groupId}</groupId>
+ <artifactId>idp-profile-impl</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${idp.groupId}</groupId>
+ <artifactId>idp-saml-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${idp.groupId}</groupId>
+ <artifactId>idp-session-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${idp.groupId}</groupId>
+ <artifactId>idp-ui</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${shib-profile.groupId}</groupId>
+ <artifactId>shib-profile-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${shib-profile.groupId}</groupId>
+ <artifactId>shib-profile-impl</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${shib-profile.groupId}</groupId>
+ <artifactId>shib-saml-profile-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${shib-attribute.groupId}</groupId>
+ <artifactId>shib-attribute-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${shib-attribute.groupId}</groupId>
+ <artifactId>shib-attribute-impl</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${opensaml.groupId}</groupId>
+ <artifactId>opensaml-core-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${opensaml.groupId}</groupId>
+ <artifactId>opensaml-profile-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${opensaml.groupId}</groupId>
+ <artifactId>opensaml-messaging-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${opensaml.groupId}</groupId>
+ <artifactId>opensaml-saml-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${opensaml.groupId}</groupId>
+ <artifactId>opensaml-security-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${opensaml.groupId}</groupId>
+ <artifactId>opensaml-storage-impl</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${opensaml.groupId}</groupId>
+ <artifactId>opensaml-xmlsec-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${opensaml.groupId}</groupId>
+ <artifactId>opensaml-xmlsec-impl</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${shib-shared.groupId}</groupId>
+ <artifactId>shib-spring</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${shib-shared.groupId}</groupId>
+ <artifactId>shib-service</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${shib-shared.groupId}</groupId>
+ <artifactId>shib-networking</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${shib-shared.groupId}</groupId>
+ <artifactId>shib-support</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${shib-shared.groupId}</groupId>
+ <artifactId>shib-security</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.nimbusds</groupId>
+ <artifactId>oauth2-oidc-sdk</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${opensaml.groupId}</groupId>
+ <artifactId>opensaml-storage-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-core</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${slf4j.groupId}</groupId>
+ <artifactId>jcl-over-slf4j</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.google.code.findbugs</groupId>
+ <artifactId>jsr305</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${spring.groupId}</groupId>
+ <artifactId>spring-web</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>commons-codec</groupId>
+ <artifactId>commons-codec</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${spring.groupId}</groupId>
+ <artifactId>spring-context</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${shib-shared.groupId}</groupId>
+ <artifactId>shib-attribute-filter-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>net.minidev</groupId>
+ <artifactId>json-smart</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${spring.groupId}</groupId>
+ <artifactId>spring-core</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.nimbusds</groupId>
+ <artifactId>nimbus-jose-jwt</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.nimbusds</groupId>
+ <artifactId>content-type</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>jakarta.servlet</groupId>
+ <artifactId>jakarta.servlet-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>jakarta.json</groupId>
+ <artifactId>jakarta.json-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${spring.groupId}</groupId>
+ <artifactId>spring-beans</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${spring-webflow.groupId}</groupId>
+ <artifactId>spring-webflow</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${spring-webflow.groupId}</groupId>
+ <artifactId>spring-binding</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${httpclient.groupId}</groupId>
+ <artifactId>${httpclient.artifactId}</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${httpclient.httpcore.groupId}</groupId>
+ <artifactId>${httpclient.httpcore.artifactId}</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <!-- Test dependencies -->
+ <dependency>
+ <groupId>${oidc-common.groupId}</groupId>
+ <artifactId>oidc-common-crypto-impl</artifactId>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${oidc-common.groupId}</groupId>
+ <artifactId>oidc-common-saml-api</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${oidc-common.groupId}</groupId>
+ <artifactId>oidc-common-saml-impl</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${idp.groupId}</groupId>
+ <artifactId>idp-schema</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${idp.groupId}</groupId>
+ <artifactId>idp-spring</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${idp.groupId}</groupId>
+ <artifactId>idp-testing</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${shib-shared.groupId}</groupId>
+ <artifactId>shib-profile-testing</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${shib-attribute.groupId}</groupId>
+ <artifactId>shib-attribute-filter-impl</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${shib-shared.groupId}</groupId>
+ <artifactId>shib-attribute-filter-spring</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${opensaml.groupId}</groupId>
+ <artifactId>opensaml-messaging-impl</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${opensaml.groupId}</groupId>
+ <artifactId>opensaml-core-impl</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${shib-shared.groupId}</groupId>
+ <artifactId>shib-testing</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${spring.groupId}</groupId>
+ <artifactId>spring-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${idp.groupId}</groupId>
+ <artifactId>idp-conf-impl</artifactId>
+ <version>${idp.version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${idp.groupId}</groupId>
+ <artifactId>idp-conf-impl</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${oidc-op.groupId}</groupId>
+ <artifactId>idp-plugin-oidc-op-impl</artifactId>
+ <version>${oidc-op.version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${oidc-op.groupId}</groupId>
+ <artifactId>idp-plugin-oidc-op-impl</artifactId>
+ <version>${oidc-op.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${shib-shared.groupId}</groupId>
+ <artifactId>shib-attribute-filter-spring</artifactId>
+ <version>${shib-attribute.version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${shib-attribute.groupId}</groupId>
+ <artifactId>shib-attribute-resolver-spring</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${opensaml.groupId}</groupId>
+ <artifactId>opensaml-profile-impl</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${opensaml.groupId}</groupId>
+ <artifactId>opensaml-testing</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${shib-shared.groupId}</groupId>
+ <artifactId>shib-cli</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${shib-shared.groupId}</groupId>
+ <artifactId>shib-networking-spring</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${shib-shared.groupId}</groupId>
+ <artifactId>shib-security-spring</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.unboundid</groupId>
+ <artifactId>unboundid-ldapsdk</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.janino</groupId>
+ <artifactId>janino</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <!-- Spring webflow tests require Junit4, runs in TestNG bridge -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.13.2</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.squareup.okhttp3</groupId>
+ <artifactId>mockwebserver</artifactId>
+ <scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>com.squareup.okhttp3</groupId>
+ <artifactId>okhttp-tls</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.openjdk.nashorn</groupId>
+ <artifactId>nashorn-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>copy-dependencies-test</id>
+ <phase>prepare-package</phase>
+ <goals>
+ <goal>copy-dependencies</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>${project.target.directory}</outputDirectory>
+ <includeScope>runtime</includeScope>
+ <excludeTransitive>true</excludeTransitive>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/OIDFedOPModule.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/OIDFedOPModule.java
new file mode 100644
index 0000000..0d3dd6a
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/OIDFedOPModule.java
@@ -0,0 +1,37 @@
+/*
+ * 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.oidfed;
+
+import java.io.IOException;
+
+import net.shibboleth.idp.module.IdPModule;
+import net.shibboleth.idp.module.impl.PluginIdPModule;
+import net.shibboleth.profile.module.ModuleException;
+
+/**
+ * {@link IdPModule} implementation.
+ */
+public final class OIDFedOPModule extends PluginIdPModule {
+
+ /**
+ * Constructor.
+ *
+ * @throws ModuleException on error
+ * @throws IOException on error
+ */
+ public OIDFedOPModule() throws IOException, ModuleException {
+ super(OIDFedOPModule.class);
+ }
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/OIDFedOPPlugin.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/OIDFedOPPlugin.java
new file mode 100644
index 0000000..8142f42
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/OIDFedOPPlugin.java
@@ -0,0 +1,49 @@
+/*
+ * 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.oidfed;
+
+import java.io.IOException;
+
+import net.shibboleth.idp.module.IdPModule;
+import net.shibboleth.idp.plugin.impl.FirstPartyIdPPlugin;
+import net.shibboleth.profile.module.ModuleException;
+import net.shibboleth.profile.plugin.PluginException;
+import net.shibboleth.shared.collection.CollectionSupport;
+
+/**
+ * Details about the OIDC OP plugin.
+ */
+public class OIDFedOPPlugin extends FirstPartyIdPPlugin {
+
+ /**
+ * Constructor.
+ *
+ * @throws IOException if the properties fail to load
+ * @throws PluginException if other errors occur
+ */
+ public OIDFedOPPlugin() throws IOException, PluginException {
+ super(OIDFedOPPlugin.class);
+ try {
+ final IdPModule module = new OIDFedOPModule();
+ setEnableOnInstall(CollectionSupport.singleton(module));
+ setDisableOnRemoval(CollectionSupport.singleton(module));
+ } catch (final IOException e) {
+ throw e;
+ } catch (final ModuleException e) {
+ throw new PluginException(e);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/AbstractOIDFederationRegistrationProfileConfiguration.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/AbstractOIDFederationRegistrationProfileConfiguration.java
new file mode 100644
index 0000000..fb3931e
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/AbstractOIDFederationRegistrationProfileConfiguration.java
@@ -0,0 +1,163 @@
+/*
+ * 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.oidfed.config;
+
+import java.time.Duration;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import net.shibboleth.oidc.metadata.policy.MetadataPolicy;
+import net.shibboleth.profile.config.AbstractConditionalProfileConfiguration;
+import net.shibboleth.shared.annotation.ParameterName;
+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.Positive;
+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;
+
+/**
+ * Abstract implementation class for profile configurations related OpenID Federation client registration.
+ */
+public class AbstractOIDFederationRegistrationProfileConfiguration extends AbstractConditionalProfileConfiguration
+ implements OIDFederationRegistrationProfileConfiguration {
+
+ /** Lookup function to local metadata policy to be merged into the federation policy. */
+ @Nonnull private Function<ProfileRequestContext,Map<String, MetadataPolicy>> localMetadataPolicyLookupStrategy;
+
+ /** Lookup function to mandatory trust marks. */
+ @Nonnull private Function<ProfileRequestContext,List<String>> mandatoryTrustMarksLookupStrategy;
+
+ /** Lookup function to supply maximum trust mark lifetime. */
+ @Nonnull private Function<ProfileRequestContext,Duration> maximumTrustMarkLifetimeLookupStrategy;
+
+ /**
+ * Constructor.
+ *
+ * @param id ID of the communication profile, never null or empty
+ */
+ public AbstractOIDFederationRegistrationProfileConfiguration(
+ @Nonnull @NotEmpty @ParameterName(name="id") final String id) {
+ super(id);
+ localMetadataPolicyLookupStrategy = FunctionSupport.constant(CollectionSupport.emptyMap());
+ mandatoryTrustMarksLookupStrategy = FunctionSupport.constant(CollectionSupport.emptyList());
+ maximumTrustMarkLifetimeLookupStrategy = FunctionSupport.constant(Duration.ofDays(365));
+ }
+
+ /** {@inheritDoc} */
+ @Override @Nonnull @NonnullElements @NotLive @Unmodifiable
+ public Map<String, MetadataPolicy> getLocalMetadataPolicy(
+ @Nullable final ProfileRequestContext profileRequestContext) {
+ final Map<String, MetadataPolicy> policy = localMetadataPolicyLookupStrategy.apply(profileRequestContext);
+ if (policy != null) {
+ return CollectionSupport.copyToMap(policy);
+ }
+ return CollectionSupport.emptyMap();
+ }
+
+ /**
+ * Set local metadata policy to be merged into the federation policy.
+ *
+ * @param policy metadata policy
+ */
+ public void setLocalMetadataPolicy(
+ @Nonnull @NonnullElements @NotLive @Unmodifiable final Map<String, MetadataPolicy> policy) {
+ localMetadataPolicyLookupStrategy = FunctionSupport.constant(policy);
+ }
+
+ /**
+ * Sets lookup strategy for local metadata policy to be merged into the federation policy.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setLocalMetadataPolicyLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext,Map<String, MetadataPolicy>> strategy) {
+ localMetadataPolicyLookupStrategy =
+ Constraint.isNotNull(strategy, "Local metadata policy lookup strategy cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override @Nonnull @NonnullElements @NotLive @Unmodifiable
+ public List<String> getMandatoryTrustMarks(@Nullable final ProfileRequestContext profileRequestContext) {
+ final List<String> trustMarks = mandatoryTrustMarksLookupStrategy.apply(profileRequestContext);
+ if (trustMarks != null) {
+ return CollectionSupport.copyToList(trustMarks);
+ }
+ return CollectionSupport.emptyList();
+ }
+
+ /**
+ * Set mandatory trust marks.
+ *
+ * @param marks trust marks
+ */
+ public void setMandatoryTrustMarks(@Nonnull @NonnullElements @NotLive @Unmodifiable final List<String> marks) {
+ mandatoryTrustMarksLookupStrategy = FunctionSupport.constant(marks);
+ }
+
+ /**
+ * Sets lookup strategy for mandatory trust marks value.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setMandatoryTrustMarksLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext,List<String>> strategy) {
+ mandatoryTrustMarksLookupStrategy =
+ Constraint.isNotNull(strategy, "Mandatory trust marks lookup strategy cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ @Positive @Nonnull
+ public Duration getMaximumTrustMarkLifetime(@Nullable final ProfileRequestContext profileRequestContext) {
+ final Duration lifetime = maximumTrustMarkLifetimeLookupStrategy.apply(profileRequestContext);
+
+ Constraint.isTrue(lifetime != null && !lifetime.isZero() && !lifetime.isNegative(),
+ "Maximum trust mark lifetime must be greater than 0");
+ assert lifetime != null;
+ return lifetime;
+ }
+
+ /**
+ * Set the maximum lifetime of a trust mark.
+ *
+ * @param lifetime lifetime of a trust mark
+ */
+ public void setMaximumTrustMarkLifetime(@Positive @Nonnull final Duration lifetime) {
+ final Duration trustMarkLifetime = Constraint.isNotNull(lifetime, "Maximum trust mark lifetime cannot be null");
+ Constraint.isTrue(!trustMarkLifetime.isZero() && !trustMarkLifetime.isNegative(),
+ "Maximum trust mark lifetime must be greater than 0");
+
+ maximumTrustMarkLifetimeLookupStrategy = FunctionSupport.constant(trustMarkLifetime);
+ }
+
+ /**
+ * Set a lookup strategy for the maximum trust mark lifetime.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setMaximumTrustMarkLifetimeLookupStrategy(
+ @Nullable final Function<ProfileRequestContext,Duration> strategy) {
+ maximumTrustMarkLifetimeLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null");
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/AbstractOIDFederationResponseCachingProfileConfiguration.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/AbstractOIDFederationResponseCachingProfileConfiguration.java
new file mode 100644
index 0000000..654f958
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/AbstractOIDFederationResponseCachingProfileConfiguration.java
@@ -0,0 +1,89 @@
+/*
+ * 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.oidfed.config;
+
+import java.time.Duration;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import net.shibboleth.profile.config.AbstractConditionalProfileConfiguration;
+import net.shibboleth.shared.annotation.ParameterName;
+import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.annotation.constraint.Positive;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.logic.FunctionSupport;
+
+/**
+ * Abstract implementation class for profile configurations related OpenID Federation response caching configuration.
+ */
+public abstract class AbstractOIDFederationResponseCachingProfileConfiguration
+ extends AbstractConditionalProfileConfiguration
+ implements OIDFederationResponseCachingProfileConfiguration {
+
+ /** Lookup function to supply cached success response lifetime. */
+ @Nonnull private Function<ProfileRequestContext,Duration> cachedSuccessResponseLifetimeLookupStrategy;
+
+ /**
+ * Constructor.
+ *
+ * @param id ID of the communication profile, never null or empty
+ */
+ public AbstractOIDFederationResponseCachingProfileConfiguration(
+ @Nonnull @NotEmpty @ParameterName(name="id") final String id) {
+ super(id);
+ cachedSuccessResponseLifetimeLookupStrategy = FunctionSupport.constant(Duration.ofMinutes(5));
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ @Positive @Nonnull
+ public Duration getCachedSuccessResponseLifetime(@Nullable final ProfileRequestContext profileRequestContext) {
+ final Duration lifetime = cachedSuccessResponseLifetimeLookupStrategy.apply(profileRequestContext);
+
+ Constraint.isTrue(lifetime != null && !lifetime.isZero() && !lifetime.isNegative(),
+ "Success response lifetime must be greater than 0");
+ assert lifetime != null;
+ return lifetime;
+ }
+
+ /**
+ * Set the lifetime of a cached success response.
+ *
+ * @param lifetime lifetime of a cached success response
+ */
+ public void setCachedSuccessResponseLifetime(@Positive @Nonnull final Duration lifetime) {
+ final Duration successLifetime = Constraint.isNotNull(lifetime,
+ "Cached success response lifetime cannot be null");
+ Constraint.isTrue(!successLifetime.isZero() && !successLifetime.isNegative(),
+ "Cached success response lifetime must be greater than 0");
+
+ cachedSuccessResponseLifetimeLookupStrategy = FunctionSupport.constant(successLifetime);
+ }
+
+ /**
+ * Set a lookup strategy for the cached success response lifetime.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setCachedSuccessResponseLifetimeLookupStrategy(
+ @Nullable final Function<ProfileRequestContext,Duration> strategy) {
+ cachedSuccessResponseLifetimeLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null");
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/CachedErrorResponseLifetimeLookupFunction.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/CachedErrorResponseLifetimeLookupFunction.java
new file mode 100644
index 0000000..01ded1d
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/CachedErrorResponseLifetimeLookupFunction.java
@@ -0,0 +1,45 @@
+/*
+ * 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.oidfed.config;
+
+import java.time.Duration;
+import java.util.Optional;
+
+import javax.annotation.Nullable;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import net.shibboleth.profile.context.navigate.AbstractRelyingPartyLookupFunction;
+
+/**
+ * A function that returns
+ * {@link OIDFederationResolveEntityProfileConfiguration#getCachedErrorResponseLifetime(ProfileRequestContext)}.
+ *
+ * <p>If a specific setting is unavailable, a null value is returned.</p>
+ */
+public class CachedErrorResponseLifetimeLookupFunction
+ extends AbstractRelyingPartyLookupFunction<Duration> {
+
+ /** {@inheritDoc} */
+ @Override
+ @Nullable public Duration apply(@Nullable final ProfileRequestContext input) {
+ return Optional.ofNullable(getRelyingPartyContextLookupStrategy().apply(input))
+ .map(relyingPartyContext -> relyingPartyContext.getProfileConfig())
+ .filter(OIDFederationResolveEntityProfileConfiguration.class::isInstance)
+ .map(OIDFederationResolveEntityProfileConfiguration.class::cast)
+ .map(config -> config.getCachedErrorResponseLifetime(input))
+ .orElse(null);
+ }
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/CachedSuccessResponseLifetimeLookupFunction.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/CachedSuccessResponseLifetimeLookupFunction.java
new file mode 100644
index 0000000..b083076
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/CachedSuccessResponseLifetimeLookupFunction.java
@@ -0,0 +1,45 @@
+/*
+ * 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.oidfed.config;
+
+import java.time.Duration;
+import java.util.Optional;
+
+import javax.annotation.Nullable;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import net.shibboleth.profile.context.navigate.AbstractRelyingPartyLookupFunction;
+
+/**
+ * A function that returns
+ * {@link OIDFederationResponseCachingProfileConfiguration#getCachedSuccessResponseLifetime(ProfileRequestContext)}.
+ *
+ * <p>If a specific setting is unavailable, a null value is returned.</p>
+ */
+public class CachedSuccessResponseLifetimeLookupFunction
+ extends AbstractRelyingPartyLookupFunction<Duration> {
+
+ /** {@inheritDoc} */
+ @Override
+ @Nullable public Duration apply(@Nullable final ProfileRequestContext input) {
+ return Optional.ofNullable(getRelyingPartyContextLookupStrategy().apply(input))
+ .map(relyingPartyContext -> relyingPartyContext.getProfileConfig())
+ .filter(OIDFederationResponseCachingProfileConfiguration.class::isInstance)
+ .map(OIDFederationResponseCachingProfileConfiguration.class::cast)
+ .map(config -> config.getCachedSuccessResponseLifetime(input))
+ .orElse(null);
+ }
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/DefaultOIDFederationAutomaticRegistrationProfileConfiguration.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/DefaultOIDFederationAutomaticRegistrationProfileConfiguration.java
new file mode 100644
index 0000000..878433b
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/DefaultOIDFederationAutomaticRegistrationProfileConfiguration.java
@@ -0,0 +1,47 @@
+/*
+ * 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.oidfed.config;
+
+import javax.annotation.Nonnull;
+
+import net.shibboleth.shared.annotation.constraint.NotEmpty;
+
+/**
+ * Implementation of a profile configuration for the OpenID Federation Automatic Registration.
+ */
+public class DefaultOIDFederationAutomaticRegistrationProfileConfiguration
+ extends AbstractOIDFederationRegistrationProfileConfiguration
+ implements OIDFederationAutomaticRegistrationProfileConfiguration {
+
+ /** OIDC provider information profile counter name. */
+ @Nonnull @NotEmpty
+ public static final String PROFILE_COUNTER = "net.shibboleth.idp.profiles.oidfed.automaticregistration";
+
+ /**
+ * Constructor.
+ */
+ public DefaultOIDFederationAutomaticRegistrationProfileConfiguration() {
+ this(PROFILE_ID);
+ }
+
+ /**
+ * Creates a new configuration instance.
+ *
+ * @param profileId Unique profile identifier.
+ */
+ public DefaultOIDFederationAutomaticRegistrationProfileConfiguration(@Nonnull @NotEmpty final String profileId) {
+ super(profileId);
+ }
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/DefaultOIDFederationEntityConfigurationProfileConfiguration.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/DefaultOIDFederationEntityConfigurationProfileConfiguration.java
new file mode 100644
index 0000000..c885f7a
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/DefaultOIDFederationEntityConfigurationProfileConfiguration.java
@@ -0,0 +1,199 @@
+/*
+ * 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.oidfed.config;
+
+import java.time.Duration;
+import java.util.List;
+import java.util.Map;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+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.Positive;
+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;
+
+/**
+ * Implementation of a profile configuration for the OpenID Federation Entity Configuration.
+ */
+public class DefaultOIDFederationEntityConfigurationProfileConfiguration
+ extends AbstractOIDFederationResponseCachingProfileConfiguration
+ implements OIDFederationEntityConfigurationProfileConfiguration {
+
+ /** OIDC provider information profile counter name. */
+ @Nonnull @NotEmpty public static final String PROFILE_COUNTER = "net.shibboleth.idp.profiles.oidfed.configuration";
+
+ /** Lookup function to override issuer value. */
+ @Nonnull private Function<ProfileRequestContext,String> issuerLookupStrategy;
+
+ /** Lookup function to authority hints. */
+ @Nonnull private Function<ProfileRequestContext,List<String>> authorityHintsLookupStrategy;
+
+ /** Lookup function to supply entity statement lifetime. */
+ @Nonnull private Function<ProfileRequestContext,Duration> entityStatementLifetimeLookupStrategy;
+
+ /** Lookup function to supply strategy bi-function for manipulating entity statement claims set. */
+ @Nonnull
+ private Function<ProfileRequestContext,BiFunction<ProfileRequestContext,Map<String,Object>,Map<String,Object>>>
+ entityStatementClaimsSetManipulationStrategyLookupStrategy;
+
+ /**
+ * Constructor.
+ */
+ public DefaultOIDFederationEntityConfigurationProfileConfiguration() {
+ this(PROFILE_ID);
+ }
+
+ /**
+ * Creates a new configuration instance.
+ *
+ * @param profileId Unique profile identifier.
+ */
+ public DefaultOIDFederationEntityConfigurationProfileConfiguration(@Nonnull @NotEmpty final String profileId) {
+ super(profileId);
+ issuerLookupStrategy = FunctionSupport.constant(null);
+ authorityHintsLookupStrategy = FunctionSupport.constant(CollectionSupport.emptyList());
+ entityStatementLifetimeLookupStrategy = FunctionSupport.constant(Duration.ofHours(24));
+ entityStatementClaimsSetManipulationStrategyLookupStrategy = FunctionSupport.constant(null);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ @Nullable @NotEmpty public String getIssuer(@Nullable final ProfileRequestContext profileRequestContext) {
+ return issuerLookupStrategy.apply(profileRequestContext);
+ }
+
+ /**
+ * Set overridden issuer value.
+ *
+ * @param issuer issuer value
+ */
+ public void setIssuer(@Nullable @NotEmpty final String issuer) {
+ issuerLookupStrategy = FunctionSupport.constant(issuer);
+ }
+
+ /**
+ * Sets lookup strategy for overridden issuer value.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setIssuerLookupStrategy(@Nonnull final Function<ProfileRequestContext,String> strategy) {
+ issuerLookupStrategy = Constraint.isNotNull(strategy, "Issuer lookup strategy cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override @Nonnull @NonnullElements @NotLive @Unmodifiable
+ public List<String> getAuthorityHints(@Nullable final ProfileRequestContext profileRequestContext) {
+ final List<String> authorityHints = authorityHintsLookupStrategy.apply(profileRequestContext);
+ if (authorityHints != null) {
+ return CollectionSupport.copyToList(authorityHints);
+ }
+ return CollectionSupport.emptyList();
+ }
+
+ /**
+ * Set authority hints value.
+ *
+ * @param hints authority hints
+ */
+ public void setAuthorityHints(@Nonnull @NonnullElements @NotLive @Unmodifiable final List<String> hints) {
+ authorityHintsLookupStrategy = FunctionSupport.constant(hints);
+ }
+
+ /**
+ * Sets lookup strategy for authority hints value.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setAuthorityHintsLookupStrategy(@Nonnull final Function<ProfileRequestContext,List<String>> strategy) {
+ authorityHintsLookupStrategy = Constraint.isNotNull(strategy, "Authority hints lookup strategy cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ @Positive @Nonnull
+ public Duration getEntityStatementLifetime(@Nullable final ProfileRequestContext profileRequestContext) {
+ final Duration lifetime = entityStatementLifetimeLookupStrategy.apply(profileRequestContext);
+
+ Constraint.isTrue(lifetime != null && !lifetime.isZero() && !lifetime.isNegative(),
+ "Entity statement lifetime must be greater than 0");
+ assert lifetime != null;
+ return lifetime;
+ }
+
+ /**
+ * Set the lifetime of an entity statement.
+ *
+ * @param lifetime lifetime of an entity statement
+ */
+ public void setEntityStatementLifetime(@Positive @Nonnull final Duration lifetime) {
+ final Duration statementLifetime = Constraint.isNotNull(lifetime, "Entity statement lifetime cannot be null");
+ Constraint.isTrue(!statementLifetime.isZero() && !statementLifetime.isNegative(),
+ "Entity statement lifetime must be greater than 0");
+
+ entityStatementLifetimeLookupStrategy = FunctionSupport.constant(statementLifetime);
+ }
+
+ /**
+ * Set a lookup strategy for the entity statement lifetime.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setEntityStatementLifetimeLookupStrategy(
+ @Nullable final Function<ProfileRequestContext,Duration> strategy) {
+ entityStatementLifetimeLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ @Nullable
+ public BiFunction<ProfileRequestContext,Map<String,Object>,Map<String,Object>>
+ getEntityStatementClaimsSetManipulationStrategy(
+ @Nullable final ProfileRequestContext profileRequestContext) {
+ return entityStatementClaimsSetManipulationStrategyLookupStrategy.apply(profileRequestContext);
+ }
+
+ /**
+ * Set the bi-function for manipulating entity statement claims set.
+ *
+ * @param strategy bi-function for manipulating entity statement claims set
+ */
+ public void setEntityStatementClaimsSetManipulationStrategy(
+ @Nullable final BiFunction<ProfileRequestContext,Map<String,Object>,Map<String,Object>> strategy) {
+ entityStatementClaimsSetManipulationStrategyLookupStrategy = FunctionSupport.constant(strategy);
+ }
+
+ /**
+ * Set a lookup strategy for the bi-function for manipulating entity statement claims set.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setEntityStatementClaimsSetManipulationStrategyLookupStrategy(@Nonnull final
+ Function<ProfileRequestContext,BiFunction<ProfileRequestContext,Map<String,Object>,Map<String,Object>>>
+ strategy) {
+ entityStatementClaimsSetManipulationStrategyLookupStrategy = Constraint.isNotNull(strategy,
+ "Lookup strategy cannot be null");
+ }
+
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/DefaultOIDFederationExplicitRegistrationProfileConfiguration.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/DefaultOIDFederationExplicitRegistrationProfileConfiguration.java
new file mode 100644
index 0000000..5001bc5
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/DefaultOIDFederationExplicitRegistrationProfileConfiguration.java
@@ -0,0 +1,262 @@
+/*
+ * 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.oidfed.config;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import com.nimbusds.oauth2.sdk.auth.ClientAuthenticationMethod;
+
+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 net.shibboleth.shared.primitive.StringSupport;
+
+/**
+ * Implementation of a profile configuration for the OpenID Federation Explicit Registration.
+ */
+public class DefaultOIDFederationExplicitRegistrationProfileConfiguration
+ extends AbstractOIDFederationRegistrationProfileConfiguration
+ implements OIDFederationExplicitRegistrationProfileConfiguration {
+
+ /** OIDC provider information profile counter name. */
+ @Nonnull @NotEmpty
+ public static final String PROFILE_COUNTER = "net.shibboleth.idp.profiles.oidfed.explicitregistration";
+
+ /** Lookup function to override issuer value. */
+ @Nonnull private Function<ProfileRequestContext,String> issuerLookupStrategy;
+
+ /** Predicate used to indicate whether authorization code flow is supported by this profile. Default true. */
+ @Nonnull private Predicate<ProfileRequestContext> authorizationCodeFlowPredicate;
+
+ /** Predicate used to indicate whether implicit flow is supported by this profile. Default true. */
+ @Nonnull private Predicate<ProfileRequestContext> implicitFlowPredicate;
+
+ /** Predicate used to indicate whether refresh tokens are supported by this profile. Default true. */
+ @Nonnull private Predicate<ProfileRequestContext> refreshTokensPredicate;
+
+ /** Enabled token endpoint authentication methods. */
+ @Nonnull private Function<ProfileRequestContext,Set<String>> tokenEndpointAuthMethodsLookupStrategy;
+
+ /** Lookup function to supply strategy bi-function for manipulating entity statement claims set. */
+ @Nonnull
+ private Function<ProfileRequestContext,BiFunction<ProfileRequestContext,Map<String,Object>,Map<String,Object>>>
+ entityStatementClaimsSetManipulationStrategyLookupStrategy;
+
+ /**
+ * Constructor.
+ */
+ public DefaultOIDFederationExplicitRegistrationProfileConfiguration() {
+ this(PROFILE_ID);
+ }
+
+ /**
+ * Creates a new configuration instance.
+ *
+ * @param profileId Unique profile identifier.
+ */
+ public DefaultOIDFederationExplicitRegistrationProfileConfiguration(@Nonnull @NotEmpty final String profileId) {
+ super(profileId);
+ issuerLookupStrategy = FunctionSupport.constant(null);
+ authorizationCodeFlowPredicate = PredicateSupport.alwaysTrue();
+ implicitFlowPredicate = PredicateSupport.alwaysTrue();
+ refreshTokensPredicate = PredicateSupport.alwaysTrue();
+ tokenEndpointAuthMethodsLookupStrategy = FunctionSupport.constant(
+ CollectionSupport.setOf(
+ ClientAuthenticationMethod.CLIENT_SECRET_BASIC.toString(),
+ ClientAuthenticationMethod.CLIENT_SECRET_POST.toString(),
+ ClientAuthenticationMethod.CLIENT_SECRET_JWT.toString(),
+ ClientAuthenticationMethod.PRIVATE_KEY_JWT.toString()));
+ entityStatementClaimsSetManipulationStrategyLookupStrategy = FunctionSupport.constant(null);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ @Nullable @NotEmpty public String getIssuer(@Nullable final ProfileRequestContext profileRequestContext) {
+ return issuerLookupStrategy.apply(profileRequestContext);
+ }
+
+ /**
+ * Set overridden issuer value.
+ *
+ * @param issuer issuer value
+ */
+ public void setIssuer(@Nullable @NotEmpty final String issuer) {
+ issuerLookupStrategy = FunctionSupport.constant(issuer);
+ }
+
+ /**
+ * Sets lookup strategy for overridden issuer value.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setIssuerLookupStrategy(@Nonnull final Function<ProfileRequestContext,String> strategy) {
+ issuerLookupStrategy = Constraint.isNotNull(strategy, "Issuer lookup strategy cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean isAuthorizationCodeFlowEnabled(@Nullable final ProfileRequestContext profileRequestContext) {
+ return authorizationCodeFlowPredicate.test(profileRequestContext);
+ }
+
+ /**
+ * Set whether authorization code flow is supported by this profile.
+ *
+ * @param flag flag to set
+ */
+ public void setAuthorizationCodeFlowEnabled(final boolean flag) {
+ authorizationCodeFlowPredicate = flag ? PredicateSupport.alwaysTrue() : PredicateSupport.alwaysFalse();
+ }
+
+ /**
+ * Set condition used to indicate whether authorization code flow is supported by this profile.
+ *
+ * @param condition condition to set
+ */
+ public void setAuthorizationCodeFlowEnabledPredicate(@Nonnull final Predicate<ProfileRequestContext> condition) {
+ authorizationCodeFlowPredicate = Constraint.isNotNull(condition,
+ "Condition used to indicate whether authorization code flow is supported cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean isImplicitFlowEnabled(@Nullable final ProfileRequestContext profileRequestContext) {
+ return implicitFlowPredicate.test(profileRequestContext);
+ }
+
+ /**
+ * Set whether hybrid flow is supported by this profile.
+ *
+ * @param flag flag to set
+ */
+ public void setImplicitFlowEnabled(final boolean flag) {
+ implicitFlowPredicate = flag ? PredicateSupport.alwaysTrue() : PredicateSupport.alwaysFalse();
+ }
+
+ /**
+ * Set condition used to indicate whether hybrid flow is supported by this profile.
+ *
+ * @param condition condition to set.
+ */
+ public void setImplicitFlowEnabledPredicate(@Nonnull final Predicate<ProfileRequestContext> condition) {
+ implicitFlowPredicate = Constraint.isNotNull(condition,
+ "Condition used to indicate whether hybrid flow is supported cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean isRefreshTokensEnabled(@Nullable final ProfileRequestContext profileRequestContext) {
+ return refreshTokensPredicate.test(profileRequestContext);
+ }
+
+ /**
+ * Set whether refresh tokens are supported by this profile.
+ *
+ * @param flag flag to set
+ */
+ public void setRefreshTokensEnabled(final boolean flag) {
+ refreshTokensPredicate = flag ? PredicateSupport.alwaysTrue() : PredicateSupport.alwaysFalse();
+ }
+
+ /**
+ * Set condition used to indicate whether refresh tokens are supported by this profile.
+ *
+ * @param condition condition to set
+ */
+ public void setRefreshTokensEnabledPredicate(@Nonnull final Predicate<ProfileRequestContext> condition) {
+ refreshTokensPredicate = Constraint.isNotNull(condition,
+ "Condition used to indicate whether refresh tokens are supported cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ @Nonnull @NonnullElements @NotLive @Unmodifiable public Set<String> getTokenEndpointAuthMethods(
+ @Nullable final ProfileRequestContext profileRequestContext) {
+
+ final Collection<String> methods = tokenEndpointAuthMethodsLookupStrategy.apply(profileRequestContext);
+ if (methods != null) {
+ return CollectionSupport.copyToSet(methods);
+ }
+ return CollectionSupport.emptySet();
+ }
+
+ /**
+ * Set the enabled token endpoint authentication methods.
+ *
+ * @param methods What to set.
+ */
+ public void setTokenEndpointAuthMethods(@Nonnull @NonnullElements final Collection<String> methods) {
+ Constraint.isNotNull(methods, "Collection of methods cannot be null");
+
+ tokenEndpointAuthMethodsLookupStrategy =
+ FunctionSupport.constant(Set.copyOf(StringSupport.normalizeStringCollection(methods)));
+ }
+
+ /**
+ * Set a lookup strategy for the enabled token endpoint authentication methods.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setTokenEndpointAuthMethodsLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext,Set<String>> strategy) {
+ tokenEndpointAuthMethodsLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ @Nullable
+ public BiFunction<ProfileRequestContext,Map<String,Object>,Map<String,Object>>
+ getEntityStatementClaimsSetManipulationStrategy(
+ @Nullable final ProfileRequestContext profileRequestContext) {
+ return entityStatementClaimsSetManipulationStrategyLookupStrategy.apply(profileRequestContext);
+ }
+
+ /**
+ * Set the bi-function for manipulating entity statement claims set.
+ *
+ * @param strategy bi-function for manipulating entity statement claims set
+ */
+ public void setEntityStatementClaimsSetManipulationStrategy(
+ @Nullable final BiFunction<ProfileRequestContext,Map<String,Object>,Map<String,Object>> strategy) {
+ entityStatementClaimsSetManipulationStrategyLookupStrategy = FunctionSupport.constant(strategy);
+ }
+
+ /**
+ * Set a lookup strategy for the bi-function for manipulating entity statement claims set.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setEntityStatementClaimsSetManipulationStrategyLookupStrategy(@Nonnull final
+ Function<ProfileRequestContext,BiFunction<ProfileRequestContext,Map<String,Object>,Map<String,Object>>>
+ strategy) {
+ entityStatementClaimsSetManipulationStrategyLookupStrategy = Constraint.isNotNull(strategy,
+ "Lookup strategy cannot be null");
+ }
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/DefaultOIDFederationResolveEntityProfileConfiguration.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/DefaultOIDFederationResolveEntityProfileConfiguration.java
new file mode 100644
index 0000000..ca140f8
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/DefaultOIDFederationResolveEntityProfileConfiguration.java
@@ -0,0 +1,123 @@
+/*
+ * 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.oidfed.config;
+
+import java.time.Duration;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.annotation.constraint.Positive;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.logic.FunctionSupport;
+
+/**
+ * Implementation of a profile configuration for the OpenID Federation Resolve Entity.
+ */
+public class DefaultOIDFederationResolveEntityProfileConfiguration
+ extends AbstractOIDFederationResponseCachingProfileConfiguration
+ implements OIDFederationResolveEntityProfileConfiguration {
+
+ /** OIDC provider information profile counter name. */
+ @Nonnull @NotEmpty public static final String PROFILE_COUNTER = "net.shibboleth.idp.profiles.oidfed.resolve-entity";
+
+ /** Lookup function to override issuer value. */
+ @Nonnull private Function<ProfileRequestContext,String> issuerLookupStrategy;
+
+ /** Lookup function to supply cached error response lifetime. */
+ @Nonnull private Function<ProfileRequestContext,Duration> cachedErrorResponseLifetimeLookupStrategy;
+
+ /**
+ * Constructor.
+ */
+ public DefaultOIDFederationResolveEntityProfileConfiguration() {
+ this(PROFILE_ID);
+ }
+
+ /**
+ * Creates a new configuration instance.
+ *
+ * @param profileId Unique profile identifier.
+ */
+ public DefaultOIDFederationResolveEntityProfileConfiguration(@Nonnull @NotEmpty final String profileId) {
+ super(profileId);
+ issuerLookupStrategy = FunctionSupport.constant(null);
+ cachedErrorResponseLifetimeLookupStrategy = FunctionSupport.constant(Duration.ofMinutes(5));
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ @Nullable @NotEmpty public String getIssuer(@Nullable final ProfileRequestContext profileRequestContext) {
+ return issuerLookupStrategy.apply(profileRequestContext);
+ }
+
+ /**
+ * Set overridden issuer value.
+ *
+ * @param issuer issuer value
+ */
+ public void setIssuer(@Nullable @NotEmpty final String issuer) {
+ issuerLookupStrategy = FunctionSupport.constant(issuer);
+ }
+
+ /**
+ * Sets lookup strategy for overridden issuer value.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setIssuerLookupStrategy(@Nonnull final Function<ProfileRequestContext,String> strategy) {
+ issuerLookupStrategy = Constraint.isNotNull(strategy, "Issuer lookup strategy cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ @Positive @Nonnull
+ public Duration getCachedErrorResponseLifetime(@Nullable final ProfileRequestContext profileRequestContext) {
+ final Duration lifetime = cachedErrorResponseLifetimeLookupStrategy.apply(profileRequestContext);
+
+ Constraint.isTrue(lifetime != null && !lifetime.isZero() && !lifetime.isNegative(),
+ "Error response lifetime must be greater than 0");
+ assert lifetime != null;
+ return lifetime;
+ }
+
+ /**
+ * Set the lifetime of a cached error response.
+ *
+ * @param lifetime lifetime of a cached error response
+ */
+ public void setCachedErrorResponseLifetime(@Positive @Nonnull final Duration lifetime) {
+ final Duration errorLifetime = Constraint.isNotNull(lifetime,
+ "Cached error response lifetime cannot be null");
+ Constraint.isTrue(!errorLifetime.isZero() && !errorLifetime.isNegative(),
+ "Cached error response lifetime must be greater than 0");
+
+ cachedErrorResponseLifetimeLookupStrategy = FunctionSupport.constant(errorLifetime);
+ }
+
+ /**
+ * Set a lookup strategy for the cached error response lifetime.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setCachedErrorResponseLifetimeLookupStrategy(
+ @Nullable final Function<ProfileRequestContext,Duration> strategy) {
+ cachedErrorResponseLifetimeLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null");
+ }
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/OIDFederationAutomaticRegistrationProfileConfiguration.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/OIDFederationAutomaticRegistrationProfileConfiguration.java
new file mode 100644
index 0000000..ea48d68
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/OIDFederationAutomaticRegistrationProfileConfiguration.java
@@ -0,0 +1,25 @@
+/*
+ * 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.oidfed.config;
+
+/**
+ * Profile configuration for an OpenID Federation Automatic Registration.
+ */
+public interface OIDFederationAutomaticRegistrationProfileConfiguration extends OIDFederationRegistrationProfileConfiguration {
+
+ /** ID for this profile configuration. */
+ public static final String PROFILE_ID = "http://shibboleth.net/ns/profiles/oidfed/automaticregistration";
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/OIDFederationEntityConfigurationProfileConfiguration.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/OIDFederationEntityConfigurationProfileConfiguration.java
new file mode 100644
index 0000000..fa05db0
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/OIDFederationEntityConfigurationProfileConfiguration.java
@@ -0,0 +1,68 @@
+/*
+ * 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.oidfed.config;
+
+import java.time.Duration;
+import java.util.List;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import net.shibboleth.profile.config.OverriddenIssuerProfileConfiguration;
+import net.shibboleth.shared.annotation.ConfigurationSetting;
+import net.shibboleth.shared.annotation.constraint.NonnullElements;
+import net.shibboleth.shared.annotation.constraint.NotLive;
+import net.shibboleth.shared.annotation.constraint.Positive;
+import net.shibboleth.shared.annotation.constraint.Unmodifiable;
+
+/**
+ * Profile configuration for an OpenID Federation Entity Configuration.
+ */
+public interface OIDFederationEntityConfigurationProfileConfiguration extends OverriddenIssuerProfileConfiguration,
+ OIDFederationProfileConfiguration, OIDFederationEntityStatementProducingProfileConfiguration,
+ OIDFederationResponseCachingProfileConfiguration{
+
+ /** OIDC base protocol URI. Section 4 is relevant. */
+ public static final String PROTOCOL_URI = "https://openid.net/specs/openid-federation-1_0.html";
+
+ /** ID for this profile configuration. */
+ public static final String PROFILE_ID = "http://shibboleth.net/ns/profiles/oidfed/configuration";
+
+ /**
+ * Get the authority hints to be included to the entity configuration.
+ *
+ * @param profileRequestContext profile request context
+ *
+ * @return authority hints to be included to the entity configuration
+ */
+ @ConfigurationSetting(name="authorityHints")
+ @Nonnull @NonnullElements @NotLive @Unmodifiable List<String> getAuthorityHints(
+ @Nullable final ProfileRequestContext profileRequestContext);
+
+ /**
+ * Get entity statement lifetime.
+ *
+ * <p>Defaults to 24 hours.</p>
+ *
+ * @param profileRequestContext profile request context
+ *
+ * @return entity statement lifetime
+ */
+ @ConfigurationSetting(name="entityStatementLifetime")
+ @Positive @Nonnull Duration getEntityStatementLifetime(@Nullable final ProfileRequestContext profileRequestContext);
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/OIDFederationEntityStatementProducingProfileConfiguration.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/OIDFederationEntityStatementProducingProfileConfiguration.java
new file mode 100644
index 0000000..61711f6
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/OIDFederationEntityStatementProducingProfileConfiguration.java
@@ -0,0 +1,43 @@
+/*
+ * 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.oidfed.config;
+
+import java.util.Map;
+import java.util.function.BiFunction;
+
+import javax.annotation.Nullable;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import net.shibboleth.shared.annotation.ConfigurationSetting;
+
+/**
+ * Configuration common to OpenID Federation Entity Statement producing profiles.
+ */
+public interface OIDFederationEntityStatementProducingProfileConfiguration extends OIDFederationProfileConfiguration {
+
+ /**
+ * Get the bi-function for manipulating entity statement claims set.
+ *
+ * @param profileRequestContext profile request context
+ *
+ * @return the bi-function for manipulating entity statement claims set
+ */
+ @ConfigurationSetting(name="entityStatementClaimsSetManipulationStrategy")
+ @Nullable BiFunction<ProfileRequestContext,Map<String,Object>,Map<String,Object>>
+ getEntityStatementClaimsSetManipulationStrategy(
+ @Nullable final ProfileRequestContext profileRequestContext);
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/OIDFederationExplicitRegistrationProfileConfiguration.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/OIDFederationExplicitRegistrationProfileConfiguration.java
new file mode 100644
index 0000000..97a7292
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/OIDFederationExplicitRegistrationProfileConfiguration.java
@@ -0,0 +1,52 @@
+/*
+ * 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.oidfed.config;
+
+import java.util.Set;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import net.shibboleth.oidc.profile.oauth2.config.OAuth2FlowAwareProfileConfiguration;
+import net.shibboleth.profile.config.OverriddenIssuerProfileConfiguration;
+import net.shibboleth.shared.annotation.ConfigurationSetting;
+import net.shibboleth.shared.annotation.constraint.NonnullElements;
+import net.shibboleth.shared.annotation.constraint.NotLive;
+import net.shibboleth.shared.annotation.constraint.Unmodifiable;
+
+/**
+ * Profile configuration for an OpenID Federation Explicit Registration.
+ */
+public interface OIDFederationExplicitRegistrationProfileConfiguration
+ extends OIDFederationRegistrationProfileConfiguration, OAuth2FlowAwareProfileConfiguration,
+ OIDFederationEntityStatementProducingProfileConfiguration, OverriddenIssuerProfileConfiguration {
+
+ /** ID for this profile configuration. */
+ public static final String PROFILE_ID = "http://shibboleth.net/ns/profiles/oidfed/explicitregistration";
+
+ /**
+ * Get the enabled token endpoint authentication methods.
+ *
+ * @param profileRequestContext profile request context
+ *
+ * @return enabled token endpoint authentication methods
+ */
+ @ConfigurationSetting(name="tokenEndpointAuthMethods")
+ @Nonnull @NonnullElements @NotLive @Unmodifiable Set<String> getTokenEndpointAuthMethods(
+ @Nullable final ProfileRequestContext profileRequestContext);
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/OIDFederationProfileConfiguration.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/OIDFederationProfileConfiguration.java
new file mode 100644
index 0000000..5abc926
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/OIDFederationProfileConfiguration.java
@@ -0,0 +1,23 @@
+/*
+ * 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.oidfed.config;
+
+import net.shibboleth.oidc.profile.oauth2.config.OAuth2ProfileConfiguration;
+
+/** Common interface for OpenID Federation 1.0 Profile Configurations.*/
+public interface OIDFederationProfileConfiguration extends OAuth2ProfileConfiguration {
+
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/OIDFederationRegistrationProfileConfiguration.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/OIDFederationRegistrationProfileConfiguration.java
new file mode 100644
index 0000000..98277cc
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/OIDFederationRegistrationProfileConfiguration.java
@@ -0,0 +1,66 @@
+
+package net.shibboleth.idp.plugin.oidc.op.oidfed.config;
+
+import java.time.Duration;
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import net.shibboleth.oidc.metadata.policy.MetadataPolicy;
+import net.shibboleth.oidc.profile.oauth2.config.OAuth2ProfileConfiguration;
+import net.shibboleth.shared.annotation.ConfigurationSetting;
+import net.shibboleth.shared.annotation.constraint.NonnullElements;
+import net.shibboleth.shared.annotation.constraint.NotLive;
+import net.shibboleth.shared.annotation.constraint.Positive;
+import net.shibboleth.shared.annotation.constraint.Unmodifiable;
+
+/**
+ * Profile configuration for an OpenID Federation profiles related to client registration.
+ */
+public interface OIDFederationRegistrationProfileConfiguration extends OAuth2ProfileConfiguration {
+
+ /** OpenID Federation base protocol URI. */
+ public static final String PROTOCOL_URI = "https://openid.net/specs/openid-federation-1_0.html";
+
+ /**
+ * Get local metadata policy to be merged into the federation policy.
+ *
+ * <p>Defaults to empty map.</p>
+ *
+ * @param profileRequestContext profile request context
+ *
+ * @return local metadata policy
+ */
+ @ConfigurationSetting(name="localMetadataPolicy")
+ @Nonnull @NonnullElements @NotLive @Unmodifiable
+ Map<String, MetadataPolicy> getLocalMetadataPolicy(@Nullable final ProfileRequestContext profileRequestContext);
+
+ /**
+ * Get the mandatory trust mark identifiers required by this profile configuration.
+ *
+ * @param profileRequestContext profile request context
+ *
+ * @return mandatory trust mark identifiers
+ */
+ @ConfigurationSetting(name="mandatoryTrustMarks")
+ @Nonnull @NonnullElements @NotLive @Unmodifiable List<String> getMandatoryTrustMarks(
+ @Nullable final ProfileRequestContext profileRequestContext);
+
+ /**
+ * Get maximum lifetime for trust marks.
+ *
+ * <p>Defaults to one year.</p>
+ *
+ * @param profileRequestContext profile request context
+ *
+ * @return maximum lifetime
+ */
+ @ConfigurationSetting(name="maximumTrustMarkLifetime")
+ @Positive @Nonnull
+ Duration getMaximumTrustMarkLifetime(@Nullable final ProfileRequestContext profileRequestContext);
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/OIDFederationResolveEntityProfileConfiguration.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/OIDFederationResolveEntityProfileConfiguration.java
new file mode 100644
index 0000000..6aaac8c
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/OIDFederationResolveEntityProfileConfiguration.java
@@ -0,0 +1,52 @@
+/*
+ * 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.oidfed.config;
+
+import java.time.Duration;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import net.shibboleth.profile.config.OverriddenIssuerProfileConfiguration;
+import net.shibboleth.shared.annotation.ConfigurationSetting;
+import net.shibboleth.shared.annotation.constraint.Positive;
+
+/**
+ * Profile configuration for an OpenID Federation Resolve Entity.
+ */
+public interface OIDFederationResolveEntityProfileConfiguration extends OverriddenIssuerProfileConfiguration,
+ OIDFederationProfileConfiguration, OIDFederationResponseCachingProfileConfiguration {
+
+ /** OIDC base protocol URI. */
+ public static final String PROTOCOL_URI = "https://openid.net/specs/openid-federation-1_0.html";
+
+ /** ID for this profile configuration. */
+ public static final String PROFILE_ID = "http://shibboleth.net/ns/profiles/oidfed/resolve-entity";
+
+ /**
+ * Get cached error response lifetime.
+ *
+ * <p>Defaults to 5 minutes.</p>
+ *
+ * @param profileRequestContext profile request context
+ *
+ * @return cached error response lifetime
+ */
+ @ConfigurationSetting(name="cachedErrorResponseLifetime")
+ @Positive @Nonnull
+ Duration getCachedErrorResponseLifetime(@Nullable final ProfileRequestContext profileRequestContext);
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/OIDFederationResponseCachingProfileConfiguration.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/OIDFederationResponseCachingProfileConfiguration.java
new file mode 100644
index 0000000..5a0f143
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/OIDFederationResponseCachingProfileConfiguration.java
@@ -0,0 +1,47 @@
+/*
+ * 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.oidfed.config;
+
+import java.time.Duration;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import net.shibboleth.profile.config.OverriddenIssuerProfileConfiguration;
+import net.shibboleth.shared.annotation.ConfigurationSetting;
+import net.shibboleth.shared.annotation.constraint.Positive;
+
+/**
+ * Common interface for OpenID Federation Profiles producing cacheable response messages.
+ */
+public interface OIDFederationResponseCachingProfileConfiguration extends OverriddenIssuerProfileConfiguration,
+ OIDFederationProfileConfiguration {
+
+ /**
+ * Get cached success response lifetime.
+ *
+ * <p>Defaults to 5 minutes.</p>
+ *
+ * @param profileRequestContext profile request context
+ *
+ * @return cached success response lifetime
+ */
+ @ConfigurationSetting(name="cachedSuccessResponseLifetime")
+ @Positive @Nonnull
+ Duration getCachedSuccessResponseLifetime(@Nullable final ProfileRequestContext profileRequestContext);
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/RelyingPartyConfigurationSupport.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/RelyingPartyConfigurationSupport.java
new file mode 100644
index 0000000..f40f80a
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/RelyingPartyConfigurationSupport.java
@@ -0,0 +1,60 @@
+/*
+ * 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.oidfed.config;
+
+import java.util.Collection;
+
+import javax.annotation.Nonnull;
+
+import net.shibboleth.profile.relyingparty.BasicRelyingPartyConfiguration;
+import net.shibboleth.profile.relyingparty.RelyingPartyConfiguration;
+import net.shibboleth.shared.logic.Constraint;
+
+/**
+ * Support functions for building {@link RelyingPartyConfiguration} objects with activation conditions.
+ */
+public class RelyingPartyConfigurationSupport {
+
+ /**
+ * A shorthand method for constructing a {@link BasicRelyingPartyConfiguration} with an activation condition
+ * based on one or more trust anchor IDs.
+ *
+ * <p>If a single ID is supplied, then the ID is also set as the identifier for the configuration.</p>
+ *
+ * @param trustAnchorIds the trust anchors for which the configuration should be active
+ *
+ * @return a default-constructed configuration with the appropriate condition set
+ */
+ @Nonnull
+ public static BasicRelyingPartyConfiguration byTrustAnchor(@Nonnull final Collection<String> trustAnchorIds) {
+
+ Constraint.isNotNull(trustAnchorIds, "Trust Anchor ID list cannot be null");
+
+ final BasicRelyingPartyConfiguration config = new BasicRelyingPartyConfiguration();
+ config.setActivationCondition(new TrustAnchorIdPredicate(trustAnchorIds));
+
+ final StringBuffer name = new StringBuffer("TrustAnchorIDs[");
+ for (final String taId: trustAnchorIds) {
+ name.append(taId).append(',');
+
+ }
+ name.append(']');
+ final String id = name.toString();
+ assert id != null;
+ config.setId(id);
+ return config;
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/TokenEndpointAuthMethodLookupFunction.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/TokenEndpointAuthMethodLookupFunction.java
new file mode 100644
index 0000000..2758248
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/TokenEndpointAuthMethodLookupFunction.java
@@ -0,0 +1,55 @@
+/*
+ * 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.oidfed.config;
+
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import javax.annotation.Nullable;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import com.nimbusds.oauth2.sdk.auth.ClientAuthenticationMethod;
+
+import net.shibboleth.profile.context.RelyingPartyContext;
+import net.shibboleth.profile.context.navigate.AbstractRelyingPartyLookupFunction;
+
+/**
+ * A function that obtains
+ * {@link OIDFederationExplicitRegistrationProfileConfiguration#getTokenEndpointAuthMethods(ProfileRequestContext)}
+ * if such a profile is available from a {@link RelyingPartyContext} obtained via a lookup function,
+ * by default a child of the {@link ProfileRequestContext}. That result is then transformed into a list
+ * of {@link ClientAuthenticationMethod}s.
+ *
+ * <p>If a specific setting is unavailable, a null value is returned.</p>
+ */
+public class TokenEndpointAuthMethodLookupFunction
+ extends AbstractRelyingPartyLookupFunction<Set<ClientAuthenticationMethod>> {
+
+ /** {@inheritDoc} */
+ @Override
+ @Nullable public Set<ClientAuthenticationMethod> apply(@Nullable final ProfileRequestContext input) {
+ return Optional.ofNullable(getRelyingPartyContextLookupStrategy().apply(input))
+ .map(relyingPartyContext -> relyingPartyContext.getProfileConfig())
+ .filter(OIDFederationExplicitRegistrationProfileConfiguration.class::isInstance)
+ .map(OIDFederationExplicitRegistrationProfileConfiguration.class::cast)
+ .map(config -> config.getTokenEndpointAuthMethods(input).stream()
+ .map(ClientAuthenticationMethod::new)
+ .collect(Collectors.toUnmodifiableSet()))
+ .orElse(null);
+ }
+
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/TrustAnchorIdLookupFunction.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/TrustAnchorIdLookupFunction.java
new file mode 100644
index 0000000..d6ebfdb
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/TrustAnchorIdLookupFunction.java
@@ -0,0 +1,74 @@
+/*
+ * 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.oidfed.config;
+
+import java.util.Optional;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.messaging.context.navigate.ChildContextLookup;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.opensaml.profile.context.navigate.InboundMessageContextLookup;
+
+import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.RelyingPartyTrustChainContext;
+import net.shibboleth.shared.logic.Constraint;
+
+/**
+ * A function that returns selected trust anchor ID from a {@link RelyingPartyTrustChainContext} obtained via a lookup
+ * function.
+ *
+ * <p>If a specific setting is unavailable, a null value is returned.</p>
+ */
+public class TrustAnchorIdLookupFunction implements Function<ProfileRequestContext, String> {
+
+ /** Strategy used to lookup the trust chain context. */
+ @Nonnull private Function<ProfileRequestContext, RelyingPartyTrustChainContext> trustChainContextLookupStrategy;
+
+ /**
+ * Constructor.
+ */
+ public TrustAnchorIdLookupFunction() {
+ final Function<ProfileRequestContext, RelyingPartyTrustChainContext> tcls =
+ new ChildContextLookup<>(RelyingPartyTrustChainContext.class).compose(
+ new InboundMessageContextLookup());
+ assert tcls != null;
+ trustChainContextLookupStrategy = tcls;
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param strategy strategy used to lookup the trust chain context
+ */
+ public TrustAnchorIdLookupFunction(
+ @Nonnull final Function<ProfileRequestContext, RelyingPartyTrustChainContext> strategy) {
+ trustChainContextLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Nullable public String apply(@Nullable final ProfileRequestContext profileRequestContext) {
+ return Optional.ofNullable(profileRequestContext)
+ .map(profileCtx -> trustChainContextLookupStrategy.apply(profileCtx))
+ .map(trustChainCtx -> trustChainCtx.getSelectedTrustChain())
+ .filter(pair -> pair != null && pair.getFirst() != null)
+ .map(pair -> pair.getFirst())
+ .filter(list -> !list.isEmpty())
+ .map(chain -> chain.get(chain.size() - 1))
+ .map(statement -> statement.getEntityID().getValue())
+ .orElse(null);
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/TrustAnchorIdPredicate.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/TrustAnchorIdPredicate.java
new file mode 100644
index 0000000..0b381ed
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/config/TrustAnchorIdPredicate.java
@@ -0,0 +1,96 @@
+/*
+ * 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.oidfed.config;
+
+import java.util.Collection;
+import java.util.function.Predicate;
+
+import javax.annotation.Nonnull;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import net.shibboleth.shared.annotation.ParameterName;
+import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.collection.CollectionSupport;
+import net.shibboleth.shared.logic.StrategyIndirectedPredicate;
+import net.shibboleth.shared.primitive.StringSupport;
+
+/**
+ * Predicate that evaluates a {@link ProfileRequestContext} by looking for a trust anchor ID that matches one of a
+ * designated set, or a generic predicate.
+ */
+public class TrustAnchorIdPredicate extends StrategyIndirectedPredicate<ProfileRequestContext,String> {
+
+ /**
+ * Constructor.
+ *
+ * @param candidates hardwired set of values to check against
+ */
+ public TrustAnchorIdPredicate(@Nonnull @ParameterName(name="candidates") final Collection<String> candidates) {
+ super(new TrustAnchorIdLookupFunction(), StringSupport.normalizeStringCollection(candidates));
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param candidate a single value to check against
+ */
+ public TrustAnchorIdPredicate(@Nonnull @NotEmpty @ParameterName(name="candidate") final String candidate) {
+ this(CollectionSupport.singleton(candidate));
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param pred generalized predicate
+ */
+ public TrustAnchorIdPredicate(@Nonnull @ParameterName(name="pred") final Predicate<String> pred) {
+ super(new TrustAnchorIdLookupFunction(), pred);
+ }
+
+ /**
+ * Workaround for Spring type conversion ambiguities.
+ *
+ * @param candidates hardwired set of values to check against
+ *
+ * @return the predicate
+ */
+ @Nonnull public static TrustAnchorIdPredicate fromCandidates(@Nonnull final Collection<String> candidates) {
+ return new TrustAnchorIdPredicate(candidates);
+ }
+
+ /**
+ * Workaround for Spring type conversion ambiguities.
+ *
+ * @param candidate a single value to check against
+ *
+ * @return the predicate
+ */
+ @Nonnull public static TrustAnchorIdPredicate fromCandidate(@Nonnull @NotEmpty final String candidate) {
+ return new TrustAnchorIdPredicate(candidate);
+ }
+
+ /**
+ * Workaround for Spring type conversion ambiguities.
+ *
+ * @param pred generalized predicate
+ *
+ * @return the predicate
+ */
+ @Nonnull public static TrustAnchorIdPredicate fromPredicate(@Nonnull final Predicate<String> pred) {
+ return new TrustAnchorIdPredicate(pred);
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/decoding/impl/BaseOAuth2RequestDecoder.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/decoding/impl/BaseOAuth2RequestDecoder.java
new file mode 100644
index 0000000..2c9bbbc
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/decoding/impl/BaseOAuth2RequestDecoder.java
@@ -0,0 +1,117 @@
+/*
+ * 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.oidfed.decoding.impl;
+
+import java.net.URI;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.messaging.context.MessageContext;
+import org.opensaml.messaging.decoder.MessageDecodingException;
+import org.opensaml.messaging.decoder.servlet.AbstractHttpServletRequestMessageDecoder;
+import org.slf4j.Logger;
+
+import com.nimbusds.oauth2.sdk.Request;
+
+import jakarta.servlet.http.HttpServletRequest;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+/**
+ * TODO: duplicate with OP's impl
+ * Base decoder for Nimbus OAuth2 request messages.
+ *
+ * @param <T> The exact type of the request message, extends {@link Request}.
+ */
+public abstract class BaseOAuth2RequestDecoder<T extends Request> extends AbstractHttpServletRequestMessageDecoder {
+
+ /** Class logger. */
+ @Nonnull private final static Logger log = LoggerFactory.getLogger(BaseOAuth2RequestDecoder.class);
+
+ /** A flag to remove the IP address from the endpoint URI. */
+ private boolean removeIpAddressFromEndpointUri;
+
+ /** Constructor. */
+ public BaseOAuth2RequestDecoder() {
+ super();
+ setProtocolMessageLoggerSubCategory("OAUTH2");
+ }
+
+ /**
+ * Set the flag to remove the IP address from the endpoint URI.
+ *
+ * @param flag What to set.
+ */
+ public synchronized void setRemoveIpAddressFromEndpointUri(final boolean flag) {
+ ifInitializedThrowUnmodifiabledComponentException();
+ ifDestroyedThrowDestroyedComponentException();
+
+ removeIpAddressFromEndpointUri = flag;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doDecode() throws MessageDecodingException {
+ final MessageContext messageContext = new MessageContext();
+ final HttpServletRequest httpServletRequest = getHttpServletRequest();
+ assert httpServletRequest != null;
+ final T requestMessage;
+ requestMessage = parseMessage();
+ messageContext.setMessage(requestMessage);
+ setMessageContext(messageContext);
+ }
+
+ /**
+ * Parses the message into the exact type of the request message.
+ *
+ * @return The request message
+ * @throws MessageDecodingException if there is a problem decoding the message context
+ */
+ @Nullable protected abstract T parseMessage() throws MessageDecodingException;
+
+ /**
+ * Get the string representation of what will be logged as the protocol message.
+ *
+ * @param message the request message
+ * @return the string representing the protocol message for logging purposes
+ */
+ @Nullable protected abstract String getMessageToLog(final T message);
+
+ /** {@inheritDoc} */
+ @Override
+ @Nullable
+ @SuppressWarnings("unchecked")
+ protected String serializeMessageForLogging(@Nullable Object message) {
+ return getMessageToLog((T) message);
+ }
+
+ /**
+ * Returns the endpoint URI either from servlet request or from the given message, depending on the flag for
+ * removing IP address from the endpoint URI.
+ *
+ * @param message the message from which to take the endpoint URI (with IP address), if the flag is false
+ * @return the endpoint URI
+ */
+ @Nullable protected String getEndpointURI(final Request message) {
+ if (removeIpAddressFromEndpointUri) {
+ final HttpServletRequest httpServletRequest = getHttpServletRequest();
+ return httpServletRequest != null ? httpServletRequest.getRequestURI() : null;
+ } else {
+ final URI endpointUri = message.getEndpointURI();
+ return endpointUri != null ? endpointUri.toString() : null;
+ }
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/decoding/impl/ExplicitClientRegistrationRequestDecoder.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/decoding/impl/ExplicitClientRegistrationRequestDecoder.java
new file mode 100644
index 0000000..2723e04
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/decoding/impl/ExplicitClientRegistrationRequestDecoder.java
@@ -0,0 +1,134 @@
+/*
+ * 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.oidfed.decoding.impl;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.List;
+import java.util.Objects;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.messaging.decoder.MessageDecodingException;
+import org.slf4j.Logger;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.base.MoreObjects;
+import com.nimbusds.oauth2.sdk.http.HTTPRequest;
+import com.nimbusds.oauth2.sdk.http.JakartaServletUtils;
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import jakarta.servlet.http.HttpServletRequest;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.messaging.impl.ExplicitClientRegistrationRequest;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.EntityStatementHelper;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.tbd.RequestUtil;
+import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+/**
+ * Message decoder decoding OpenID Federation Explicit Registration request {@link ExplicitClientRegistrationRequest}.
+ *
+ * @since 4.3.0
+ */
+public class ExplicitClientRegistrationRequestDecoder
+ extends BaseOAuth2RequestDecoder<ExplicitClientRegistrationRequest> {
+
+ /** Class logger. */
+ @Nonnull
+ private final Logger log = LoggerFactory.getLogger(ExplicitClientRegistrationRequestDecoder.class);
+
+ /** Object mapper used for pretty-printing JSON in the request and decoding trust chain from the request. */
+ @NonnullAfterInit private ObjectMapper objectMapper;
+
+ /**
+ * Set the object mapper used for pretty-printing JSON in the request and decoding trust chain from the request.
+ *
+ * @param mapper What to set.
+ */
+ public void setObjectMapper(@Nonnull final ObjectMapper mapper) {
+ checkSetterPreconditions();
+ objectMapper = Constraint.isNotNull(mapper, "Object mapper cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+
+ if (objectMapper == null) {
+ throw new ComponentInitializationException("Object mapper cannot be null");
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected ExplicitClientRegistrationRequest parseMessage() throws MessageDecodingException {
+ final HttpServletRequest request = getHttpServletRequest();
+ assert request != null;
+ if (!"POST".equalsIgnoreCase(request.getMethod())) {
+ throw new MessageDecodingException("This message decoder only supports the HTTP POST method");
+ }
+ try {
+ final HTTPRequest httpRequest = JakartaServletUtils.createHTTPRequest(request);
+ getProtocolMessageLogger().trace("Inbound request {}", RequestUtil.toString(httpRequest, objectMapper));
+ final URI uri = httpRequest.getURI();
+ if (uri == null) {
+ throw new MessageDecodingException("Could not parse request URI");
+ }
+ final String contentType = request.getContentType();
+ if ("application/entity-statement+jwt".equals(contentType)) {
+ final EntityStatement entityConfiguration =
+ EntityStatementHelper.deserializeEntityStatement(httpRequest.getQuery());
+ if (entityConfiguration == null) {
+ throw new MessageDecodingException("Could not deserialize entity configuration");
+ }
+ log.trace("Entity configuration claims set: {}", entityConfiguration.getClaimsSet());
+ return new ExplicitClientRegistrationRequest(uri, entityConfiguration);
+ } else if ("application/trust-chain+json".equals(contentType)) {
+ final TypeReference<List<String>> typeReference = new TypeReference<List<String>>() {};
+ final List<String> strings = objectMapper.readValue(httpRequest.getQuery(), typeReference);
+ final List<EntityStatement> trustChain = strings.stream()
+ .map(string -> EntityStatementHelper.deserializeEntityStatement(string))
+ .filter(Objects::nonNull)
+ .toList();
+ if (trustChain == null || trustChain.isEmpty()) {
+ throw new MessageDecodingException("Could not deserialize trust chain");
+ }
+ return new ExplicitClientRegistrationRequest(uri, trustChain);
+ } else {
+ log.warn("Unexpected content type {}", contentType);
+ throw new MessageDecodingException("Unexpected content type: " + contentType);
+ }
+ } catch (final IOException e) {
+ log.error("Could not create HTTP request from the request", e);
+ throw new MessageDecodingException(e);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected String getMessageToLog(@Nullable final ExplicitClientRegistrationRequest message) {
+ return message == null ? null : MoreObjects.toStringHelper(this).omitNullValues()
+ .add("entityConfiguration", EntityStatementHelper.getSerializedEntityStatement(
+ message.getEntityConfiguration()))
+ .add("trustChain", EntityStatementHelper.getSerializedTrustChain(message.getTrustChain()))
+ .add("endpointURI", getEndpointURI(message))
+ .toString();
+ }
+
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/decoding/impl/ResolveEntityRequestDecoder.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/decoding/impl/ResolveEntityRequestDecoder.java
new file mode 100644
index 0000000..ec64f0b
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/decoding/impl/ResolveEntityRequestDecoder.java
@@ -0,0 +1,98 @@
+/*
+ * 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.oidfed.decoding.impl;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.messaging.decoder.MessageDecodingException;
+import org.slf4j.Logger;
+
+import com.google.common.base.MoreObjects;
+import com.nimbusds.oauth2.sdk.http.HTTPRequest;
+import com.nimbusds.oauth2.sdk.http.JakartaServletUtils;
+
+import jakarta.servlet.http.HttpServletRequest;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.messaging.impl.ResolveEntityRequest;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.tbd.RequestUtil;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+/**
+ * Message decoder decoding OpenID Federation Resolve Entity request {@link ResolveEntityRequest}.
+ *
+ * @since 4.3.0
+ */
+public class ResolveEntityRequestDecoder extends BaseOAuth2RequestDecoder<ResolveEntityRequest> {
+
+ /** Class logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(ResolveEntityRequestDecoder.class);
+
+ /** {@inheritDoc} */
+ @Override
+ protected ResolveEntityRequest parseMessage() throws MessageDecodingException {
+ final HttpServletRequest request = getHttpServletRequest();
+ assert request != null;
+ if (!"GET".equalsIgnoreCase(request.getMethod())) {
+ throw new MessageDecodingException("This message decoder only supports the HTTP GET method");
+ }
+ try {
+ final HTTPRequest httpRequest = JakartaServletUtils.createHTTPRequest(request);
+ getProtocolMessageLogger().trace("Inbound request {}", RequestUtil.toString(httpRequest, null));
+ final URI uri = httpRequest.getURI();
+ if (uri == null) {
+ throw new MessageDecodingException("Could not parse request URI");
+ }
+ final Map<String, List<String>> parameters = httpRequest.getQueryParameters();
+ final String subject = Optional.ofNullable(parameters.get("sub"))
+ .filter(Objects::nonNull)
+ .filter(list -> list.size() == 1)
+ .map(list -> list.get(0))
+ .orElse(null);
+ if (subject == null) {
+ throw new MessageDecodingException("No single sub value in the request");
+ }
+ final List<String> trustAnchors = Optional.ofNullable(parameters.get("trust_anchor"))
+ .filter(Objects::nonNull)
+ .filter(list -> list.size() > 0)
+ .orElse(null);
+ if (trustAnchors == null) {
+ throw new MessageDecodingException("No trust_anchor included in the request");
+ }
+ return new ResolveEntityRequest(uri, subject, trustAnchors, parameters.get("entity_type"));
+ } catch (final IOException e) {
+ log.error("Could not create HTTP request from the request", e);
+ throw new MessageDecodingException(e);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected String getMessageToLog(@Nullable final ResolveEntityRequest message) {
+ return message == null ? null : MoreObjects.toStringHelper(this).omitNullValues()
+ .add("subject", message.getSubject())
+ .add("trustAnchors", message.getTrustAnchors())
+ .add("entityTypes", message.getEntityTypes())
+ .add("endpointURI", getEndpointURI(message))
+ .toString();
+ }
+
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/messaging/impl/ExplicitClientRegistrationRequest.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/messaging/impl/ExplicitClientRegistrationRequest.java
new file mode 100644
index 0000000..5a9d978
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/messaging/impl/ExplicitClientRegistrationRequest.java
@@ -0,0 +1,100 @@
+/*
+ * 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.oidfed.messaging.impl;
+
+import java.net.URI;
+import java.util.List;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import com.nimbusds.oauth2.sdk.Request;
+import com.nimbusds.oauth2.sdk.http.HTTPRequest;
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.logic.Constraint;
+
+/**
+ * Request message to the OpenID federation explicit registration endpoint.
+ */
+public class ExplicitClientRegistrationRequest implements Request {
+
+ /** The endpoint URI of the request. */
+ @Nonnull private final URI endpointUri;
+
+ /** The entity configuration from the request. */
+ @Nullable private final EntityStatement entityConfiguration;
+
+ /** The trust chain from the request. */
+ @Nullable private final List<EntityStatement> trustChain;
+
+ /**
+ * Constructor.
+ *
+ * @param uri endpoint URI
+ * @param configuration client configuration
+ */
+ public ExplicitClientRegistrationRequest(@Nonnull final URI uri, @Nonnull final EntityStatement configuration) {
+ endpointUri = Constraint.isNotNull(uri, "Endpoint URI cannot be null");
+ entityConfiguration = Constraint.isNotNull(configuration, "Entity configuration cannot be null");
+ trustChain = null;
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param uri endpoint URI
+ * @param chain trust chain
+ */
+ public ExplicitClientRegistrationRequest(@Nonnull final URI uri,
+ @Nonnull @NotEmpty final List<EntityStatement> chain) {
+ endpointUri = Constraint.isNotNull(uri, "Endpoint URI cannot be null");
+ Constraint.isNotEmpty(chain, "Trust chain cannot be empty");
+ trustChain = chain;
+ entityConfiguration = null;
+ }
+
+ /** {@inheritDoc} */
+ @Override @Nonnull
+ public URI getEndpointURI() {
+ return endpointUri;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public HTTPRequest toHTTPRequest() {
+ //TODO
+ return null;
+ }
+
+ /**
+ * Get the entity configuration from the request.
+ *
+ * @return entity configuration
+ */
+ @Nullable public EntityStatement getEntityConfiguration() {
+ return entityConfiguration;
+ }
+
+ /**
+ * Get the trust chain from the request.
+ *
+ * @return trust chain
+ */
+ @Nullable public List<EntityStatement> getTrustChain() {
+ return trustChain;
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/messaging/impl/ExplicitClientRegistrationResponse.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/messaging/impl/ExplicitClientRegistrationResponse.java
new file mode 100644
index 0000000..827e6d5
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/messaging/impl/ExplicitClientRegistrationResponse.java
@@ -0,0 +1,97 @@
+/*
+ * 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.oidfed.messaging.impl;
+
+import javax.annotation.Nonnull;
+
+import com.nimbusds.jwt.SignedJWT;
+import com.nimbusds.oauth2.sdk.ParseException;
+import com.nimbusds.oauth2.sdk.Response;
+import com.nimbusds.oauth2.sdk.http.HTTPResponse;
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.StringSupport;
+
+/**
+ * Response message to the OpenID federation explicit registration endpoint.
+ */
+public class ExplicitClientRegistrationResponse implements Response {
+
+ /** The entity statement included in the response. */
+ @Nonnull private final EntityStatement entityStatement;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param statement entity statement
+ */
+ public ExplicitClientRegistrationResponse(@Nonnull final EntityStatement statement) {
+ entityStatement = Constraint.isNotNull(statement, "Entity statement cannot be null");
+ }
+
+ /**
+ * Get the entity statement included in the response.
+ *
+ * @return entity statement
+ */
+ @Nonnull public EntityStatement getEntityStatement() {
+ return entityStatement;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean indicatesSuccess() {
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public HTTPResponse toHTTPResponse() {
+ final HTTPResponse httpResponse = new HTTPResponse(HTTPResponse.SC_OK);
+ httpResponse.setEntityContentType(EntityStatement.CONTENT_TYPE);
+ httpResponse.setContent(entityStatement.getSignedStatement().serialize());
+ return httpResponse;
+ }
+
+ /**
+ * Parses a federation explicit registration success response from the given HTTP response.
+ *
+ * @param httpResponse the HTTP response
+ * @return explicit registration success response
+ * @throws ParseException if HTTP response could not be parsed into registration response
+ */
+ @Nonnull
+ public static ExplicitClientRegistrationResponse parse(@Nonnull final HTTPResponse httpResponse)
+ throws ParseException {
+
+ httpResponse.ensureStatusCode(HTTPResponse.SC_OK);
+ httpResponse.ensureEntityContentType(EntityStatement.CONTENT_TYPE);
+ final String content = httpResponse.getContent();
+
+ if (StringSupport.trimOrNull(content) == null) {
+ throw new ParseException("Message body is empty");
+ }
+
+ try {
+ final EntityStatement entityStatement = EntityStatement.parse(SignedJWT.parse(httpResponse.getContent()));
+ assert entityStatement != null;
+ return new ExplicitClientRegistrationResponse(entityStatement);
+ } catch (final java.text.ParseException e) {
+ throw new ParseException(e.getMessage(), e);
+ }
+ }
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/messaging/impl/ResolveEntityRequest.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/messaging/impl/ResolveEntityRequest.java
new file mode 100644
index 0000000..2c00b0f
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/messaging/impl/ResolveEntityRequest.java
@@ -0,0 +1,135 @@
+/*
+ * 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.oidfed.messaging.impl;
+
+import java.net.URI;
+import java.util.List;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import com.google.common.base.MoreObjects;
+import com.nimbusds.oauth2.sdk.Request;
+import com.nimbusds.oauth2.sdk.http.HTTPRequest;
+
+import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.collection.CollectionSupport;
+import net.shibboleth.shared.logic.Constraint;
+
+/**
+ * Request message to the OpenID federation resolve entity API.
+ */
+public class ResolveEntityRequest implements Request {
+
+ /** The endpoint URI of the request. */
+ @Nonnull private final URI endpointUri;
+
+ /** The requested subject. */
+ @Nonnull @NotEmpty private final String subject;
+
+ /** The requested trust anchors. */
+ @Nonnull @NotEmpty private final List<String> trustAnchors;
+
+ /** The requested entity types to resolve. */
+ @Nonnull private final List<String> entityTypes;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param uri endpoint URI
+ * @param sub subject
+ * @param anchors trust anchors
+ * @param types optional entity types
+ */
+ public ResolveEntityRequest(@Nonnull final URI uri,
+ @Nonnull @NotEmpty final String sub,
+ @Nonnull @NotEmpty final List<String> anchors,
+ @Nullable final List<String> types) {
+ endpointUri = Constraint.isNotNull(uri, "Endpoint URI cannot be null");
+ subject = Constraint.isNotNull(sub, "Subject cannot be empty");
+ Constraint.isNotEmpty(anchors, "Trust anchors cannot be empty");
+ trustAnchors = anchors;
+ entityTypes = types == null ? CollectionSupport.emptyList() : CollectionSupport.copyToList(types);
+ }
+
+ /**
+ * Returns the requested subject.
+ *
+ * @return The subject.
+ */
+ @Nonnull @NotEmpty public String getSubject() {
+ return subject;
+ }
+
+ /**
+ * Returns the requested trust anchor.
+ *
+ * @return The trust anchor.
+ */
+ @Nonnull @NotEmpty public List<String> getTrustAnchors() {
+ return trustAnchors;
+ }
+
+ /**
+ * Returns the requested entity type to resolve.
+ *
+ * @return The entity type to resolve.
+ */
+ @Nonnull public List<String> getEntityTypes() {
+ return entityTypes;
+ }
+
+ /** {@inheritDoc} */
+ @Override @Nonnull public URI getEndpointURI() {
+ return endpointUri;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public HTTPRequest toHTTPRequest() {
+ //TODO
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("subject", getSubject())
+ .add("trustAnchors", getTrustAnchors())
+ .add("entityTypes", getEntityTypes())
+ .add("endpointURI", getEndpointURI())
+ .toString();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final ResolveEntityRequest other = (ResolveEntityRequest) obj;
+ return endpointUri.equals(other.endpointUri) && subject.equals(other.subject) &&
+ entityTypes.containsAll(other.entityTypes) && other.entityTypes.containsAll(entityTypes) &&
+ trustAnchors.containsAll(other.trustAnchors) && other.trustAnchors.containsAll(trustAnchors);
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/messaging/impl/ResolveEntityResponse.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/messaging/impl/ResolveEntityResponse.java
new file mode 100644
index 0000000..7372859
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/messaging/impl/ResolveEntityResponse.java
@@ -0,0 +1,99 @@
+/*
+ * 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.oidfed.messaging.impl;
+
+import javax.annotation.Nonnull;
+
+import com.nimbusds.common.contenttype.ContentType;
+import com.nimbusds.jwt.SignedJWT;
+import com.nimbusds.oauth2.sdk.ParseException;
+import com.nimbusds.oauth2.sdk.Response;
+import com.nimbusds.oauth2.sdk.http.HTTPResponse;
+
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.StringSupport;
+
+/**
+ * Response message to the OpenID federation resolve entity endpoint.
+ */
+public class ResolveEntityResponse implements Response {
+
+ /** The content type. */
+ @Nonnull public static final ContentType CONTENT_TYPE = new ContentType("application", "resolve-response+jwt");
+
+ /** The JWT included in the response. */
+ @Nonnull private final SignedJWT jwt;
+
+ /**
+ * Constructor.
+ *
+ * @param statement JWT
+ */
+ public ResolveEntityResponse(@Nonnull final SignedJWT statement) {
+ jwt = Constraint.isNotNull(statement, "Entity statement cannot be null");
+ }
+
+ /**
+ * Get the JWT included in the response.
+ *
+ * @return JWT
+ */
+ @Nonnull public SignedJWT getJWT() {
+ return jwt;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean indicatesSuccess() {
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public HTTPResponse toHTTPResponse() {
+ final HTTPResponse httpResponse = new HTTPResponse(HTTPResponse.SC_OK);
+ httpResponse.setEntityContentType(CONTENT_TYPE);
+ httpResponse.setContent(jwt.serialize());
+ return httpResponse;
+ }
+
+ /**
+ * Parses a federation resolve entity success response from the given HTTP response.
+ *
+ * @param httpResponse the HTTP response
+ * @return resolve entity success response
+ * @throws ParseException if HTTP response could not be parsed into resolve entity response
+ */
+ @Nonnull
+ public static ResolveEntityResponse parse(@Nonnull final HTTPResponse httpResponse)
+ throws ParseException {
+
+ httpResponse.ensureStatusCode(HTTPResponse.SC_OK);
+ httpResponse.ensureEntityContentType(CONTENT_TYPE);
+ final String content = httpResponse.getContent();
+
+ if (StringSupport.trimOrNull(content) == null) {
+ throw new ParseException("Message body is empty");
+ }
+
+ try {
+ final SignedJWT jwt = SignedJWT.parse(httpResponse.getContent());
+ assert jwt != null;
+ return new ResolveEntityResponse(jwt);
+ } catch (final java.text.ParseException e) {
+ throw new ParseException(e.getMessage(), e);
+ }
+ }
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/AbstractTrustEngineSignatureValidationComponent.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/AbstractTrustEngineSignatureValidationComponent.java
new file mode 100644
index 0000000..45c847c
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/AbstractTrustEngineSignatureValidationComponent.java
@@ -0,0 +1,104 @@
+/*
+ * 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.oidfed.metadata;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.security.SecurityException;
+import org.opensaml.security.trust.TrustEngine;
+import org.slf4j.Logger;
+
+import com.nimbusds.jwt.SignedJWT;
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.component.AbstractIdentifiableInitializableComponent;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.resolver.CriteriaSet;
+
+/**
+ * Abstract component performing signature validation via {@link TrustEngine}.
+ */
+public class AbstractTrustEngineSignatureValidationComponent extends AbstractIdentifiableInitializableComponent {
+
+ /** Class logger. */
+ @Nonnull private Logger log = LoggerFactory.getLogger(AbstractTrustEngineSignatureValidationComponent.class);
+
+ /** Trust engine used to validate a signature. */
+ @NonnullAfterInit private TrustEngine<SignedJWT> trustEngine;
+
+ /** Set of externally specified default criteria for input to the trust engine. */
+ @Nullable private CriteriaSet defaultCriteria;
+
+ /**
+ * Set trust engine used to validate a signature.
+ *
+ * @param engine trust engine
+ */
+ public void setTrustEngine(@Nonnull final TrustEngine<SignedJWT> engine) {
+ checkSetterPreconditions();
+ trustEngine = Constraint.isNotNull(engine, "Trust Engine cannot be null");
+ }
+
+ /**
+ * Set the optional set of default criteria used as input to the trust engine.
+ *
+ * @param criteria criteria set to use
+ */
+ public void setDefaultCriteria(@Nullable final CriteriaSet criteria) {
+ checkSetterPreconditions();
+ defaultCriteria = criteria;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+ if (trustEngine == null) {
+ throw new ComponentInitializationException("Trust Engine cannot be null");
+ }
+ }
+
+ /**
+ * Validates the given entity statement via trust engine and the given criteria.
+ *
+ * @param entityStatement the entity statement to be validated
+ * @param criteria the criteria (expanded with the optional default criteria)
+ * @param entityId the entity ID used for logging
+ * @return true if validation was successful, false otherwise
+ */
+ protected boolean validateStatement(@Nonnull final EntityStatement entityStatement,
+ @Nonnull final CriteriaSet criteria, @Nullable final String entityId) {
+ if (defaultCriteria != null && !defaultCriteria.isEmpty()) {
+ criteria.addAll(defaultCriteria);
+ }
+ try {
+ final SignedJWT jwt = entityStatement.getSignedStatement();
+ assert jwt != null;
+ if (trustEngine.validate(jwt, criteria)) {
+ log.debug("Successfully validated entity statement for {}", entityId);
+ return true;
+ }
+ } catch (final SecurityException e) {
+ log.debug("Could not validate entity statement for {}", entityId, e);
+ }
+ log.warn("Trust Engine validation failed for {}", entityId);
+ return false;
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultCombinedMetadataFromTrustChainLookupStrategy.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultCombinedMetadataFromTrustChainLookupStrategy.java
new file mode 100644
index 0000000..ec2eda5
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultCombinedMetadataFromTrustChainLookupStrategy.java
@@ -0,0 +1,109 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.collection.CollectionSupport;
+import net.shibboleth.shared.component.AbstractIdentifiableInitializableComponent;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+/**
+ * Default strategy to combine metadata claim contents from the trust chain by exploiting both entity configuration
+ * and subordinate statement issued by the immediate superior.
+ */
+public class DefaultCombinedMetadataFromTrustChainLookupStrategy extends AbstractIdentifiableInitializableComponent
+ implements Function<List<EntityStatement>,Map<String,Map<String,Object>>> {
+
+ /** Class logger. */
+ @Nonnull private Logger log = LoggerFactory.getLogger(DefaultCombinedMetadataFromTrustChainLookupStrategy.class);
+
+ /** Object mapper used for deserializing metadata. */
+ @NonnullAfterInit private ObjectMapper objectMapper;
+
+ /**
+ * Set the object mapper used for deserializing metadata
+ *
+ * @param mapper What to set.
+ */
+ public void setObjectMapper(@Nonnull final ObjectMapper mapper) {
+ checkSetterPreconditions();
+ objectMapper = Constraint.isNotNull(mapper, "Object mapper cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+
+ if (objectMapper == null) {
+ throw new ComponentInitializationException("Object mapper cannot be null");
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override @Nullable
+ public Map<String,Map<String,Object>> apply(@Nullable final List<EntityStatement> chain) {
+ if (chain == null || chain.size() < 3) {
+ log.warn("Unexpected trust chain input: {}", chain == null ? null : "size = " + chain.size());
+ return null;
+ }
+ final Map<String,Map<String,Object>> configurationMetadata =
+ EntityStatementHelper.parseMetadata(objectMapper, chain.get(0));
+ final Map<String,Map<String,Object>> subordinateMetadata =
+ EntityStatementHelper.parseMetadata(objectMapper, chain.get(1));
+
+ if (configurationMetadata == null || configurationMetadata.isEmpty()) {
+ log.error("Entity configuration for {} doesn't contain metadata", chain.get(0).getEntityID().getValue());
+ return null;
+ }
+
+ final Map<String,Map<String,Object>> result = new HashMap<>();
+ for (final String entityType : configurationMetadata.keySet()) {
+ final Map<String, Object> configurationClaims = configurationMetadata.get(entityType);
+ final Map<String, Object> subordinateClaims = new HashMap<>(Optional.ofNullable(subordinateMetadata)
+ .map(metadata -> metadata.get(entityType))
+ .orElse(CollectionSupport.emptyMap()));
+
+ for (final String configurationClaim : configurationClaims.keySet()) {
+ if (!subordinateClaims.containsKey(configurationClaim)) {
+ log.trace("Including metadata claim {} from the entity configuration", configurationClaim);
+ subordinateClaims.put(configurationClaim, configurationClaims.get(configurationClaim));
+ } else {
+ log.trace("Keeping metadata claim {} from the subordinate configuration", configurationClaim);
+ }
+ }
+
+ result.put(entityType, subordinateClaims);
+ }
+
+ return result;
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultEntityConfigurationCredentialResolver.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultEntityConfigurationCredentialResolver.java
new file mode 100644
index 0000000..a5f0f24
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultEntityConfigurationCredentialResolver.java
@@ -0,0 +1,87 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.util.Objects;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.security.credential.Credential;
+import org.slf4j.Logger;
+
+import com.nimbusds.jose.jwk.JWKSet;
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import net.shibboleth.oidc.security.credential.impl.BasicJOSEObjectCredentialResolver;
+import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.resolver.CriteriaSet;
+import net.shibboleth.shared.resolver.ResolverException;
+
+/**
+ * Resolves credentials from the jwks-claim located in the signed JWT (entity configuration) payload. The JWT is fetched
+ * via {@link SubjectEntityStatementCriterion}. If the JWT is not self-signed (i.e. it's a subordinate statement), a
+ * {@link ResolverException} is thrown.
+ */
+public class DefaultEntityConfigurationCredentialResolver extends BasicJOSEObjectCredentialResolver {
+
+ /** Logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(DefaultEntityConfigurationCredentialResolver.class);
+
+ /** {@inheritDoc} */
+ @Override
+ protected Iterable<Credential> resolveFromSource(@Nullable final CriteriaSet criteriaSet) throws ResolverException {
+ if (criteriaSet == null) {
+ throw new ResolverException("No criteria set supplied");
+ }
+
+ return parseJwkSet(criteriaSet).getKeys().stream()
+ .filter(Objects::nonNull)
+ .map(jwk -> buildJWKCredential(jwk, null))
+ .filter(Objects::nonNull)
+ .map(Credential.class::cast)
+ .toList();
+ }
+
+ /**
+ * Parses the JWKSet from the given criteria set.
+ *
+ * @param criteriaSet criteria set containing source JWT for the JWKSet
+ * @return the JWKSet parsed from the JWT payload
+ * @throws ResolverException if the JWKSet could not be parsed or found
+ */
+ @Nonnull protected JWKSet parseJwkSet(@Nonnull final CriteriaSet criteriaSet) throws ResolverException {
+ final SubjectEntityStatementCriterion subjectCriterion = criteriaSet.get(SubjectEntityStatementCriterion.class);
+ if (subjectCriterion == null) {
+ log.debug("No mandatory SubjectEntityStatementCriterion criteria supplied, resolver could not process");
+ throw new ResolverException(
+ "Credential criteria set did not contain an instance of SubjectEntityStatementCriterion");
+ }
+ final JWKSet jwks;
+ final EntityStatement subjectStatement = subjectCriterion.getValue();
+ if (subjectStatement.getEntityID().getValue().equals(
+ subjectStatement.getClaimsSet().getIssuer().getValue())) {
+ jwks = subjectStatement.getClaimsSet().getJWKSet();;
+ } else {
+ throw new ResolverException(
+ "Unexpected contents in the SubjectEntityStatementCriterion: subject does not match issuer");
+ }
+
+ if (jwks == null || jwks.isEmpty()) {
+ throw new ResolverException("Could not parse mandatory jwks");
+ }
+ return jwks;
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultEntityConfigurationEndpointExtractionStrategy.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultEntityConfigurationEndpointExtractionStrategy.java
new file mode 100644
index 0000000..0ecb3b6
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultEntityConfigurationEndpointExtractionStrategy.java
@@ -0,0 +1,82 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+
+import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.annotation.constraint.ThreadSafeAfterInit;
+import net.shibboleth.shared.component.AbstractIdentifiableInitializableComponent;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.resolver.CriteriaSet;
+
+/**
+ * Default strategy for extracting entity configuration endpoint URI from the given {@link CriteriaSet}.
+ */
+ at ThreadSafeAfterInit
+public class DefaultEntityConfigurationEndpointExtractionStrategy extends AbstractIdentifiableInitializableComponent
+ implements Function<CriteriaSet, URI> {
+
+ /** Class logger. */
+ @Nonnull private Logger log = LoggerFactory.getLogger(DefaultEntityConfigurationEndpointExtractionStrategy.class);
+
+ /** Strategy for fetching entity ID from the criteria set. */
+ @NonnullAfterInit private Function<CriteriaSet, String> criteriaToEntityIdStrategy;
+
+ /**
+ * Set the strategy for fetching entity ID from the criteria set.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setCriteriaToEntityIdStrategy(@Nonnull final Function<CriteriaSet, String> strategy) {
+ checkSetterPreconditions();
+ criteriaToEntityIdStrategy = Constraint.isNotNull(strategy, "Criteria to entity ID strategy cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+ if (criteriaToEntityIdStrategy == null) {
+ throw new ComponentInitializationException("Criteria to entity ID strategy cannot be null");
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override @Nullable
+ public URI apply(@Nullable final CriteriaSet criteria) {
+ checkComponentActive();
+ final String entityId = criteriaToEntityIdStrategy.apply(criteria);
+ if (entityId == null) {
+ return null;
+ }
+ try {
+ return new URI(entityId + (entityId.endsWith("/") ? "" : "/") + ".well-known/openid-federation");
+ } catch (final URISyntaxException e) {
+ log.error("Could not build URI for entity configuration endpoint", e);
+ }
+ return null;
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultEntityConfigurationMetadataSkeletonLookupStrategy.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultEntityConfigurationMetadataSkeletonLookupStrategy.java
new file mode 100644
index 0000000..91d0dc1
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultEntityConfigurationMetadataSkeletonLookupStrategy.java
@@ -0,0 +1,84 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.util.Map;
+import java.util.Optional;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+
+import net.shibboleth.oidc.metadata.cache.MetadataCache;
+import net.shibboleth.oidc.metadata.cache.MetadataCacheException;
+import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.annotation.constraint.ThreadSafeAfterInit;
+import net.shibboleth.shared.collection.CollectionSupport;
+import net.shibboleth.shared.component.AbstractIdentifiableInitializableComponent;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.resolver.CriteriaSet;
+
+/**
+ * Default strategy for fetching skeleton for entity configuration metadata via criteria.
+ */
+ at ThreadSafeAfterInit
+public class DefaultEntityConfigurationMetadataSkeletonLookupStrategy extends AbstractIdentifiableInitializableComponent
+ implements Function<CriteriaSet, Map<String,Map<String,Object>>> {
+
+ /** Class logger. */
+ @Nonnull
+ private Logger log = LoggerFactory.getLogger(DefaultEntityConfigurationMetadataSkeletonLookupStrategy.class);
+
+ /** Metadata cache providing metadata skeleton. */
+ @NonnullAfterInit private MetadataCache<Map<String,Map<String,Object>>> metadataSkeletonCache;
+
+ /**
+ * Set the cache providing metadata skeleton.
+ *
+ * @param cache cache providing metadata skeleton
+ */
+ public void setMetadataSkeletonCache(@Nonnull final MetadataCache<Map<String,Map<String,Object>>> cache) {
+ checkSetterPreconditions();
+ metadataSkeletonCache = Constraint.isNotNull(cache, "Metadata skeleton cache cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+ if (metadataSkeletonCache == null) {
+ throw new ComponentInitializationException("Metadata skeleton cache cannot be null");
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override @Nullable
+ public Map<String,Map<String,Object>> apply(@Nullable final CriteriaSet criteria) {
+ checkComponentActive();
+ try {
+ return Optional.of(metadataSkeletonCache.get(criteria))
+ .filter(result -> result.size() == 1)
+ .map(result -> result.get(0))
+ .orElse(CollectionSupport.emptyMap());
+ } catch (final MetadataCacheException e) {
+ log.error("Could not fetch metadata skeleton via metadata cache", e);
+ }
+ return CollectionSupport.emptyMap();
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultEntityConfigurationResponseContainerExpirationTimeStrategy.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultEntityConfigurationResponseContainerExpirationTimeStrategy.java
new file mode 100644
index 0000000..b0058b5
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultEntityConfigurationResponseContainerExpirationTimeStrategy.java
@@ -0,0 +1,59 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.time.Instant;
+import java.util.Optional;
+import java.util.function.Function;
+
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.ThreadSafe;
+
+import com.nimbusds.openid.connect.sdk.federation.config.FederationEntityConfigurationSuccessResponse;
+
+import net.shibboleth.oidc.metadata.cache.ExpirationTimeContext;
+
+/**
+ * Default strategy for fetching expiration time for the entity configuration response container. The expiration instant
+ * is fetched from which is before: the success response message's JWT expiration time or the instant returned by
+ * {@link NimbusResponseContainer#getExpirationInstant()}.
+ */
+ at ThreadSafe
+public class DefaultEntityConfigurationResponseContainerExpirationTimeStrategy
+ implements Function<ExpirationTimeContext<NimbusResponseContainer>, Instant> {
+
+ /** {@inheritDoc} */
+ @Nullable public Instant apply(@Nullable final ExpirationTimeContext<NimbusResponseContainer> context) {
+ if (context == null) {
+ return null;
+ }
+ final Instant contextExpiration = context.getNow().plus(context.getMaxCacheDuration());
+ final NimbusResponseContainer container = context.getMetadata();
+ if (container == null || container.getExpirationInstant() == null) {
+ return contextExpiration;
+ }
+ final Instant containerExpiration = container.getExpirationInstant();
+ if (container.getResponse() instanceof FederationEntityConfigurationSuccessResponse successResponse) {
+ final Instant jwtExpiration = Optional.ofNullable(
+ successResponse.getEntityStatement().getClaimsSet().getExpirationTime())
+ .map(date -> date.toInstant())
+ .orElse(null);
+ return jwtExpiration == null ? containerExpiration :
+ jwtExpiration.isBefore(containerExpiration) ? jwtExpiration : containerExpiration;
+ }
+ return containerExpiration;
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultEntityConfigurationResponseFetchingStrategy.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultEntityConfigurationResponseFetchingStrategy.java
new file mode 100644
index 0000000..1862386
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultEntityConfigurationResponseFetchingStrategy.java
@@ -0,0 +1,59 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+
+import net.shibboleth.shared.annotation.constraint.ThreadSafeAfterInit;
+import net.shibboleth.shared.component.AbstractIdentifiableInitializableComponent;
+import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.resolver.CriteriaSet;
+
+/**
+ * Default strategy for fetching entity configuration response container via criteria.
+ */
+ at ThreadSafeAfterInit
+public class DefaultEntityConfigurationResponseFetchingStrategy extends AbstractIdentifiableInitializableComponent
+ implements Function<CriteriaSet, NimbusResponseContainer> {
+
+ /** Class logger. */
+ @Nonnull private Logger log = LoggerFactory.getLogger(DefaultEntityConfigurationResponseFetchingStrategy.class);
+
+ /** {@inheritDoc} */
+ @Override @Nullable
+ public NimbusResponseContainer apply(@Nullable final CriteriaSet criteria) {
+ checkComponentActive();
+ if (criteria == null) {
+ return null;
+ }
+ final NimbusResponseCriterion responseCriterion = criteria.get(NimbusResponseCriterion.class);
+ if (responseCriterion == null) {
+ log.debug("No response criterion given, returning null");
+ return null;
+ }
+ final ResponseContainerExpirationCriterion expirationCriterion =
+ criteria.get(ResponseContainerExpirationCriterion.class);
+ if (expirationCriterion == null) {
+ log.debug("No expiration criterion given, returning null");
+ return null;
+ }
+ return new NimbusResponseContainer(responseCriterion.getResponse(), expirationCriterion.getExpirationInstant());
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultEntityStatementExpirationTimeStrategy.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultEntityStatementExpirationTimeStrategy.java
new file mode 100644
index 0000000..7960cfd
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultEntityStatementExpirationTimeStrategy.java
@@ -0,0 +1,48 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.time.Instant;
+import java.util.function.Function;
+
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.ThreadSafe;
+
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import net.shibboleth.oidc.metadata.cache.ExpirationTimeContext;
+
+/**
+ * Default strategy for fetching expiration time for the entity statement.
+ */
+ at ThreadSafe
+public class DefaultEntityStatementExpirationTimeStrategy
+ implements Function<ExpirationTimeContext<EntityStatement>, Instant> {
+
+ /** {@inheritDoc} */
+ @Nullable public Instant apply(@Nullable final ExpirationTimeContext<EntityStatement> context) {
+ if (context == null) {
+ return null;
+ }
+ final Instant contextExpiration = context.getNow().plus(context.getMaxCacheDuration());
+ final EntityStatement statement = context.getMetadata();
+ if (statement == null) {
+ return contextExpiration;
+ }
+ final Instant metadataExpiration = statement.getClaimsSet().getExpirationTime().toInstant();
+ return metadataExpiration.isBefore(contextExpiration) ? metadataExpiration : contextExpiration;
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultEntityStatementFetchingStrategy.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultEntityStatementFetchingStrategy.java
new file mode 100644
index 0000000..acf0579
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultEntityStatementFetchingStrategy.java
@@ -0,0 +1,155 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.apache.hc.client5.http.classic.HttpClient;
+import org.apache.hc.client5.http.classic.methods.HttpGet;
+import org.apache.hc.client5.http.protocol.HttpClientContext;
+import org.apache.hc.core5.http.ClassicHttpRequest;
+import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.apache.hc.core5.http.HttpStatus;
+import org.apache.hc.core5.http.ParseException;
+import org.apache.hc.core5.http.io.entity.EntityUtils;
+import org.opensaml.security.httpclient.HttpClientSecurityParameters;
+import org.opensaml.security.httpclient.HttpClientSecuritySupport;
+import org.slf4j.Logger;
+
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.annotation.constraint.ThreadSafeAfterInit;
+import net.shibboleth.shared.component.AbstractIdentifiableInitializableComponent;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.primitive.StringSupport;
+import net.shibboleth.shared.resolver.CriteriaSet;
+
+/**
+ * Default entity statement fetching strategy via configurable {@link HttpClient} and strategy for looking up the
+ * endpoint URI.
+ */
+ at ThreadSafeAfterInit
+public class DefaultEntityStatementFetchingStrategy extends AbstractIdentifiableInitializableComponent
+ implements Function<CriteriaSet, EntityStatement> {
+
+ /** Class logger. */
+ @Nonnull private Logger log = LoggerFactory.getLogger(DefaultEntityStatementFetchingStrategy.class);
+
+ /** HTTP client to use. */
+ @NonnullAfterInit protected HttpClient httpClient;
+
+ /** HTTP client security parameters. */
+ @Nullable private HttpClientSecurityParameters httpClientSecurityParameters;
+
+ /** Strategy to lookup URI from the criteria set. */
+ @NonnullAfterInit private Function<CriteriaSet, URI> criteriaToEndpointStrategy;
+
+ /**
+ * Set the {@link HttpClient} to use.
+ *
+ * @param client HTTP client to use
+ */
+ public void setHttpClient(@Nonnull final HttpClient client) {
+ checkSetterPreconditions();
+ httpClient = Constraint.isNotNull(client, "HttpClient cannot be null");
+ }
+
+ /**
+ * Set the optional client security parameters.
+ *
+ * @param params the new client security parameters
+ */
+ public void setHttpClientSecurityParameters(@Nullable final HttpClientSecurityParameters params) {
+ checkSetterPreconditions();
+ httpClientSecurityParameters = params;
+ }
+
+ /**
+ * Set the strategy to lookup URI from the criteria set.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setCriteriaToEndpointStrategy(@Nonnull final Function<CriteriaSet, URI> strategy) {
+ checkSetterPreconditions();
+ criteriaToEndpointStrategy = Constraint.isNotNull(strategy, "Criteria to endpoint strategy cannot be null");
+ }
+
+ /**
+ * Build the {@link HttpClientContext} instance to be used by the HttpClient.
+ *
+ * @param request the HTTP client request
+ * @return the client context instance
+ */
+ @Nonnull
+ protected HttpClientContext buildHttpContext(@Nonnull final ClassicHttpRequest request) {
+ final HttpClientContext clientContext = HttpClientContext.create();
+ assert clientContext != null;
+ HttpClientSecuritySupport.marshalSecurityParameters(clientContext, httpClientSecurityParameters, false);
+ HttpClientSecuritySupport.addDefaultTLSTrustEngineCriteria(clientContext, request);
+ return clientContext;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+ if (httpClient == null) {
+ throw new ComponentInitializationException("Httpclient cannot be null");
+ }
+ if (criteriaToEndpointStrategy == null) {
+ throw new ComponentInitializationException("Criteria to endpoint strategy cannot be null");
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override @Nullable
+ public EntityStatement apply(@Nullable final CriteriaSet criteria) {
+ checkComponentActive();
+ final URI uri = criteriaToEndpointStrategy.apply(criteria);
+ if (uri == null || StringSupport.trimOrNull(uri.getScheme()) == null) {
+ log.error("No valid URI could be resolved for fetching entity statement: {}", uri);
+ return null;
+ }
+ log.debug("Using URI {} for fetching entity statement", uri);
+ final HttpGet httpRequest = new HttpGet(uri);
+ final HttpClientContext httpContext = buildHttpContext(httpRequest);
+ try (final ClassicHttpResponse response = httpClient.executeOpen(null, httpRequest, httpContext)) {
+ final String scheme = httpRequest.getUri().getScheme();
+ assert scheme != null;
+ HttpClientSecuritySupport.checkTLSCredentialEvaluated(httpContext, scheme);
+ if (response.getCode() == HttpStatus.SC_OK) {
+ return EntityStatementHelper.deserializeEntityStatement(EntityUtils.toString(response.getEntity()));
+ } else {
+ log.debug("Unable to fetch entity configuration from URI: {} (HTTP status {})", uri,
+ response.getCode());
+ return null;
+ }
+ } catch (final ParseException | URISyntaxException | IOException e) {
+ log.debug("Unable to fetch entity statement from URI: {}", uri, e);
+ }
+
+ return null;
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultEntityStatementSignatureValidationFilterStrategy.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultEntityStatementSignatureValidationFilterStrategy.java
new file mode 100644
index 0000000..a3a06e4
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultEntityStatementSignatureValidationFilterStrategy.java
@@ -0,0 +1,62 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.util.function.BiFunction;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.security.trust.TrustEngine;
+import org.slf4j.Logger;
+
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import net.shibboleth.oidc.metadata.filter.MetadataFilterContext;
+import net.shibboleth.shared.annotation.constraint.ThreadSafeAfterInit;
+import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.resolver.CriteriaSet;
+
+/**
+ * Default signature validating filter for entity statement. The signature validation is performed via configurable
+ * {@link TrustEngine}.
+ */
+ at ThreadSafeAfterInit
+public class DefaultEntityStatementSignatureValidationFilterStrategy
+ extends AbstractTrustEngineSignatureValidationComponent
+ implements BiFunction<EntityStatement, MetadataFilterContext, EntityStatement> {
+
+ /** Class logger. */
+ @Nonnull private Logger log =
+ LoggerFactory.getLogger(DefaultEntityStatementSignatureValidationFilterStrategy.class);
+
+ /** {@inheritDoc} */
+ @Override @Nullable
+ public EntityStatement apply(@Nullable final EntityStatement entityStatement,
+ @Nullable final MetadataFilterContext filterContext) {
+ checkComponentActive();
+ if (entityStatement == null) {
+ return null;
+ }
+
+ final String entityId = entityStatement.getEntityID().getValue();
+ log.trace("Starting signature validation of entity statement for {}", entityId);
+ final CriteriaSet criteria = new CriteriaSet(new SubjectEntityStatementCriterion(entityStatement));
+ if (validateStatement(entityStatement, criteria, entityId)) {
+ return entityStatement;
+ }
+ return null;
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultEntityStatementSubjectIdentifierExtractionStrategy.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultEntityStatementSubjectIdentifierExtractionStrategy.java
new file mode 100644
index 0000000..75e6fec
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultEntityStatementSubjectIdentifierExtractionStrategy.java
@@ -0,0 +1,40 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.util.function.Function;
+
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.ThreadSafe;
+
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+/**
+ * Default strategy to extract entity ID from an entity statement.
+ */
+ at ThreadSafe
+public class DefaultEntityStatementSubjectIdentifierExtractionStrategy
+ implements Function<EntityStatement, String> {
+
+ /** {@inheritDoc} */
+ @Override @Nullable
+ public String apply(@Nullable final EntityStatement entityStatement) {
+ if (entityStatement == null) {
+ return null;
+ }
+ return entityStatement.getEntityID().getValue();
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultIssuerEntityIDCriteriaToIdentifierStrategy.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultIssuerEntityIDCriteriaToIdentifierStrategy.java
new file mode 100644
index 0000000..51b131f
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultIssuerEntityIDCriteriaToIdentifierStrategy.java
@@ -0,0 +1,42 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.util.function.Function;
+
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.ThreadSafe;
+
+import net.shibboleth.shared.resolver.CriteriaSet;
+
+/**
+ * Strategy for extracting an issuer entity ID via {@link IssuerEntityIDCriterion} from a {@link CriteriaSet}.
+ */
+ at ThreadSafe
+public class DefaultIssuerEntityIDCriteriaToIdentifierStrategy implements Function<CriteriaSet, String> {
+
+ /** {@inheritDoc} */
+ @Override @Nullable
+ public String apply(@Nullable final CriteriaSet criteria) {
+ if (criteria == null) {
+ return null;
+ }
+ final IssuerEntityIDCriterion criterion = criteria.get(IssuerEntityIDCriterion.class);
+ if (criterion != null) {
+ return criterion.getValue();
+ }
+ return null;
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultLocalTrustAnchorCredentialResolver.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultLocalTrustAnchorCredentialResolver.java
new file mode 100644
index 0000000..c663131
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultLocalTrustAnchorCredentialResolver.java
@@ -0,0 +1,107 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.security.credential.Credential;
+import org.slf4j.Logger;
+
+import com.nimbusds.jose.jwk.JWK;
+import com.nimbusds.jose.jwk.JWKSet;
+
+import net.shibboleth.oidc.metadata.cache.MetadataCache;
+import net.shibboleth.oidc.metadata.cache.MetadataCacheException;
+import net.shibboleth.oidc.security.credential.impl.BasicJOSEObjectCredentialResolver;
+import net.shibboleth.shared.annotation.ParameterName;
+import net.shibboleth.shared.collection.CollectionSupport;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.resolver.CriteriaSet;
+import net.shibboleth.shared.resolver.ResolverException;
+
+/**
+ * Default resolver for trusted trust anchor key resolution. A configurable {@link MetadataCache} is used for fetching
+ * the trusted/local public credentials for the entity referred via {@link SubjectEntityStatementCriterion}.
+ */
+public class DefaultLocalTrustAnchorCredentialResolver extends BasicJOSEObjectCredentialResolver {
+
+ /** Logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(DefaultLocalTrustAnchorCredentialResolver.class);
+
+ /** Cache containing local copies of trusted trust anchor keys. */
+ @Nonnull private MetadataCache<Map<String, LocalKeyContainer>> localTrustAnchorsCache;
+
+ /**
+ * Constructor.
+ *
+ * @param cache cache containing local copies of trusted trust anchor keys
+ */
+ public DefaultLocalTrustAnchorCredentialResolver(
+ @Nonnull @ParameterName(name="cache") final MetadataCache<Map<String, LocalKeyContainer>> cache) {
+ localTrustAnchorsCache = Constraint.isNotNull(cache, "Local Trust Anchors cache cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected Iterable<Credential> resolveFromSource(@Nullable final CriteriaSet criteriaSet) throws ResolverException {
+ if (criteriaSet == null) {
+ throw new ResolverException("No criteria supplied");
+ }
+ final SubjectEntityStatementCriterion subjectCriterion = criteriaSet.get(SubjectEntityStatementCriterion.class);
+ if (subjectCriterion == null) {
+ log.debug("No SubjectEntityStatementCriterion criteria supplied, resolver could not process");
+ throw new ResolverException(
+ "Credential criteria set did not contain an instance of SubjectEntityStatementCriterion");
+ }
+ final String entityId = subjectCriterion.getValue().getEntityID().getValue();
+ log.debug("Attempting to find trusted keys for {}", entityId);
+
+ final List<Map<String, LocalKeyContainer>> keyContainers;
+ try {
+ keyContainers = localTrustAnchorsCache.get(criteriaSet);
+ } catch (final MetadataCacheException e) {
+ throw new ResolverException("Could not resolve local trust anchor keys from the cache", e);
+ }
+ if (keyContainers.isEmpty() || !keyContainers.get(0).containsKey(entityId)) {
+ log.debug("No keys found for {}", entityId);
+ return CollectionSupport.emptyList();
+ }
+ final LocalKeyContainer keyContainer = keyContainers.get(0).get(entityId);
+ if (keyContainer == null || keyContainer.getJWKSet() == null) {
+ log.debug("No JWKSet found for {}", entityId);
+ return CollectionSupport.emptyList();
+ }
+ final JWKSet jwkSet = keyContainer.getJWKSet();
+ final List<Credential> credentials = new ArrayList<>();
+ assert jwkSet != null;
+ for (final JWK jwk : jwkSet.getKeys()) {
+ if (jwk != null) {
+ final Credential cred = buildJWKCredential(jwk, null);
+ if (cred != null) {
+ credentials.add(cred);
+ }
+ }
+ }
+ log.debug("Returning credentials {} for {}", credentials, entityId);
+ return credentials;
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultLocalTrustAnchorsValidator.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultLocalTrustAnchorsValidator.java
new file mode 100644
index 0000000..28d9d10
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultLocalTrustAnchorsValidator.java
@@ -0,0 +1,58 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.util.Map;
+import java.util.function.Predicate;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.ThreadSafe;
+
+import org.slf4j.Logger;
+
+import com.nimbusds.jose.jwk.JWKSet;
+
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+/**
+ * Default validator for local trust anchor keyset. It verifies that the keyset only contains public keys. Otherwise
+ * the keyset is considered as invalid.
+ */
+ at ThreadSafe
+public class DefaultLocalTrustAnchorsValidator implements Predicate<Map<String, LocalKeyContainer>> {
+
+ /** Class logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(DefaultLocalTrustAnchorsValidator.class);
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean test(@Nullable final Map<String, LocalKeyContainer> keyContainers) {
+ if (keyContainers == null) {
+ return false;
+ }
+ for (final String anchor : keyContainers.keySet()) {
+ final LocalKeyContainer container = keyContainers.get(anchor);
+ if (container != null) {
+ final JWKSet jwkSet = container.getJWKSet();
+ if (jwkSet != null && jwkSet.containsNonPublicKeys()) {
+ log.warn("Not accepting keyset for {} as it contains non-public keys", anchor);
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultPayloadJOSEObjectCredentialResolver.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultPayloadJOSEObjectCredentialResolver.java
new file mode 100644
index 0000000..99fc68b
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultPayloadJOSEObjectCredentialResolver.java
@@ -0,0 +1,71 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.text.ParseException;
+import java.util.Objects;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.security.credential.Credential;
+import org.slf4j.Logger;
+
+import com.nimbusds.jose.JOSEObject;
+import com.nimbusds.jose.jwk.JWKSet;
+import com.nimbusds.jwt.SignedJWT;
+
+import net.shibboleth.oidc.security.credential.impl.BasicJOSEObjectCredentialResolver;
+import net.shibboleth.oidc.security.jose.criterion.JOSEObjectCriterion;
+import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.resolver.CriteriaSet;
+import net.shibboleth.shared.resolver.ResolverException;
+
+/**
+ * Resolves credentials from the jwks-claim located in the signed JWT (entity statement) payload. The JWT is fetched
+ * via {@link JOSEObjectCriterion}.
+ */
+public class DefaultPayloadJOSEObjectCredentialResolver extends BasicJOSEObjectCredentialResolver {
+
+ /** Logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(DefaultPayloadJOSEObjectCredentialResolver.class);
+
+ /** {@inheritDoc} */
+ @Override
+ protected Iterable<Credential> resolveFromSource(@Nullable final CriteriaSet criteriaSet) throws ResolverException {
+ if (criteriaSet == null || !criteriaSet.contains(JOSEObjectCriterion.class)) {
+ throw new ResolverException("CriteriaSet does not contain JOSEObjectCriterion");
+ }
+
+ final JOSEObjectCriterion joseObjectCriteria = criteriaSet.get(JOSEObjectCriterion.class);
+ final JOSEObject joseObject = joseObjectCriteria.getJOSEObject();
+ if (joseObject == null) {
+ throw new ResolverException("JOSEObjectCriterion did not contain an instance of JOSEObject");
+ }
+ try {
+ final SignedJWT jwt = SignedJWT.parse(joseObject.serialize());
+ final JWKSet jwks = JWKSet.parse(jwt.getJWTClaimsSet().getJSONObjectClaim("jwks"));
+ return jwks.getKeys().stream()
+ .filter(Objects::nonNull)
+ .map(jwk -> buildJWKCredential(jwk, null))
+ .filter(Objects::nonNull)
+ .map(Credential.class::cast)
+ .toList();
+ } catch (final ParseException e) {
+ throw new ResolverException("Could not parse JWKSet from JOSEObject", e);
+ }
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultProvidedTrustChainValidationStrategy.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultProvidedTrustChainValidationStrategy.java
new file mode 100644
index 0000000..d6bbcd7
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultProvidedTrustChainValidationStrategy.java
@@ -0,0 +1,159 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.util.List;
+import java.util.Map;
+import java.util.function.BiFunction;
+import java.util.function.BiPredicate;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.opensaml.security.trust.TrustEngine;
+import org.slf4j.Logger;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.constraints.FederationPolicyConstraint;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.constraints.FederationPolicyConstraintHelper;
+import net.shibboleth.oidc.metadata.filter.MetadataFilterContext;
+import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.resolver.CriteriaSet;
+
+/**
+ * Default strategy for validating provided trust chain signatures via {@link TrustEngine} and configurable
+ * trust anchor signature validation filter.
+ */
+public class DefaultProvidedTrustChainValidationStrategy
+ extends AbstractTrustEngineSignatureValidationComponent
+ implements BiPredicate<ProfileRequestContext, List<EntityStatement>> {
+
+ /** Class logger. */
+ @Nonnull private Logger log = LoggerFactory.getLogger(DefaultProvidedTrustChainValidationStrategy.class);
+
+ /** Strategy for validating trust anchor's entity configuration signature. */
+ @NonnullAfterInit BiFunction<EntityStatement, MetadataFilterContext, EntityStatement>
+ trustAnchorSignatureValidationFilterStrategy;
+
+ /** Map of supported federation policy constraints. */
+ @NonnullAfterInit private Map<String, FederationPolicyConstraint> federationPolicyConstraints;
+
+ /** JSON object mapper used for decoding JSON into Map. */
+ @NonnullAfterInit private ObjectMapper objectMapper;
+
+ /**
+ * Set the strategy for validating trust anchor's entity configuration signature.
+ *
+ * @param strategy validation strategy
+ */
+ public void setTrustAnchorSignatureValidationFilterStrategy(
+ @Nonnull final BiFunction<EntityStatement, MetadataFilterContext, EntityStatement> strategy) {
+ checkSetterPreconditions();
+ trustAnchorSignatureValidationFilterStrategy = Constraint.isNotNull(strategy,
+ "TrustAnchorSignatureValidationFilterStrategy cannot be null");
+ }
+
+ /**
+ * Set the map of supported federation policy constraints.
+ *
+ * @param constraints map of supported federation policy constraints.
+ */
+ public void setfederationPolicyConstraints(@Nonnull final Map<String, FederationPolicyConstraint> constraints) {
+ checkSetterPreconditions();
+ federationPolicyConstraints = Constraint.isNotNull(constraints, "Map of policy constraints cannot be null");
+ }
+
+ /**
+ * Set the JSON {@link ObjectMapper} used for decoding JSON into Map.
+ *
+ * @param mapper object mapper
+ */
+ public void setObjectMapper(@Nonnull final ObjectMapper mapper) {
+ checkSetterPreconditions();
+
+ objectMapper = Constraint.isNotNull(mapper, "Object mapper cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+ if (trustAnchorSignatureValidationFilterStrategy == null) {
+ throw new ComponentInitializationException("TrustAnchorSignatureValidationFilterStrategy cannot be null");
+ }
+ if (federationPolicyConstraints == null) {
+ throw new ComponentInitializationException("Map of policy constraints cannot be null");
+ }
+ if (objectMapper == null) {
+ throw new ComponentInitializationException("Object mapper cannot be null");
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean test(@Nullable final ProfileRequestContext profileRequestContext,
+ @Nullable final List<EntityStatement> trustChain) {
+ checkComponentActive();
+ if (trustChain == null || trustChain.size() < 3 || trustChain.contains(null)) {
+ log.error("No satisfactory trust chain provided");
+ return false;
+ }
+
+ final EntityStatement entityConfiguration = trustChain.get(0);
+ assert entityConfiguration != null;
+ if (!validateStatement(entityConfiguration,
+ new CriteriaSet(new SubjectEntityStatementCriterion(entityConfiguration)),
+ entityConfiguration.getEntityID().getValue())) {
+ log.debug("Entity configuration signature validation failed");
+ return false;
+ }
+ for (int i = 1; i < trustChain.size() - 2; i++) {
+ final EntityStatement subordinateStatement = trustChain.get(i);
+ final EntityStatement issuerStatement = trustChain.get(i + 1);
+ assert subordinateStatement != null;
+ assert issuerStatement != null;
+ final CriteriaSet criteria = new CriteriaSet();
+ criteria.add(new IssuerEntityStatementCriterion(issuerStatement));
+ criteria.add(new SubjectEntityStatementCriterion(subordinateStatement));
+ if (!validateStatement(subordinateStatement, criteria, subordinateStatement.getEntityID().getValue())) {
+ log.debug("Subordinate statement {} signature validation failed", subordinateStatement.getEntityID());
+ return false;
+ }
+ }
+
+ for (int i = 1; i < trustChain.size() - 1; i++) {
+ if (!FederationPolicyConstraintHelper.verifyPolicyConstraints(
+ objectMapper, trustChain.get(i), trustChain.subList(0, i), federationPolicyConstraints)) {
+ log.debug("Subordinate statement {} policy constraints validation failed",
+ trustChain.get(i).getEntityID());
+ return false;
+ }
+ }
+
+ final EntityStatement trustAnchor = trustChain.get(trustChain.size() - 1);
+ if (!trustAnchor.equals(trustAnchorSignatureValidationFilterStrategy.apply(trustAnchor, null))) {
+ log.debug("Trust anchor {} validation failed", trustAnchor.getEntityID());
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultResolveEntityRequestCriteriaToIdentifierStrategy.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultResolveEntityRequestCriteriaToIdentifierStrategy.java
new file mode 100644
index 0000000..d2e77ae
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultResolveEntityRequestCriteriaToIdentifierStrategy.java
@@ -0,0 +1,42 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.util.Optional;
+import java.util.function.Function;
+
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.ThreadSafe;
+
+import net.shibboleth.shared.resolver.CriteriaSet;
+
+/**
+ * Strategy for extracting a resolve entity request as String via {@link ResolveEntityRequestCriterion} from
+ * {@link CriteriaSet}.
+ */
+ at ThreadSafe
+public class DefaultResolveEntityRequestCriteriaToIdentifierStrategy
+ implements Function<CriteriaSet, String> {
+
+ /** {@inheritDoc} */
+ @Override @Nullable
+ public String apply(@Nullable final CriteriaSet criteria) {
+ return Optional.ofNullable(criteria)
+ .map(set -> set.get(ResolveEntityRequestCriterion.class))
+ .map(criterion -> criterion.getRequest())
+ .map(request -> request.toString())
+ .orElse(null);
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultResolveEntityResponseContainerExpirationTimeStrategy.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultResolveEntityResponseContainerExpirationTimeStrategy.java
new file mode 100644
index 0000000..4730da4
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultResolveEntityResponseContainerExpirationTimeStrategy.java
@@ -0,0 +1,59 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.text.ParseException;
+import java.time.Instant;
+import java.util.function.Function;
+
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.ThreadSafe;
+
+import net.shibboleth.idp.plugin.oidc.op.oidfed.messaging.impl.ResolveEntityResponse;
+import net.shibboleth.oidc.metadata.cache.ExpirationTimeContext;
+
+/**
+ * Default strategy for fetching expiration time for the resolve entity response container. The expiration instant is
+ * fetched from which is before: the success response message's JWT expiration time or the instant returned by
+ * {@link ResolveEntityResponseContainer#getExpirationInstant()}.
+ */
+ at ThreadSafe
+public class DefaultResolveEntityResponseContainerExpirationTimeStrategy
+ implements Function<ExpirationTimeContext<ResolveEntityResponseContainer>, Instant> {
+
+ /** {@inheritDoc} */
+ @Nullable public Instant apply(@Nullable final ExpirationTimeContext<ResolveEntityResponseContainer> context) {
+ if (context == null) {
+ return null;
+ }
+ final Instant contextExpiration = context.getNow().plus(context.getMaxCacheDuration());
+ final ResolveEntityResponseContainer container = context.getMetadata();
+ if (container == null || container.getExpirationInstant() == null) {
+ return contextExpiration;
+ }
+ final Instant containerExpiration = container.getExpirationInstant();
+ if (container.getResponse() instanceof ResolveEntityResponse successResponse) {
+ try {
+ final Instant jwtExpiration =
+ successResponse.getJWT().getJWTClaimsSet().getExpirationTime().toInstant();
+ return jwtExpiration.isBefore(containerExpiration) ? jwtExpiration : containerExpiration;
+ } catch (final ParseException e) {
+ // ignore, use container expiration
+ }
+ }
+ return containerExpiration;
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultResolveEntityResponseFetchingStrategy.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultResolveEntityResponseFetchingStrategy.java
new file mode 100644
index 0000000..70ba1cc
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultResolveEntityResponseFetchingStrategy.java
@@ -0,0 +1,65 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+
+import net.shibboleth.shared.annotation.constraint.ThreadSafeAfterInit;
+import net.shibboleth.shared.component.AbstractIdentifiableInitializableComponent;
+import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.resolver.CriteriaSet;
+
+/**
+ * Default strategy for fetching resolve entity response container via criteria.
+ */
+ at ThreadSafeAfterInit
+public class DefaultResolveEntityResponseFetchingStrategy extends AbstractIdentifiableInitializableComponent
+ implements Function<CriteriaSet, ResolveEntityResponseContainer> {
+
+ /** Class logger. */
+ @Nonnull private Logger log = LoggerFactory.getLogger(DefaultResolveEntityResponseFetchingStrategy.class);
+
+ /** {@inheritDoc} */
+ @Override @Nullable
+ public ResolveEntityResponseContainer apply(@Nullable final CriteriaSet criteria) {
+ checkComponentActive();
+ if (criteria == null) {
+ return null;
+ }
+ final ResolveEntityRequestCriterion requestCriterion = criteria.get(ResolveEntityRequestCriterion.class);
+ if (requestCriterion == null) {
+ log.debug("No request criterion given, returning null");
+ return null;
+ }
+ final NimbusResponseCriterion responseCriterion = criteria.get(NimbusResponseCriterion.class);
+ if (responseCriterion == null) {
+ log.debug("No response criterion given, returning null");
+ return null;
+ }
+ final ResponseContainerExpirationCriterion expirationCriterion =
+ criteria.get(ResponseContainerExpirationCriterion.class);
+ if (expirationCriterion == null) {
+ log.debug("No expiration criterion given, returning null");
+ return null;
+ }
+ return new ResolveEntityResponseContainer(responseCriterion.getResponse(), requestCriterion.getRequest(),
+ expirationCriterion.getExpirationInstant());
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultResolveEntityResponseIdentifierExtractionStrategy.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultResolveEntityResponseIdentifierExtractionStrategy.java
new file mode 100644
index 0000000..a5009e4
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultResolveEntityResponseIdentifierExtractionStrategy.java
@@ -0,0 +1,38 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.util.Optional;
+import java.util.function.Function;
+
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.ThreadSafe;
+
+/**
+ * Default strategy for extracting request identifier out of {@link ResolveEntityResponseContainer}.
+ */
+ at ThreadSafe
+public class DefaultResolveEntityResponseIdentifierExtractionStrategy
+ implements Function<ResolveEntityResponseContainer, String> {
+
+ /** {@inheritDoc} */
+ @Override @Nullable
+ public String apply(@Nullable final ResolveEntityResponseContainer responseContainer) {
+ return Optional.ofNullable(responseContainer)
+ .map(container -> container.getRequest())
+ .map(request -> request.toString())
+ .orElse(null);
+ }
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultSubjectEntityIDCriteriaToIdentifierStrategy.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultSubjectEntityIDCriteriaToIdentifierStrategy.java
new file mode 100644
index 0000000..cdc5247
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultSubjectEntityIDCriteriaToIdentifierStrategy.java
@@ -0,0 +1,42 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.util.function.Function;
+
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.ThreadSafe;
+
+import net.shibboleth.shared.resolver.CriteriaSet;
+
+/**
+ * Strategy for extracting the {@link SubjectEntityIDCriterion} contents from a {@link CriteriaSet}.
+ */
+ at ThreadSafe
+public class DefaultSubjectEntityIDCriteriaToIdentifierStrategy implements Function<CriteriaSet, String> {
+
+ /** {@inheritDoc} */
+ @Override @Nullable
+ public String apply(@Nullable final CriteriaSet criteria) {
+ if (criteria == null) {
+ return null;
+ }
+ final SubjectEntityIDCriterion criterion = criteria.get(SubjectEntityIDCriterion.class);
+ if (criterion != null) {
+ return criterion.getValue();
+ }
+ return null;
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultSubordinateStatementCredentialResolver.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultSubordinateStatementCredentialResolver.java
new file mode 100644
index 0000000..6231528
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultSubordinateStatementCredentialResolver.java
@@ -0,0 +1,103 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.util.Objects;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.security.credential.Credential;
+import org.slf4j.Logger;
+
+import com.nimbusds.jose.jwk.JWKSet;
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import net.shibboleth.oidc.security.credential.impl.BasicJOSEObjectCredentialResolver;
+import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.resolver.CriteriaSet;
+import net.shibboleth.shared.resolver.ResolverException;
+
+/**
+ * Resolves credentials from the jwks-claim located in the signed JWT (issuer of a subordinate statement) payload.
+ * First, a JWT is fetched via {@link SubjectEntityStatementCriterion}. Its issuer must match with the entity
+ * statement fetched via {@link IssuerEntityStatementCriterion}. The issuer must be a self-signed statement.
+ */
+public class DefaultSubordinateStatementCredentialResolver extends BasicJOSEObjectCredentialResolver {
+
+ /** Logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(DefaultSubordinateStatementCredentialResolver.class);
+
+ /** {@inheritDoc} */
+ @Override
+ protected Iterable<Credential> resolveFromSource(@Nullable final CriteriaSet criteriaSet) throws ResolverException {
+ if (criteriaSet == null) {
+ throw new ResolverException("No criteria set supplied");
+ }
+
+ return parseJwkSet(criteriaSet).getKeys().stream()
+ .filter(Objects::nonNull)
+ .map(jwk -> buildJWKCredential(jwk, null))
+ .filter(Objects::nonNull)
+ .map(Credential.class::cast)
+ .toList();
+ }
+
+ /**
+ * Parses the JWKSet from the given criteria set.
+ *
+ * @param criteriaSet criteria set containing source JWT for the JWKSet
+ * @return the JWKSet parsed from the JWT payload
+ * @throws ResolverException if the JWKSet could not be parsed or found
+ */
+ @Nonnull protected JWKSet parseJwkSet(@Nonnull final CriteriaSet criteriaSet) throws ResolverException {
+ final SubjectEntityStatementCriterion subjectCriterion = criteriaSet.get(SubjectEntityStatementCriterion.class);
+ if (subjectCriterion == null) {
+ log.debug("No mandatory SubjectEntityStatementCriterion criteria supplied, resolver could not process");
+ throw new ResolverException(
+ "Credential criteria set did not contain an instance of SubjectEntityStatementCriterion");
+ }
+ final JWKSet jwks;
+ final EntityStatement subjectStatement = subjectCriterion.getValue();
+ if (subjectStatement.getEntityID().getValue().equals(
+ subjectStatement.getClaimsSet().getIssuer().getValue())) {
+ throw new ResolverException(
+ "Unexpected contents in the SubjectEntityStatementCriterion: subject matches issuer");
+ } else {
+ final IssuerEntityStatementCriterion issuerCriterion =
+ criteriaSet.get(IssuerEntityStatementCriterion.class);
+ if (issuerCriterion == null) {
+ log.debug("No mandatory IssuerEntityStatementCriterion supplied, resolver could not process");
+ throw new ResolverException(
+ "Credential criteria set did not contain an instance of IssuerEntityStatementCriterion");
+ }
+ final EntityStatement issuerStatement = issuerCriterion.getValue();
+ if (!issuerStatement.getEntityID().getValue().equals(
+ subjectStatement.getClaimsSet().getIssuer().getValue())) {
+ throw new ResolverException("Credential criteria do not match for subject and issuer");
+ }
+ if (!issuerStatement.getEntityID().getValue().equals(
+ issuerStatement.getClaimsSet().getIssuer().getValue())) {
+ throw new ResolverException("Issuer entity statement is not self signed");
+ }
+ jwks = issuerStatement.getClaimsSet().getJWKSet();
+ }
+
+ if (jwks == null || jwks.isEmpty()) {
+ throw new ResolverException("Could not parse mandatory jwks");
+ }
+ return jwks;
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultSubordinateStatementCriteriaToIdentifierStrategy.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultSubordinateStatementCriteriaToIdentifierStrategy.java
new file mode 100644
index 0000000..6e589b2
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultSubordinateStatementCriteriaToIdentifierStrategy.java
@@ -0,0 +1,93 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.annotation.constraint.ThreadSafeAfterInit;
+import net.shibboleth.shared.collection.Pair;
+import net.shibboleth.shared.component.AbstractIdentifiableInitializableComponent;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.resolver.CriteriaSet;
+
+/**
+ * Default identifier strategy for subordinate statement. The criteria set is transformed into a {@link Pair} that
+ * consists of subject and issuer entity IDs.
+ */
+ at ThreadSafeAfterInit
+public class DefaultSubordinateStatementCriteriaToIdentifierStrategy
+ extends AbstractIdentifiableInitializableComponent implements Function<CriteriaSet, Pair<String, String>> {
+
+ /** Strategy to fetch subject entity ID from criteria set. */
+ @NonnullAfterInit private Function<CriteriaSet, String> criteriaToSubjectEntityIdStrategy;
+
+ /** Strategy to fetch issuer entity ID from criteria set. */
+ @NonnullAfterInit private Function<CriteriaSet, String> criteriaToIssuerEntityIdStrategy;
+
+ /**
+ * Set the strategy to fetch subject entity ID from criteria set.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setCriteriaToSubjectEntityIdStrategy(@Nonnull final Function<CriteriaSet, String> strategy) {
+ checkSetterPreconditions();
+ criteriaToSubjectEntityIdStrategy = Constraint.isNotNull(strategy,
+ "Criteria to subject entity ID strategy cannot be null");
+ }
+
+ /**
+ * Set the strategy to fetch issuer entity ID from criteria set.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setCriteriaToIssuerEntityIdStrategy(@Nonnull final Function<CriteriaSet, String> strategy) {
+ checkSetterPreconditions();
+ criteriaToIssuerEntityIdStrategy = Constraint.isNotNull(strategy,
+ "Criteria to issuer entity ID strategy cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+ if (criteriaToSubjectEntityIdStrategy == null) {
+ throw new ComponentInitializationException("Criteria to subject entity ID strategy cannot be null");
+ }
+ if (criteriaToIssuerEntityIdStrategy == null) {
+ throw new ComponentInitializationException("Criteria to issuer entity ID strategy cannot be null");
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override @Nullable
+ public Pair<String, String> apply(@Nullable final CriteriaSet criteria) {
+ checkComponentActive();
+ final String subjectEntityId = criteriaToSubjectEntityIdStrategy.apply(criteria);
+ if (subjectEntityId == null) {
+ return null;
+ }
+ final String issuerEntityId = criteriaToIssuerEntityIdStrategy.apply(criteria);
+ if (issuerEntityId == null) {
+ return null;
+ }
+ return new Pair<>(issuerEntityId, subjectEntityId);
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultSubordinateStatementEndpointExtractionStrategy.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultSubordinateStatementEndpointExtractionStrategy.java
new file mode 100644
index 0000000..b4e19e1
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultSubordinateStatementEndpointExtractionStrategy.java
@@ -0,0 +1,149 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.List;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+import com.nimbusds.openid.connect.sdk.federation.entities.FederationEntityMetadata;
+
+import net.shibboleth.oidc.metadata.cache.MetadataCache;
+import net.shibboleth.oidc.metadata.cache.MetadataCacheException;
+import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.annotation.constraint.ThreadSafeAfterInit;
+import net.shibboleth.shared.component.AbstractIdentifiableInitializableComponent;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.resolver.CriteriaSet;
+
+/**
+ * Default strategy for fetching endpoint URI used for fetching subordinate statement. The issuer's entity configuration
+ * is fetched from a configurable {@link MetadataCache}.
+ */
+ at ThreadSafeAfterInit
+public class DefaultSubordinateStatementEndpointExtractionStrategy extends AbstractIdentifiableInitializableComponent
+ implements Function<CriteriaSet, URI> {
+
+ /** Class logger. */
+ @Nonnull private final Logger log =
+ LoggerFactory.getLogger(DefaultSubordinateStatementEndpointExtractionStrategy.class);
+
+ /** Cache containing entity configurations. */
+ @NonnullAfterInit private MetadataCache<EntityStatement> entityConfigurationCache;
+
+ /** Strategy to fetch subject entity ID from criteria set. */
+ @NonnullAfterInit private Function<CriteriaSet, String> criteriaToSubjectEntityIdStrategy;
+
+ /** Strategy to fetch issuer entity ID from criteria set. */
+ @NonnullAfterInit private Function<CriteriaSet, String> criteriaToIssuerEntityIdStrategy;
+
+ /**
+ * Set the strategy to fetch subject entity ID from criteria set.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setCriteriaToSubjectEntityIdStrategy(@Nonnull final Function<CriteriaSet, String> strategy) {
+ checkSetterPreconditions();
+ criteriaToSubjectEntityIdStrategy = Constraint.isNotNull(strategy,
+ "Criteria to subject entity ID strategy cannot be null");
+ }
+
+ /**
+ * Set the strategy to fetch issuer entity ID from criteria set.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setCriteriaToIssuerEntityIdStrategy(@Nonnull final Function<CriteriaSet, String> strategy) {
+ checkSetterPreconditions();
+ criteriaToIssuerEntityIdStrategy = Constraint.isNotNull(strategy,
+ "Criteria to issuer entity ID strategy cannot be null");
+ }
+
+ /**
+ * Set the cache containing entity configurations.
+ *
+ * @param cache cache containing entity configurations
+ */
+ public void setEntityConfigurationCache(@Nonnull final MetadataCache<EntityStatement> cache) {
+ checkSetterPreconditions();
+ entityConfigurationCache = Constraint.isNotNull(cache, "Entity Configuration cache cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+ if (criteriaToSubjectEntityIdStrategy == null) {
+ throw new ComponentInitializationException("Criteria to subject entity ID strategy cannot be null");
+ }
+ if (criteriaToIssuerEntityIdStrategy == null) {
+ throw new ComponentInitializationException("Criteria to issuer entity ID strategy cannot be null");
+ }
+ if (entityConfigurationCache == null) {
+ throw new ComponentInitializationException("Entity Configuration cache cannot be null");
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override @Nullable
+ public URI apply(@Nullable final CriteriaSet criteria) {
+ checkComponentActive();
+ final String subjectEntityId = criteriaToSubjectEntityIdStrategy.apply(criteria);
+ if (subjectEntityId == null) {
+ return null;
+ }
+ final String issuerEntityId = criteriaToIssuerEntityIdStrategy.apply(criteria);
+ if (issuerEntityId == null) {
+ return null;
+ }
+ final List<EntityStatement> issuerStatements;
+ try {
+ issuerStatements =
+ entityConfigurationCache.get(new CriteriaSet(new SubjectEntityIDCriterion(issuerEntityId)));
+ } catch (final MetadataCacheException e) {
+ log.error("Could not resolve entity configuration for issuer {}", issuerEntityId, e);
+ return null;
+ }
+ if (issuerStatements.isEmpty()) {
+ log.error("Could not resolve entity configuration for issuer {}", issuerEntityId);
+ return null;
+ }
+ final FederationEntityMetadata issuerMetadata =
+ issuerStatements.get(0).getClaimsSet().getFederationEntityMetadata();
+ final URI federationFetchEndpoint =
+ issuerMetadata != null ? issuerMetadata.getFederationFetchEndpointURI() : null;
+ if (federationFetchEndpoint == null) {
+ log.warn("No federation fetch endpoint found from the entity configuration for {}", issuerEntityId);
+ return null;
+ }
+
+ try {
+ return new URI(federationFetchEndpoint + "?sub=" + subjectEntityId);
+ } catch (final URISyntaxException e) {
+ log.error("Could not build URI for fetching subordinate entity statement", e);
+ }
+ return null;
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultSubordinateStatementIdentifierExtractionStrategy.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultSubordinateStatementIdentifierExtractionStrategy.java
new file mode 100644
index 0000000..7f2dc61
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultSubordinateStatementIdentifierExtractionStrategy.java
@@ -0,0 +1,43 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.util.function.Function;
+
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.ThreadSafe;
+
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import net.shibboleth.shared.collection.Pair;
+
+/**
+ * Default strategy for transforming subordinate statement into a {@link Pair} consisting of issuer and subject entity
+ * IDs.
+ */
+ at ThreadSafe
+public class DefaultSubordinateStatementIdentifierExtractionStrategy
+ implements Function<EntityStatement, Pair<String, String>> {
+
+ /** {@inheritDoc} */
+ @Override @Nullable
+ public Pair<String, String> apply(@Nullable final EntityStatement entityStatement) {
+ if (entityStatement == null) {
+ return null;
+ }
+ return new Pair<>(entityStatement.getClaimsSet().getIssuerEntityID().getValue(),
+ entityStatement.getEntityID().getValue());
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultSubordinateStatementSignatureValidationFilterStrategy.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultSubordinateStatementSignatureValidationFilterStrategy.java
new file mode 100644
index 0000000..9e33ec8
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultSubordinateStatementSignatureValidationFilterStrategy.java
@@ -0,0 +1,116 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.util.List;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import net.shibboleth.oidc.metadata.cache.MetadataCache;
+import net.shibboleth.oidc.metadata.cache.MetadataCacheException;
+import net.shibboleth.oidc.metadata.filter.MetadataFilterContext;
+import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.annotation.constraint.ThreadSafeAfterInit;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.resolver.CriteriaSet;
+
+/**
+ * Default signature validating filter for subordinate statement. This implementation extends
+ * {@link DefaultEntityStatementSignatureValidationFilterStrategy} by fetching the issuer's entity configuration via
+ * configurable {@link MetadataCache} and passing it via {@link IssuerEntityStatementCriterion} in the criteria set.
+ */
+ at ThreadSafeAfterInit
+public class DefaultSubordinateStatementSignatureValidationFilterStrategy
+ extends DefaultEntityStatementSignatureValidationFilterStrategy {
+
+ /** Class logger. */
+ @Nonnull private Logger log =
+ LoggerFactory.getLogger(DefaultSubordinateStatementSignatureValidationFilterStrategy.class);
+
+ /** Cache used to fetch the issuer entity configuration from. */
+ @NonnullAfterInit private MetadataCache<EntityStatement> entityConfigurationCache;
+
+ /**
+ * Set the cache used to fetch the issuer entity configuration from.
+ *
+ * @param cache cache used to fetch the issuer entity configuration from
+ */
+ public void setEntityConfigurationCache(@Nonnull final MetadataCache<EntityStatement> cache) {
+ checkSetterPreconditions();
+ entityConfigurationCache = Constraint.isNotNull(cache, "Entity Configuration cache cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+ if (entityConfigurationCache == null) {
+ throw new ComponentInitializationException("Entity Configuration cache cannot be null");
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override @Nullable
+ public EntityStatement apply(@Nullable final EntityStatement entityStatement,
+ @Nullable final MetadataFilterContext filterContext) {
+ checkComponentActive();
+ if (entityStatement == null) {
+ return null;
+ }
+
+ final String entityId = entityStatement.getEntityID().getValue();
+ final String issuer = entityStatement.getClaimsSet().getIssuerEntityID().getValue();
+ assert issuer != null;
+ log.trace("Validating subordinate statement for {}, issued by {}", entityId, issuer);
+ final EntityStatement issuerStatement = fetchIssuerStatement(issuer);
+ if (issuerStatement == null) {
+ return null;
+ }
+ final CriteriaSet criteria = new CriteriaSet();
+ criteria.add(new IssuerEntityStatementCriterion(issuerStatement));
+ criteria.add(new SubjectEntityStatementCriterion(entityStatement));
+ if (validateStatement(entityStatement, criteria, entityId)) {
+ return entityStatement;
+ }
+ return null;
+ }
+
+ /**
+ * Fetch the issuer entity configuration from the metadata cache.
+ *
+ * @param issuer the issuer entity ID
+ * @return the issuer entity configuration, or null if could not be fetched
+ */
+ @Nullable protected EntityStatement fetchIssuerStatement(@Nonnull final String issuer) {
+ final CriteriaSet criteria = new CriteriaSet(new SubjectEntityIDCriterion(issuer));
+ try {
+ final List<EntityStatement> result = entityConfigurationCache.get(criteria);
+ if (!result.isEmpty()) {
+ return result.get(0);
+ }
+ } catch (final MetadataCacheException e) {
+ log.debug("Error while fetching issuer entity configuration for {}", issuer, e);
+ }
+ log.warn("Could not fetch entity configuration for {}", issuer);
+ return null;
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultTrustAnchorSignatureValidationFilterStrategy.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultTrustAnchorSignatureValidationFilterStrategy.java
new file mode 100644
index 0000000..b07d2c9
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultTrustAnchorSignatureValidationFilterStrategy.java
@@ -0,0 +1,100 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.BiFunction;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import net.shibboleth.oidc.metadata.filter.MetadataFilterContext;
+import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.annotation.constraint.ThreadSafeAfterInit;
+import net.shibboleth.shared.component.AbstractIdentifiableInitializableComponent;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+/**
+ * Default signature validating filter trust chains. The signature validation is performed by passing the trust anchor
+ * entity statement of each trust chain to the configurable validation filter strategy. All the chains whose anchor
+ * doesn't pass the validation are filtered out from the result.
+ */
+ at ThreadSafeAfterInit
+public class DefaultTrustAnchorSignatureValidationFilterStrategy extends AbstractIdentifiableInitializableComponent
+ implements BiFunction<List<List<EntityStatement>>, MetadataFilterContext, List<List<EntityStatement>>> {
+
+ /** Class logger. */
+ @Nonnull private Logger log =
+ LoggerFactory.getLogger(DefaultTrustAnchorSignatureValidationFilterStrategy.class);
+
+ /** Signature validation filter strategy for trust anchor entity statements. */
+ @NonnullAfterInit private BiFunction<EntityStatement, MetadataFilterContext, EntityStatement>
+ entityStatementSignatureValidationFilterStrategy;
+
+ /**
+ * Set the signature validation filter strategy for trust anchor entity statements.
+ *
+ * @param strategy signature validation filter strategy
+ */
+ public void setEntityStatementSignatureValidationFilterStrategy(@Nonnull final
+ BiFunction<EntityStatement, MetadataFilterContext, EntityStatement> strategy) {
+ checkSetterPreconditions();
+ entityStatementSignatureValidationFilterStrategy = Constraint.isNotNull(strategy,
+ "EntityStatementSignatureValidationFilterStrategy cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+ if (entityStatementSignatureValidationFilterStrategy == null) {
+ throw new ComponentInitializationException(
+ "EntityStatementSignatureValidationFilterStrategy cannot be null");
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override @Nullable
+ public List<List<EntityStatement>> apply(@Nullable final List<List<EntityStatement>> trustChains,
+ @Nullable final MetadataFilterContext filterContext) {
+ checkComponentActive();
+ if (trustChains == null) {
+ return null;
+ }
+
+ final List<List<EntityStatement>> result = new ArrayList<>();
+ for (final List<EntityStatement> trustChain : trustChains) {
+ final EntityStatement trustAnchorStatement = trustChain.get(trustChain.size() - 1);
+ final String entityId = trustAnchorStatement.getEntityID().getValue();
+ final EntityStatement filteredStatement =
+ entityStatementSignatureValidationFilterStrategy.apply(trustAnchorStatement, filterContext);
+ if (filteredStatement != null) {
+ log.debug("Successfully validated entity statement for trust anchor {}", entityId);
+ result.add(trustChain);
+ } else {
+ log.debug("Signature validation failed for trust anchor {}", entityId);
+ }
+ }
+ return result;
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultTrustChainExpirationTimeStrategy.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultTrustChainExpirationTimeStrategy.java
new file mode 100644
index 0000000..ddcc640
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultTrustChainExpirationTimeStrategy.java
@@ -0,0 +1,60 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.time.Instant;
+import java.util.List;
+import java.util.function.Function;
+
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.ThreadSafe;
+
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import net.shibboleth.oidc.metadata.cache.ExpirationTimeContext;
+
+/**
+ * Default strategy for fetching expiration time for the list of trust chains. The shortest expiration of all the chains
+ * is taken and compared to the maximum cache duration defined in the {@link ExpirationTimeContext}.
+ */
+ at ThreadSafe
+public class DefaultTrustChainExpirationTimeStrategy
+ implements Function<ExpirationTimeContext<List<List<EntityStatement>>>, Instant> {
+
+ /** {@inheritDoc} */
+ @Nullable public Instant apply(@Nullable final ExpirationTimeContext<List<List<EntityStatement>>> context) {
+ if (context == null) {
+ return null;
+ }
+ final Instant contextExpiration = context.getNow().plus(context.getMaxCacheDuration());
+ final List<List<EntityStatement>> chains = context.getMetadata();
+ if (chains == null || chains.isEmpty()) {
+ return contextExpiration;
+ }
+ Instant metadataExpiration = null;
+ for (final List<EntityStatement> chain : chains) {
+ for (final EntityStatement statement : chain) {
+ final Instant statementExpiration = statement.getClaimsSet().getExpirationTime().toInstant();
+ metadataExpiration = metadataExpiration == null ? statementExpiration :
+ statementExpiration.isBefore(metadataExpiration) ? statementExpiration : metadataExpiration;
+ }
+ }
+ if (metadataExpiration == null) {
+ return contextExpiration;
+ }
+ return metadataExpiration.isBefore(contextExpiration) ? metadataExpiration : contextExpiration;
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultTrustChainFetchingStrategy.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultTrustChainFetchingStrategy.java
new file mode 100644
index 0000000..8ed6760
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultTrustChainFetchingStrategy.java
@@ -0,0 +1,382 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Stream;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityID;
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.constraints.FederationPolicyConstraint;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.constraints.FederationPolicyConstraintHelper;
+import net.shibboleth.oidc.metadata.cache.MetadataCache;
+import net.shibboleth.oidc.metadata.cache.MetadataCacheException;
+import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.annotation.constraint.NonnullElements;
+import net.shibboleth.shared.annotation.constraint.ThreadSafeAfterInit;
+import net.shibboleth.shared.collection.CollectionSupport;
+import net.shibboleth.shared.collection.Pair;
+import net.shibboleth.shared.component.AbstractIdentifiableInitializableComponent;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.resolver.CriteriaSet;
+
+/**
+ * Default strategy for fetching trust chains for an entity specified in the criteria set. Caches for entity
+ * configurations and subordinate statements are exploited for actual fetching of the entity statements. The
+ * entity configuration may also be delivered via {@link SubjectEntityStatementCriterion} in the criteria set.
+ */
+ at ThreadSafeAfterInit
+public class DefaultTrustChainFetchingStrategy extends AbstractIdentifiableInitializableComponent
+ implements Function<CriteriaSet, List<List<EntityStatement>>> {
+
+ /** Class logger. */
+ @Nonnull private Logger log = LoggerFactory.getLogger(DefaultTrustChainFetchingStrategy.class);
+
+ /** Strategy for fetching entity ID from the criteria set. */
+ @NonnullAfterInit private Function<CriteriaSet, String> criteriaToSubjectEntityIdStrategy;
+
+ /** Cache for entity configurations. */
+ @NonnullAfterInit private MetadataCache<EntityStatement> entityConfigurationCache;
+
+ /** Cache for subordinate entity statements. */
+ @NonnullAfterInit private MetadataCache<EntityStatement> subordinateStatementCache;
+
+ /** Cache containing local copies of trusted trust anchor keys. */
+ @NonnullAfterInit private MetadataCache<Map<String, LocalKeyContainer>> localTrustAnchorsCache;
+
+ /** Map of supported federation policy constraints. */
+ @NonnullAfterInit private Map<String, FederationPolicyConstraint> federationPolicyConstraints;
+
+ /** JSON object mapper used for decoding JSON into Map. */
+ @NonnullAfterInit private ObjectMapper objectMapper;
+
+ /**
+ * Set the strategy for fetching entity ID from the criteria set.
+ *
+ * @param strategy fetching strategy
+ */
+ public void setCriteriaToSubjectEntityIdStrategy(@Nonnull final Function<CriteriaSet, String> strategy) {
+ checkSetterPreconditions();
+ criteriaToSubjectEntityIdStrategy = Constraint.isNotNull(strategy,
+ "Criteria to subject entity ID strategy cannot be null");
+ }
+
+ /**
+ * Set the cache for entity configurations.
+ *
+ * @param cache entity configurations cache
+ */
+ public void setEntityConfigurationCache(@Nonnull final MetadataCache<EntityStatement> cache) {
+ checkSetterPreconditions();
+ entityConfigurationCache = Constraint.isNotNull(cache, "Entity Configuration cache cannot be null");
+ }
+
+ /**
+ * Set the cache for subordinate statement.
+ *
+ * @param cache subordinate statements cache.
+ */
+ public void setSubordinateStatementCache(@Nonnull final MetadataCache<EntityStatement> cache) {
+ checkSetterPreconditions();
+ subordinateStatementCache = Constraint.isNotNull(cache, "Subordinate statement cache cannot be null");
+ }
+
+ /**
+ * Set the cache containing local copies of trusted trust anchor keys.
+ *
+ * @param cache cache containing local copies of trusted trust anchor keys.
+ */
+ public void setLocalTrustAnchorsCache(@Nonnull final MetadataCache<Map<String, LocalKeyContainer>> cache) {
+ checkSetterPreconditions();
+ localTrustAnchorsCache = Constraint.isNotNull(cache, "Local Trust Anchor cache cannot be null");
+ }
+
+ /**
+ * Set the map of supported federation policy constraints.
+ *
+ * @param constraints map of supported federation policy constraints.
+ */
+ public void setfederationPolicyConstraints(@Nonnull final Map<String, FederationPolicyConstraint> constraints) {
+ checkSetterPreconditions();
+ federationPolicyConstraints = Constraint.isNotNull(constraints, "Map of policy constraints cannot be null");
+ }
+
+ /**
+ * Set the JSON {@link ObjectMapper} used for decoding JSON into Map.
+ *
+ * @param mapper object mapper
+ */
+ public void setObjectMapper(@Nonnull final ObjectMapper mapper) {
+ checkSetterPreconditions();
+
+ objectMapper = Constraint.isNotNull(mapper, "Object mapper cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+ if (criteriaToSubjectEntityIdStrategy == null) {
+ throw new ComponentInitializationException("Criteria to subject entity ID strategy cannot be null");
+ }
+ if (entityConfigurationCache == null) {
+ throw new ComponentInitializationException("Entity configuration cache cannot be null");
+ }
+ if (subordinateStatementCache == null) {
+ throw new ComponentInitializationException("Subordinate statement cache cannot be null");
+ }
+ if (localTrustAnchorsCache == null) {
+ throw new ComponentInitializationException("Local Trust Anchor cache cannot be null");
+ }
+ if (federationPolicyConstraints == null) {
+ throw new ComponentInitializationException("Map of policy constraints cannot be null");
+ }
+ if (objectMapper == null) {
+ throw new ComponentInitializationException("Object mapper cannot be null");
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override @Nullable
+ public List<List<EntityStatement>> apply(@Nullable final CriteriaSet criteria) {
+ checkComponentActive();
+ if (criteria == null) {
+ return null;
+ }
+ final PreSelectedTrustChainCriterion preSelectedCriterion = criteria.get(PreSelectedTrustChainCriterion.class);
+ final List<String> preSelectedChain =
+ preSelectedCriterion == null ? CollectionSupport.emptyList() : preSelectedCriterion.getValue();
+ final EntityStatement entityConfiguration;
+ final SubjectEntityStatementCriterion subjectStatementCriterion =
+ criteria.get(SubjectEntityStatementCriterion.class);
+ if (subjectStatementCriterion == null) {
+ try {
+ final List<EntityStatement> entityConfigurations = entityConfigurationCache.get(criteria);
+ if (entityConfigurations.isEmpty()) {
+ return null;
+ }
+ entityConfiguration = entityConfigurations.get(0);
+ } catch (final MetadataCacheException e) {
+ log.error("Could not fetch entity configuration for the trust chain", e);
+ return null;
+ }
+ } else {
+ entityConfiguration = subjectStatementCriterion.getValue();
+ }
+
+ if (entityConfiguration == null) {
+ return null;
+ }
+
+ final List<List<EntityStatement>> rawChains = populateChain(
+ CollectionSupport.listOf(CollectionSupport.listOf(entityConfiguration)), preSelectedChain);
+ final List<List<EntityStatement>> trustChains =
+ stripIntermediateConfigurations(entityConfiguration, rawChains);
+ return Stream.concat(trustChains.stream(), resolveLocallyTrustedTrustChains(trustChains).stream()).toList();
+ }
+
+ /**
+ * Strips the intermediate entity configurations out from the list of trust chains.
+ *
+ * @param leaf the leaf entity configuration
+ * @param chains the list of trust chains to be filtered
+ * @return the filtered list of trust chains, intermediate configurations filtered out
+ */
+ @Nonnull
+ private List<List<EntityStatement>> stripIntermediateConfigurations(@Nonnull final EntityStatement leaf,
+ @Nonnull @NonnullElements final List<List<EntityStatement>> chains) {
+ final List<List<EntityStatement>> result = new ArrayList<>();
+ for (final List<EntityStatement> chain : chains) {
+ result.add(chain.stream()
+ .filter(es -> (es.equals(leaf) || es.getClaimsSet().getAuthorityHints() == null
+ || es.getClaimsSet().getAuthorityHints().isEmpty()
+ || !es.getEntityID().equals(es.getClaimsSet().getIssuerEntityID())))
+ .toList());
+ }
+ return result;
+ }
+
+ /**
+ * Iterates the given trust chains and checks whether they contain locally trusted trust anchors as intermediate
+ * authorities. Such trust chains are returned in a way that locally trusted anchors are the trust anchors (i.e.
+ * the final items in the chain).
+ *
+ * @param chains trust chains to be iterated over
+ * @return list of trust chains containing locally trusted trust anchors
+ */
+ @Nonnull private List<List<EntityStatement>> resolveLocallyTrustedTrustChains(
+ @Nonnull @NonnullElements final List<List<EntityStatement>> chains) {
+ final List<List<EntityStatement>> result = new ArrayList<>();
+ for (final List<EntityStatement> chain : chains) {
+ for (int i = 0; i < chain.size() - 1; i++) {
+ final EntityStatement statement = chain.get(i);
+ assert statement != null;
+ final String entityId = chain.get(i).getEntityID().getValue();
+ assert entityId != null;
+ if (isLocallyTrusted(statement) && !isTrustAnchor(entityId, result)) {
+ try {
+ final CriteriaSet criteria = new CriteriaSet(new SubjectEntityIDCriterion(entityId));
+ final EntityStatement localAnchorConfiguration =
+ getFirstIfFound(entityConfigurationCache.get(criteria));
+ if (localAnchorConfiguration != null) {
+ final List<EntityStatement> localTrustChain =
+ new ArrayList<>(chain.subList(0, chain.indexOf(statement)));
+ localTrustChain.add(localAnchorConfiguration);
+ result.add(CollectionSupport.copyToList(localTrustChain));
+ log.debug("Included a trust chain based on a local trust anchor {}", entityId);
+ }
+ } catch (final MetadataCacheException e) {
+ log.error("Could not resolve entity configuration for {}", entityId);
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Checks whether the given entity is locally trusted via local trust anchors cache.
+ *
+ * @param statement the entity to be verified
+ * @return true if the entity is locally trusted, false otherwise
+ */
+ private boolean isLocallyTrusted(@Nonnull final EntityStatement statement) {
+ final CriteriaSet criteria = new CriteriaSet(new SubjectEntityStatementCriterion(statement));
+ final String entityId = statement.getEntityID().getValue();
+ assert entityId != null;
+ final List<Map<String, LocalKeyContainer>> keyContainers;
+ try {
+ keyContainers = localTrustAnchorsCache.get(criteria);
+ } catch (final MetadataCacheException e) {
+ log.debug("Could not resolve local trust anchor keys from the cache for {}", entityId, e);
+ return false;
+ }
+ if (keyContainers.isEmpty() || !keyContainers.get(0).containsKey(entityId)) {
+ log.trace("No locally trusted keys found for {}", entityId);
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Checks whether the given entity is already a trust anchor in any of the given trust chains.
+ *
+ * @param entityId the entity ID to be verified
+ * @param trustChains trust chains to be checked
+ * @return true if the entity is already a trust anchor, false otherwise
+ */
+ private boolean isTrustAnchor(@Nonnull final String entityId,
+ @Nonnull final List<List<EntityStatement>> trustChains) {
+ return trustChains.stream()
+ .filter(chain -> entityId.equals(chain.get(chain.size() - 1).getEntityID().getValue()))
+ .findAny()
+ .isPresent();
+ }
+
+ /**
+ * Recursively populates the given list of trust chains until the last entity statement in each chain doesn't
+ * contain any authority hints.
+ *
+ * @param entities the list of trust chains being populated.
+ * @param preSelectedChain the pre-selected trust chain (containing entity IDs as String).
+ * @return the list of trust chains being populated
+ */
+ @Nonnull @NonnullElements private List<List<EntityStatement>> populateChain(
+ @Nonnull @NonnullElements final List<List<EntityStatement>> entities,
+ @Nonnull final List<String> preSelectedChain) {
+ final List<List<EntityStatement>> result = new ArrayList<>();
+ boolean hints = false;
+ for (final List<EntityStatement> chain : entities) {
+ final EntityStatement entityStatement = chain.get(chain.size() - 1);
+ final List<EntityID> authorityHints = entityStatement.getClaimsSet().getAuthorityHints();
+ if (authorityHints == null || authorityHints.isEmpty()) {
+ result.add(chain);
+ } else {
+ final List<Pair<EntityStatement, EntityStatement>> authorities = authorityHints.stream()
+ .map(EntityID::getValue)
+ .filter(id -> preSelectedChain.isEmpty() || preSelectedChain.contains(id))
+ .map(id -> fetchAuthority(entityStatement, id))
+ .filter(pair -> pair != null && pair.getFirst() != null && pair.getSecond() != null)
+ .filter(pair -> FederationPolicyConstraintHelper.verifyPolicyConstraints(
+ objectMapper, pair.getSecond(), chain, federationPolicyConstraints))
+ .toList();
+ hints = !authorities.isEmpty();
+ authorities.forEach(authority -> {
+ final ArrayList<EntityStatement> newChain = new ArrayList<>(chain);
+ newChain.add(authority.getSecond());
+ newChain.add(authority.getFirst());
+ result.add(newChain);
+ });
+ }
+ }
+ if (hints) {
+ return populateChain(result, preSelectedChain);
+ }
+ return result;
+ }
+
+ /**
+ * Fetch authority's entity configuration and subordinate statement for the given entity statement and
+ * authority hint.
+ *
+ * @param entity the entity statement whose authority and subordinate statement are to be fetched
+ * @param authorityHint the authority entity ID
+ * @return pair consisting of authority's entity configuration and subordinate statement, or null if they could not
+ * be fetched.
+ */
+ @Nullable protected Pair<EntityStatement, EntityStatement> fetchAuthority(@Nonnull final EntityStatement entity,
+ @Nullable final String authorityHint) {
+ final String entityId = entity.getEntityID().getValue();
+ if (entityId == null || authorityHint == null) {
+ log.error("Entity ID ({}) or authority hint ({}) may not be null", entityId, authorityHint);
+ return null;
+ }
+ final CriteriaSet criteria = new CriteriaSet(new SubjectEntityIDCriterion(entityId),
+ new IssuerEntityIDCriterion(authorityHint));
+
+ try {
+ final EntityStatement authorityConfiguration = getFirstIfFound(
+ entityConfigurationCache.get(new CriteriaSet(new SubjectEntityIDCriterion(authorityHint))));
+ final EntityStatement metadata = getFirstIfFound(subordinateStatementCache.get(criteria));
+ return new Pair<>(authorityConfiguration, metadata);
+ } catch (final MetadataCacheException e) {
+ log.error("Could not resolve authority hint {} for {}", authorityHint, entityId);
+ return null;
+ }
+ }
+
+ /**
+ * Get the first entity statement from the given list if it's not empty.
+ *
+ * @param statements list of entity statements
+ * @return first entity statemenet, or null the list was empty.
+ */
+ @Nullable private EntityStatement getFirstIfFound(@Nonnull final List<EntityStatement> statements) {
+ return statements.size() > 0 ? statements.get(0) : null;
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultTrustChainSubjectIdentifierExtractionStrategy.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultTrustChainSubjectIdentifierExtractionStrategy.java
new file mode 100644
index 0000000..8367543
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultTrustChainSubjectIdentifierExtractionStrategy.java
@@ -0,0 +1,45 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.util.List;
+import java.util.function.Function;
+
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.ThreadSafe;
+
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+/**
+ * Default identifier strategy for the list of trust chains: the entity ID of the leaf entity is always used.
+ */
+ at ThreadSafe
+public class DefaultTrustChainSubjectIdentifierExtractionStrategy
+ implements Function<List<List<EntityStatement>>, String> {
+
+ /** {@inheritDoc} */
+ @Override @Nullable
+ public String apply(@Nullable final List<List<EntityStatement>> trustChains) {
+ if (trustChains == null || trustChains.isEmpty()) {
+ return null;
+ }
+ final List<EntityStatement> firstChain = trustChains.get(0);
+ if (firstChain == null || firstChain.isEmpty() || firstChain.get(0) == null) {
+ return null;
+ }
+ return firstChain.get(0).getEntityID().getValue();
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultTrustChainTrustMarksParsingStrategy.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultTrustChainTrustMarksParsingStrategy.java
new file mode 100644
index 0000000..5ee6654
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultTrustChainTrustMarksParsingStrategy.java
@@ -0,0 +1,109 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.text.ParseException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.ThreadSafe;
+
+import org.slf4j.Logger;
+
+import com.nimbusds.jwt.JWTClaimsSet;
+import com.nimbusds.jwt.SignedJWT;
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.primitive.StringSupport;
+
+/**
+ * Default strategy for parsing map of trust marks for the given trust chain. The keys in the map refer to the entity
+ * ID for which the trust mark has been issued to.
+ *
+ * TODO: iat / subject validation (switch into using claims validators)
+ */
+ at ThreadSafe
+public class DefaultTrustChainTrustMarksParsingStrategy
+ implements Function<List<EntityStatement>,Map<String,List<SignedJWT>>> {
+
+ /** Class logger. */
+ @Nonnull private Logger log = LoggerFactory.getLogger(DefaultTrustChainTrustMarksParsingStrategy.class);
+
+ /** {@inheritDoc} */
+ @Override @Nullable
+ public Map<String, List<SignedJWT>> apply(@Nullable final List<EntityStatement> trustChain) {
+ if (trustChain == null || trustChain.size() < 3) {
+ log.error("Unexpected length in the trust chain: {}", trustChain == null ? "null" : trustChain.size());
+ return null;
+ }
+
+ final Map<String, List<SignedJWT>> result = new HashMap<>();
+ for (final EntityStatement statement : trustChain) {
+ assert statement != null;
+ final SignedJWT statementJwt = statement.getSignedStatement();
+ log.trace("Inspecting entity statement {} with trust marks {}",
+ statementJwt.serialize(), statement.getClaimsSet().getTrustMarks());
+
+ final List<Object> rawTrustMarks = statement.getClaimsSet().getJSONArrayClaim("trust_marks");
+ if (rawTrustMarks != null && !rawTrustMarks.isEmpty()) {
+ final List<SignedJWT> trustMarks = rawTrustMarks
+ .stream()
+ .filter(Map.class::isInstance)
+ .map(Map.class::cast)
+ .map(map -> parseTrustMark(map.get("trust_mark"), map.get("trust_mark_id")))
+ .filter(Objects::nonNull)
+ .toList();
+ result.put(statement.getEntityID().getValue(), trustMarks);
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Verifies the trust mark id and issuer claims.
+ *
+ * @param trustMark trust mark to be verified, expected to be parseable from string
+ * @param id the id to be verified from the JWT claims set
+ * @return trust mark JWT if valid, null otherwise
+ */
+ @Nullable private SignedJWT parseTrustMark(@Nullable final Object trustMark, @Nullable final Object id) {
+ if (trustMark == null || !(trustMark instanceof String) || id == null || !(id instanceof String)) {
+ return null;
+ }
+ try {
+ final SignedJWT jwt = SignedJWT.parse((String) trustMark);
+ final JWTClaimsSet trustMarkClaims = jwt.getJWTClaimsSet();
+ if (StringSupport.trimOrNull(trustMarkClaims.getIssuer()) == null) {
+ log.error("Trust Mark {} is missing mandatory issuer", trustMarkClaims.getStringClaim("trust_mark_id"));
+ return null;
+ }
+ if (id.equals(trustMarkClaims.getStringClaim("trust_mark_id"))) {
+ return jwt;
+ }
+ log.error("The id {} is not matching with the trust_mark_id-claim {}", id,
+ trustMarkClaims.getStringClaim("trust_mark_id"));
+ } catch (final ParseException e) {
+ log.error("Could not parse id-claim from the trust mark", e);
+ }
+ return null;
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultTrustChainTrustedTrustMarkIssuersLookupStrategy.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultTrustChainTrustedTrustMarkIssuersLookupStrategy.java
new file mode 100644
index 0000000..64d15be
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultTrustChainTrustedTrustMarkIssuersLookupStrategy.java
@@ -0,0 +1,114 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.type.ArrayType;
+import com.fasterxml.jackson.databind.type.MapType;
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.collection.CollectionSupport;
+import net.shibboleth.shared.component.AbstractIdentifiableInitializableComponent;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+/**
+ * Default function for fetching trusted trust mark issuers from a trust chain: they are read from the trust anchor's
+ * entity configuration.
+ */
+public class DefaultTrustChainTrustedTrustMarkIssuersLookupStrategy extends AbstractIdentifiableInitializableComponent
+ implements Function<List<EntityStatement>, Map<String, List<String>>> {
+
+ /** Class logger. */
+ @Nonnull private final Logger log =
+ LoggerFactory.getLogger(DefaultTrustChainTrustedTrustMarkIssuersLookupStrategy.class);
+
+ /** JSON object mapper used for decoding JSON into Map. */
+ @NonnullAfterInit private ObjectMapper objectMapper;
+
+ /**
+ * Set the JSON {@link ObjectMapper} used for decoding JSON into Map.
+ *
+ * @param mapper object mapper
+ */
+ public void setObjectMapper(@Nonnull final ObjectMapper mapper) {
+ checkSetterPreconditions();
+
+ objectMapper = Constraint.isNotNull(mapper, "Object mapper cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+ if (objectMapper == null) {
+ throw new ComponentInitializationException("Object mapper cannot be null");
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Nullable @Override
+ public Map<String, List<String>> apply(@Nullable final List<EntityStatement> trustChain) {
+ checkComponentActive();
+ if (trustChain == null || trustChain.size() < 3) {
+ return null;
+ }
+ return parseTrustedIssuers(trustChain)
+ .entrySet().stream()
+ .filter(entry -> entry.getKey() != null && entry.getValue() != null)
+ .map(entry -> Map.entry(entry.getKey(), Arrays.stream(entry.getValue()).toList()))
+ .collect(Collectors.toUnmodifiableMap(Map.Entry::getKey, Map.Entry::getValue));
+ }
+
+ /**
+ * Parse the map of trusted issuers from the given trust chain, keyed with trust mark identifiers.
+ *
+ * @param trustChain trust chain to be parsed
+ * @return map of trusted issuers
+ */
+ @Nonnull protected Map<String, String[]> parseTrustedIssuers(@Nonnull final List<EntityStatement> trustChain) {
+ final Object issuersClaim =
+ trustChain.get(trustChain.size() - 1).getClaimsSet().getClaim("trust_mark_issuers");
+ if (issuersClaim != null) {
+ final ArrayType arrayType = objectMapper.getTypeFactory().constructArrayType(String.class);
+ final JavaType stringType = objectMapper.constructType(String.class);
+ final MapType mapType =
+ objectMapper.getTypeFactory().constructMapType(Map.class, stringType, arrayType);
+ try {
+ final Map<String, String[]> result = objectMapper.readValue(issuersClaim.toString(), mapType);
+ if (result != null) {
+ return result;
+ }
+ } catch (final JsonProcessingException e) {
+ log.warn("Could not parse trust mark issuers from the trust chain", e);
+ }
+ }
+ return CollectionSupport.emptyMap();
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultTrustChainTrustedTrustMarkOwnersLookupStrategy.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultTrustChainTrustedTrustMarkOwnersLookupStrategy.java
new file mode 100644
index 0000000..d1c7e03
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultTrustChainTrustedTrustMarkOwnersLookupStrategy.java
@@ -0,0 +1,103 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.type.MapType;
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.collection.CollectionSupport;
+import net.shibboleth.shared.component.AbstractIdentifiableInitializableComponent;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+/**
+ * Default function for fetching trusted trust mark owners from a trust chain: they are read from the trust anchor's
+ * entity configuration.
+ */
+public class DefaultTrustChainTrustedTrustMarkOwnersLookupStrategy extends AbstractIdentifiableInitializableComponent
+ implements Function<List<EntityStatement>, Map<String, Map<String, Object>>> {
+
+ /** Class logger. */
+ @Nonnull private final Logger log =
+ LoggerFactory.getLogger(DefaultTrustChainTrustedTrustMarkOwnersLookupStrategy.class);
+
+ /** JSON object mapper used for decoding JSON into Map. */
+ @NonnullAfterInit private ObjectMapper objectMapper;
+
+ /**
+ * Set the JSON {@link ObjectMapper} used for decoding JSON into Map.
+ *
+ * @param mapper object mapper
+ */
+ public void setObjectMapper(@Nonnull final ObjectMapper mapper) {
+ checkSetterPreconditions();
+
+ objectMapper = Constraint.isNotNull(mapper, "Object mapper cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+ if (objectMapper == null) {
+ throw new ComponentInitializationException("Object mapper cannot be null");
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Nullable @Override
+ public Map<String, Map<String, Object>> apply(@Nullable final List<EntityStatement> trustChain) {
+ checkComponentActive();
+ if (trustChain == null || trustChain.size() < 3) {
+ return null;
+ }
+ final Object ownersClaim =
+ trustChain.get(trustChain.size() - 1).getClaimsSet().getClaim("trust_mark_owners");
+ log.debug("Raw trust_mark_owners claim {}", ownersClaim);
+ if (ownersClaim != null) {
+ final JavaType objectType = objectMapper.constructType(Object.class);
+ final JavaType stringType = objectMapper.constructType(String.class);
+ final MapType objectMapType =
+ objectMapper.getTypeFactory().constructMapType(Map.class, stringType, objectType);
+ final MapType rootMapType =
+ objectMapper.getTypeFactory().constructMapType(Map.class, stringType, objectMapType);
+ try {
+ final Map<String, Map<String, Object>> result =
+ objectMapper.readValue(ownersClaim.toString(), rootMapType);
+ if (result != null) {
+ log.debug("Parsed trust_mark_owners map {}", result);
+ return result;
+ }
+ } catch (final JsonProcessingException e) {
+ log.warn("Could not parse trust mark issuers from the trust chain", e);
+ }
+ }
+ log.debug("Returning empty map");
+ return CollectionSupport.emptyMap();
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultTrustMarkOwnerCredentialResolver.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultTrustMarkOwnerCredentialResolver.java
new file mode 100644
index 0000000..14c9d9c
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultTrustMarkOwnerCredentialResolver.java
@@ -0,0 +1,97 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.security.credential.Credential;
+import org.slf4j.Logger;
+
+import com.nimbusds.jose.jwk.JWK;
+import com.nimbusds.jose.jwk.JWKSet;
+
+import net.shibboleth.oidc.security.credential.impl.BasicJOSEObjectCredentialResolver;
+import net.shibboleth.shared.collection.CollectionSupport;
+import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.resolver.CriteriaSet;
+import net.shibboleth.shared.resolver.ResolverException;
+
+/**
+ * Default resolver for trust anchor owner key resolution. A {@link TrustMarkOwnersCriterion} is used for fetching the
+ * credentials for the trust mark owner fetched via {@link SubjectEntityIDCriterion}.
+ */
+public class DefaultTrustMarkOwnerCredentialResolver extends BasicJOSEObjectCredentialResolver {
+
+ /** Logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(DefaultTrustMarkOwnerCredentialResolver.class);
+
+ /** {@inheritDoc} */
+ @Override
+ protected Iterable<Credential> resolveFromSource(@Nullable final CriteriaSet criteriaSet) throws ResolverException {
+ if (criteriaSet == null) {
+ throw new ResolverException("No criteria supplied");
+ }
+ final TrustMarkOwnersCriterion ownersCriterion = criteriaSet.get(TrustMarkOwnersCriterion.class);
+ if (ownersCriterion == null) {
+ log.debug("No TrustMarkOwnersCriterion criteria supplised, resolver could not process");
+ throw new ResolverException(
+ "Credential criteria set did not contain an instance of TrustMarkOwnersCriterion");
+ }
+ final SubjectEntityIDCriterion subjectCriterion = criteriaSet.get(SubjectEntityIDCriterion.class);
+ if (subjectCriterion == null) {
+ log.debug("No SubjectEntityIDCriterion criteria supplied, resolver could not process");
+ throw new ResolverException(
+ "Credential criteria set did not contain an instance of SubjectEntityIDCriterion");
+ }
+ final String entityId = subjectCriterion.getValue();
+ final Map<String, Map<String, Object>> owners = ownersCriterion.getValue();
+ if (owners.isEmpty() || owners.get(entityId) == null) {
+ log.debug("No trusted owners entry found for {}", entityId);
+ return CollectionSupport.emptyList();
+ }
+ final Map<String, Object> ownerConfiguration = owners.get(entityId);
+ if (ownerConfiguration.get("jwks") instanceof Map<?,?> map) {
+ final JWKSet jwkSet;
+ try {
+ jwkSet = JWKSet.parse(map.entrySet().stream()
+ .collect(Collectors.toMap(e -> e.getKey().toString(), e -> e.getValue())));
+ } catch (final ParseException e) {
+ log.debug("Could not parse JWKSet from the jwks claim", e);
+ return CollectionSupport.emptyList();
+ }
+ final List<Credential> credentials = new ArrayList<>();
+ for (final JWK jwk : jwkSet.getKeys()) {
+ if (jwk != null) {
+ final Credential cred = buildJWKCredential(jwk, null);
+ if (cred != null) {
+ credentials.add(cred);
+ }
+ }
+ }
+ log.debug("Returning credentials {} for {}", credentials, entityId);
+ return credentials;
+ }
+ log.debug("Could not parse jwks from {}", ownerConfiguration.get("jwks"));
+ return CollectionSupport.emptyList();
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/EntityStatementHelper.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/EntityStatementHelper.java
new file mode 100644
index 0000000..a80a584
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/EntityStatementHelper.java
@@ -0,0 +1,163 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.type.MapType;
+import com.nimbusds.oauth2.sdk.ParseException;
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import net.shibboleth.shared.collection.CollectionSupport;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+/**
+ * Static utility method related to entity statements.
+ */
+public class EntityStatementHelper {
+
+ /** Class logger. */
+ @Nonnull private final static Logger log = LoggerFactory.getLogger(EntityStatementHelper.class);
+
+ /**
+ * Parses the given claim as Map of Objects from the given entity statement.
+ *
+ * @param objectMapper object mapper used for parsing
+ * @param entityStatement entity statement from which to parse the claim from
+ * @param claim claim name to be parsed
+ * @return claim value as map or empty map if it didn't exist or could be parsed
+ */
+ @Nonnull public static Map<String, Object> parseClaimAsMap(@Nonnull final ObjectMapper objectMapper,
+ @Nonnull final EntityStatement entityStatement, @Nonnull final String claim ) {
+ final Object rawClaim = entityStatement.getClaimsSet().getClaim(claim);
+ log.trace("Raw {} claim value: {}", claim, rawClaim);
+ if (rawClaim != null) {
+ final JavaType objectType = objectMapper.constructType(Object.class);
+ final JavaType stringType = objectMapper.constructType(String.class);
+ final MapType objectMapType =
+ objectMapper.getTypeFactory().constructMapType(Map.class, stringType, objectType);
+ try {
+ final Map<String, Object> result =
+ objectMapper.readValue(rawClaim.toString(), objectMapType);
+ if (result != null) {
+ log.trace("Parsed {} map: {}", claim, result);
+ return result;
+ }
+ } catch (final JsonProcessingException e) {
+ log.warn("Could not parse " + claim + " from entity statement", e);
+ }
+ }
+ log.trace("Returning empty map");
+ return CollectionSupport.emptyMap();
+ }
+
+ /**
+ * Parses the given claim as Map of Map of Objects from the given entity statement.
+ *
+ * @param objectMapper object mapper used for parsing
+ * @param entityStatement entity statement from which to parse the claim from
+ * @param claim claim name to be parsed
+ * @return claim value as map or empty map if it didn't exist or could be parsed
+ */
+ @Nonnull public static Map<String, Map<String, Object>> parseClaimAsMapOfMaps(
+ @Nonnull final ObjectMapper objectMapper, @Nonnull final EntityStatement entityStatement,
+ @Nonnull final String claim ) {
+ final Object rawClaim = entityStatement.getClaimsSet().getClaim(claim);
+ log.trace("Raw {} claim value: {}", claim, rawClaim);
+ if (rawClaim != null) {
+ final JavaType objectType = objectMapper.constructType(Object.class);
+ final JavaType stringType = objectMapper.constructType(String.class);
+ final MapType objectMapType =
+ objectMapper.getTypeFactory().constructMapType(Map.class, stringType, objectType);
+ final MapType mapOfObjectMapType =
+ objectMapper.getTypeFactory().constructMapType(Map.class, stringType, objectMapType);
+ try {
+ final Map<String, Map<String, Object>> result =
+ objectMapper.readValue(rawClaim.toString(), mapOfObjectMapType);
+ if (result != null) {
+ log.trace("Parsed {} map: {}", claim, result);
+ return result;
+ }
+ } catch (final JsonProcessingException e) {
+ log.warn("Could not parse " + claim + " from entity statement", e);
+ }
+ }
+ log.trace("Returning empty map");
+ return CollectionSupport.emptyMap();
+ }
+
+ /**
+ * Parses the "metadata" -claim from the given entity statement.
+ *
+ * @param objectMapper object mapper used for parsing
+ * @param entityStatement entity statement from which to parse the claim from
+ * @return the map of metadata or empty map if they didn't exist or could be parsed
+ */
+ @Nonnull public static Map<String, Map<String, Object>> parseMetadata(@Nonnull final ObjectMapper objectMapper,
+ @Nonnull final EntityStatement entityStatement) {
+ return parseClaimAsMapOfMaps(objectMapper, entityStatement, "metadata");
+ }
+
+ /**
+ * Deseriealize the given string into an entity statement.
+ *
+ * @param serialized input string
+ * @return entity statement
+ */
+ @Nullable public static EntityStatement deserializeEntityStatement(@Nullable final String serialized) {
+ try {
+ if (serialized != null) {
+ return EntityStatement.parse(serialized);
+ }
+ } catch (final ParseException e) {
+ log.trace("Could not construct entity statement from {}", serialized, e);
+ }
+ log.warn("Could not deserialize entity statement {}", serialized);
+ return null;
+ }
+
+ /**
+ * Serialize the given trust chain into a comma-separated list of strings.
+ *
+ * @param trustChain input trust chain
+ * @return serialized trust chain
+ */
+ @Nullable
+ public static String getSerializedTrustChain(@Nullable final List<EntityStatement> trustChain) {
+ return trustChain == null ? null :
+ String.join(",", trustChain.stream().map(es -> es.getSignedStatement().serialize()).toList());
+ }
+
+ /**
+ * Serialize the given entity statement into a string.
+ *
+ * @param entityStatement input entity statement
+ * @return serialized entity statement
+ */
+ @Nullable
+ public static String getSerializedEntityStatement(@Nullable final EntityStatement entityStatement) {
+ return entityStatement == null ? null : entityStatement.getSignedStatement().serialize();
+ }
+
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/IssuerEntityIDCriterion.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/IssuerEntityIDCriterion.java
new file mode 100644
index 0000000..a47d7eb
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/IssuerEntityIDCriterion.java
@@ -0,0 +1,77 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.util.Objects;
+
+import javax.annotation.Nonnull;
+
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.resolver.Criterion;
+
+/**
+ * A {@link Criterion} representing an issuer entity ID in entity statement.
+ */
+public class IssuerEntityIDCriterion implements Criterion {
+
+ /** The entity ID value. */
+ @Nonnull final String value;
+
+ /**
+ * Constructor.
+ *
+ * @param entityId the entity ID value, must not be null
+ */
+ public IssuerEntityIDCriterion(@Nonnull final String entityId) {
+ value = Constraint.isNotEmpty(entityId, "Entity ID cannot be null");
+ }
+
+ /**
+ * Get the entity ID value.
+ *
+ * @return the entity ID value
+ */
+ public String getValue() {
+ return value;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public String toString() {
+ return "IssuerEntityIDCriterion [value=" + value + "]";
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public int hashCode() {
+ return Objects.hash(value);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final IssuerEntityIDCriterion other = (IssuerEntityIDCriterion) obj;
+ return value.equals(other.value);
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/IssuerEntityStatementCriterion.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/IssuerEntityStatementCriterion.java
new file mode 100644
index 0000000..1e3a88e
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/IssuerEntityStatementCriterion.java
@@ -0,0 +1,79 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.util.Objects;
+
+import javax.annotation.Nonnull;
+
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.resolver.Criterion;
+
+/**
+ * A {@link Criterion} representing an issuer entity statement.
+ */
+public class IssuerEntityStatementCriterion implements Criterion {
+
+ /** The entity statement value. */
+ @Nonnull final EntityStatement value;
+
+ /**
+ * Constructor.
+ *
+ * @param entityStatement the entity statement value, must not be null
+ */
+ public IssuerEntityStatementCriterion(@Nonnull final EntityStatement entityStatement) {
+ value = Constraint.isNotNull(entityStatement, "Entity statement cannot be null");
+ }
+
+ /**
+ * Get the entity statement value.
+ *
+ * @return the entity statement value
+ */
+ public EntityStatement getValue() {
+ return value;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public String toString() {
+ return "IssuerEntityStatementCriterion [value=" + value.getSignedStatement().serialize() + "]";
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public int hashCode() {
+ return Objects.hash(value);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final IssuerEntityStatementCriterion other = (IssuerEntityStatementCriterion) obj;
+ return value.getSignedStatement().serialize().equals(other.value.getSignedStatement().serialize());
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/JWKSetDeserializer.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/JWKSetDeserializer.java
new file mode 100644
index 0000000..c543b31
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/JWKSetDeserializer.java
@@ -0,0 +1,57 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.io.IOException;
+import java.text.ParseException;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+
+import com.fasterxml.jackson.core.JacksonException;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.nimbusds.jose.jwk.JWKSet;
+
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+/**
+ * Jackson deserializer for {@link LocalKeyContainer}.
+ */
+public class JWKSetDeserializer extends JsonDeserializer<LocalKeyContainer> {
+
+ /** Class logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(JWKSetDeserializer.class);
+
+ /** {@inheritDoc} */
+ @Override
+ public LocalKeyContainer deserialize(@Nullable final JsonParser jsonParser,
+ @Nullable final DeserializationContext deserializationContext)
+ throws IOException, JacksonException {
+ assert jsonParser != null;
+ final String raw = jsonParser.readValueAsTree().toString();
+ log.trace("Raw string to be parsed into JWTSet: {}", raw);
+ try {
+ final LocalKeyContainer keyContainer = new LocalKeyContainer();
+ keyContainer.setJWKSet(JWKSet.parse(raw));
+ return keyContainer;
+ } catch (final ParseException e) {
+ throw new IOException("Could not parse JWKSet", e);
+ }
+ }
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/LocalKeyContainer.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/LocalKeyContainer.java
new file mode 100644
index 0000000..a070c9e
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/LocalKeyContainer.java
@@ -0,0 +1,53 @@
+/*
+ * 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.oidfed.metadata;
+
+import javax.annotation.Nullable;
+
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.nimbusds.jose.jwk.JWKSet;
+
+/**
+ * Key set container class wrapping {@link JWKSet}.
+ */
+ at JsonDeserialize(using = JWKSetDeserializer.class)
+public class LocalKeyContainer {
+
+ /** The key set. */
+ @Nullable private JWKSet jwkSet;
+
+ /**
+ * Constructor.
+ */
+ public LocalKeyContainer() {
+ }
+
+ /**
+ * Get the key set.
+ *
+ * @return the key set
+ */
+ @Nullable JWKSet getJWKSet() {
+ return jwkSet;
+ }
+
+ /**
+ * Set the key set.
+ * @param set key set
+ */
+ public void setJWKSet(@Nullable final JWKSet set) {
+ jwkSet = set;
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/NimbusResponseContainer.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/NimbusResponseContainer.java
new file mode 100644
index 0000000..9928613
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/NimbusResponseContainer.java
@@ -0,0 +1,70 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.io.Serializable;
+import java.time.Instant;
+
+import javax.annotation.Nonnull;
+
+import com.nimbusds.oauth2.sdk.Response;
+
+import net.shibboleth.shared.logic.Constraint;
+
+/**
+ * A container class for metadata caches carrying Nimbus response message.
+ */
+public class NimbusResponseContainer implements Serializable {
+
+ /** Serial version UID. */
+ private static final long serialVersionUID = 656269369356865370L;
+
+ /** Response message. */
+ @Nonnull private final Response response;
+
+ /** Expiration instant for this container. */
+ @Nonnull private final Instant expiration;
+
+ /**
+ * Constructor.
+ *
+ * @param responseMessage response message
+ * @param expirationInstant expiration instant
+ */
+ public NimbusResponseContainer(@Nonnull final Response responseMessage,
+ @Nonnull final Instant expirationInstant) {
+ response = Constraint.isNotNull(responseMessage, "Response message cannot be null");
+ expiration = Constraint.isNotNull(expirationInstant, "Expiration instant cannot be null");
+ }
+
+ /**
+ * Get response message.
+ *
+ * @return response message
+ */
+ public Response getResponse() {
+ return response;
+ }
+
+ /**
+ * Get expiration instant.
+ *
+ * @return expiration instant
+ */
+ public Instant getExpirationInstant() {
+ return expiration;
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/NimbusResponseCriterion.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/NimbusResponseCriterion.java
new file mode 100644
index 0000000..bcc0dcd
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/NimbusResponseCriterion.java
@@ -0,0 +1,80 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.util.Objects;
+
+import javax.annotation.Nonnull;
+
+import com.nimbusds.oauth2.sdk.Response;
+
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.resolver.Criterion;
+
+/**
+ * A {@link Criterion} carrying Nimbus response message.
+ */
+public class NimbusResponseCriterion implements Criterion {
+
+ /** The response message. */
+ @Nonnull private final Response response;
+
+ /**
+ * Constructor.
+ *
+ * @param responseMessage response message, must not be null
+ */
+ public NimbusResponseCriterion(@Nonnull final Response responseMessage) {
+ response = Constraint.isNotNull(responseMessage, "Response cannot be null");
+ }
+
+ /**
+ * Get the response message.
+ *
+ * @return the response message
+ */
+ @Nonnull public Response getResponse() {
+ return response;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public String toString() {
+ return "NimbusResponseCriterion [response=" + response + "]";
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public int hashCode() {
+ return Objects.hash(response);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final NimbusResponseCriterion other = (NimbusResponseCriterion) obj;
+ return response.equals(other.response);
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/PreSelectedTrustChainCriterion.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/PreSelectedTrustChainCriterion.java
new file mode 100644
index 0000000..95cbb8d
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/PreSelectedTrustChainCriterion.java
@@ -0,0 +1,80 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.util.List;
+import java.util.Objects;
+
+import javax.annotation.Nonnull;
+
+import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.resolver.Criterion;
+
+/**
+ * A {@link Criterion} representing entity IDs for a pre-selected trust chain.
+ */
+public class PreSelectedTrustChainCriterion implements Criterion {
+
+ /** The entity ID values. */
+ @Nonnull @NotEmpty private final List<String> value;
+
+ /**
+ * Constructor.
+ *
+ * @param entityIds the entity ID values, must not be null
+ */
+ public PreSelectedTrustChainCriterion(@Nonnull final List<String> entityIds) {
+ value = Constraint.isNotNull(entityIds, "Entity ID cannot be null");
+ }
+
+ /**
+ * Get the entity ID values.
+ *
+ * @return the entity ID values
+ */
+ @Nonnull public List<String> getValue() {
+ return value;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public String toString() {
+ return "PreSelectedTrustChainCriterion [value=" + value + "]";
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public int hashCode() {
+ return Objects.hash(value);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final PreSelectedTrustChainCriterion other = (PreSelectedTrustChainCriterion) obj;
+ return value.containsAll(other.value) && other.value.containsAll(value);
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/ResolveEntityRequestCriterion.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/ResolveEntityRequestCriterion.java
new file mode 100644
index 0000000..d59a72f
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/ResolveEntityRequestCriterion.java
@@ -0,0 +1,80 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.util.Objects;
+
+import javax.annotation.Nonnull;
+
+import net.shibboleth.idp.plugin.oidc.op.oidfed.messaging.impl.ResolveEntityRequest;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.resolver.Criterion;
+
+/**
+ * A {@link Criterion} representing request message to a resolve entity API.
+ */
+public class ResolveEntityRequestCriterion implements Criterion {
+
+ /** The request message. */
+ @Nonnull private final ResolveEntityRequest request;
+
+ /**
+ * Constructor.
+ *
+ * @param requestMessage request message, must not be null
+ */
+ public ResolveEntityRequestCriterion(@Nonnull final ResolveEntityRequest requestMessage) {
+ request = Constraint.isNotNull(requestMessage, "Request cannot be null");
+ }
+
+ /**
+ * Get the request message.
+ *
+ * @return the request message
+ */
+ @Nonnull public ResolveEntityRequest getRequest() {
+ return request;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public String toString() {
+ return "ResolveEntityRequestCriterion [request=" + request + "]";
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public int hashCode() {
+ return Objects.hash(request);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final ResolveEntityRequestCriterion other = (ResolveEntityRequestCriterion) obj;
+ //TODO: proper equals-check
+ return request.equals(other.request);
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/ResolveEntityResponseContainer.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/ResolveEntityResponseContainer.java
new file mode 100644
index 0000000..103a436
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/ResolveEntityResponseContainer.java
@@ -0,0 +1,60 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.io.Serializable;
+import java.time.Instant;
+
+import javax.annotation.Nonnull;
+
+import com.nimbusds.oauth2.sdk.Response;
+
+import net.shibboleth.idp.plugin.oidc.op.oidfed.messaging.impl.ResolveEntityRequest;
+import net.shibboleth.shared.logic.Constraint;
+
+/**
+ * A container class for metadata caches carrying request and response message details related to Resolve Entity API.
+ */
+public class ResolveEntityResponseContainer extends NimbusResponseContainer implements Serializable {
+
+ /** Serial version UID. */
+ private static final long serialVersionUID = 756269369356865370L;
+
+ /** Request message. */
+ @Nonnull private final ResolveEntityRequest request;
+
+ /**
+ * Constructor.
+ *
+ * @param responseMessage response message
+ * @param requestMessage request message
+ * @param expirationInstant expiration instant
+ */
+ public ResolveEntityResponseContainer(@Nonnull final Response responseMessage,
+ @Nonnull final ResolveEntityRequest requestMessage, @Nonnull final Instant expirationInstant) {
+ super(responseMessage, expirationInstant);
+ request = Constraint.isNotNull(requestMessage, "Request message cannot be null");
+ }
+
+ /**
+ * Get request message.
+ *
+ * @return request message
+ */
+ public ResolveEntityRequest getRequest() {
+ return request;
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/ResponseContainerExpirationCriterion.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/ResponseContainerExpirationCriterion.java
new file mode 100644
index 0000000..a969761
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/ResponseContainerExpirationCriterion.java
@@ -0,0 +1,79 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.time.Instant;
+import java.util.Objects;
+
+import javax.annotation.Nonnull;
+
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.resolver.Criterion;
+
+/**
+ * A {@link Criterion} representing expiration instant for a response message container.
+ */
+public class ResponseContainerExpirationCriterion implements Criterion {
+
+ /** The expiration instant. */
+ @Nonnull private final Instant instant;
+
+ /**
+ * Constructor.
+ *
+ * @param expirationInstant expiration instant, must not be null
+ */
+ public ResponseContainerExpirationCriterion(@Nonnull final Instant expirationInstant) {
+ instant = Constraint.isNotNull(expirationInstant, "Expiration instant cannot be null");
+ }
+
+ /**
+ * Get the expiration instant.
+ *
+ * @return the expiration instant
+ */
+ @Nonnull public Instant getExpirationInstant() {
+ return instant;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public String toString() {
+ return "ResolveEntityContainerExpirationCriterion [instant=" + instant.toEpochMilli() + "]";
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public int hashCode() {
+ return Objects.hash(instant);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final ResponseContainerExpirationCriterion other = (ResponseContainerExpirationCriterion) obj;
+ return instant.equals(other.instant);
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/SubjectEntityIDCriterion.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/SubjectEntityIDCriterion.java
new file mode 100644
index 0000000..7352e0e
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/SubjectEntityIDCriterion.java
@@ -0,0 +1,79 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.util.Objects;
+
+import javax.annotation.Nonnull;
+
+import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.resolver.Criterion;
+
+/**
+ * A {@link Criterion} representing a subject entity ID in entity statement.
+ */
+public class SubjectEntityIDCriterion implements Criterion {
+
+ /** The entity ID value. */
+ @Nonnull @NotEmpty private final String value;
+
+ /**
+ * Constructor.
+ *
+ * @param entityId the entity ID value, must not be null
+ */
+ public SubjectEntityIDCriterion(@Nonnull final String entityId) {
+ value = Constraint.isNotEmpty(entityId, "Entity ID cannot be null");
+ }
+
+ /**
+ * Get the entity ID value.
+ *
+ * @return the entity ID value
+ */
+ public String getValue() {
+ return value;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public String toString() {
+ return "SubjectEntityIDCriterion [value=" + value + "]";
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public int hashCode() {
+ return Objects.hash(value);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final SubjectEntityIDCriterion other = (SubjectEntityIDCriterion) obj;
+ return value.equals(other.value);
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/SubjectEntityStatementCriterion.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/SubjectEntityStatementCriterion.java
new file mode 100644
index 0000000..32228c3
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/SubjectEntityStatementCriterion.java
@@ -0,0 +1,79 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.util.Objects;
+
+import javax.annotation.Nonnull;
+
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.resolver.Criterion;
+
+/**
+ * A {@link Criterion} representing a subject entity statement.
+ */
+public class SubjectEntityStatementCriterion implements Criterion {
+
+ /** The entity statement value. */
+ @Nonnull final EntityStatement value;
+
+ /**
+ * Constructor.
+ *
+ * @param entityStatement the entity statement value, must not be null
+ */
+ public SubjectEntityStatementCriterion(@Nonnull final EntityStatement entityStatement) {
+ value = Constraint.isNotNull(entityStatement, "Entity statement cannot be null");
+ }
+
+ /**
+ * Get the entity statement value.
+ *
+ * @return the entity statement value
+ */
+ @Nonnull public EntityStatement getValue() {
+ return value;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public String toString() {
+ return "SubjectEntityStatementCriterion [value=" + value.getSignedStatement().serialize() + "]";
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public int hashCode() {
+ return Objects.hash(value);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final SubjectEntityStatementCriterion other = (SubjectEntityStatementCriterion) obj;
+ return value.getSignedStatement().serialize().equals(other.value.getSignedStatement().serialize());
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/SubjectLocallyTrustedKeysCriterion.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/SubjectLocallyTrustedKeysCriterion.java
new file mode 100644
index 0000000..56d012e
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/SubjectLocallyTrustedKeysCriterion.java
@@ -0,0 +1,79 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.util.Objects;
+
+import javax.annotation.Nonnull;
+
+import com.nimbusds.jose.jwk.JWKSet;
+
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.resolver.Criterion;
+
+/**
+ * A {@link Criterion} representing locally trusted keys for a subject.
+ */
+public class SubjectLocallyTrustedKeysCriterion implements Criterion {
+
+ /** The locally trusted keys. */
+ @Nonnull final JWKSet value;
+
+ /**
+ * Constructor.
+ *
+ * @param jwkSet the locally trusted key set, must not be null
+ */
+ public SubjectLocallyTrustedKeysCriterion(@Nonnull final JWKSet jwkSet) {
+ value = Constraint.isNotNull(jwkSet, "JWKSet cannot be null");
+ }
+
+ /**
+ * Get the locally trusted keys.
+ *
+ * @return the locally rusted keys
+ */
+ @Nonnull public JWKSet getValue() {
+ return value;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public String toString() {
+ return "SubjectLocallyTrustedKeysCriterion [value=" + value.toString() + "]";
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public int hashCode() {
+ return Objects.hash(value);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final SubjectLocallyTrustedKeysCriterion other = (SubjectLocallyTrustedKeysCriterion) obj;
+ return value.toString().equals(other.value.toString());
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/TrustAnchorEntityIDsCriterion.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/TrustAnchorEntityIDsCriterion.java
new file mode 100644
index 0000000..97934e8
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/TrustAnchorEntityIDsCriterion.java
@@ -0,0 +1,80 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.util.List;
+import java.util.Objects;
+
+import javax.annotation.Nonnull;
+
+import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.resolver.Criterion;
+
+/**
+ * A {@link Criterion} representing trust anchor entity IDs in resolve entity request.
+ */
+public class TrustAnchorEntityIDsCriterion implements Criterion {
+
+ /** The entity ID values. */
+ @Nonnull final List<String> values;
+
+ /**
+ * Constructor.
+ *
+ * @param entityIds the entity ID values, must not be null nor empty
+ */
+ public TrustAnchorEntityIDsCriterion(@Nonnull @NotEmpty final List<String> entityIds) {
+ Constraint.isNotEmpty(entityIds, "Entity IDs cannot be null nor empty");
+ values = entityIds;
+ }
+
+ /**
+ * Get the entity ID values.
+ *
+ * @return the entity ID values
+ */
+ @Nonnull @NotEmpty public List<String> getValues() {
+ return values;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public String toString() {
+ return "TrustAnchorEntityIDsCriterion [values=" + values + "]";
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public int hashCode() {
+ return Objects.hash(values);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final TrustAnchorEntityIDsCriterion other = (TrustAnchorEntityIDsCriterion) obj;
+ return values.containsAll(other.values) && other.values.containsAll(values);
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/TrustMarkOwnersCriterion.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/TrustMarkOwnersCriterion.java
new file mode 100644
index 0000000..56a19bb
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/TrustMarkOwnersCriterion.java
@@ -0,0 +1,80 @@
+/*
+ * 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.oidfed.metadata;
+
+import java.util.Map;
+import java.util.Objects;
+
+import javax.annotation.Nonnull;
+
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.resolver.Criterion;
+
+/**
+ * A {@link Criterion} representing trust mark owners.
+ */
+public class TrustMarkOwnersCriterion implements Criterion {
+
+ /** The trust mark owners. */
+ @Nonnull private final Map<String, Map<String, Object>> owners;
+
+ /**
+ * Constructor.
+ *
+ * @param trustMarkOwners the truts mark owners, must not be null
+ */
+ public TrustMarkOwnersCriterion(@Nonnull final Map<String, Map<String, Object>> trustMarkOwners) {
+ owners = Constraint.isNotNull(trustMarkOwners, "Trust Mark owners cannot be null");
+ }
+
+ /**
+ * Get the trust mark owners value.
+ *
+ * @return the trust mark owners value
+ */
+ @Nonnull
+ public Map<String, Map<String, Object>> getValue() {
+ return owners;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public String toString() {
+ return "TrustMarkOwnersCriterion [owners=" + owners + "]";
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public int hashCode() {
+ return Objects.hash(owners);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final TrustMarkOwnersCriterion other = (TrustMarkOwnersCriterion) obj;
+ return owners.equals(other.owners);
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/constraints/FederationPolicyConstraint.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/constraints/FederationPolicyConstraint.java
new file mode 100644
index 0000000..b7ea206
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/constraints/FederationPolicyConstraint.java
@@ -0,0 +1,37 @@
+/*
+ * 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.oidfed.metadata.constraints;
+
+import java.util.List;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+/**
+ * Interface to be implemented by the federation policy constraints.
+ */
+public interface FederationPolicyConstraint {
+
+ /**
+ * Validate whether the given trust chain meets given federation policy constraint value,
+ *
+ * @param constraint the constraint value
+ * @param trustChain trust chain to be evaluated
+ * @return true if the trust chain is valid for this constraint, false otherwise.
+ */
+ public boolean validate(@Nullable final Object constraint, @Nonnull final List<EntityStatement> trustChain);
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/constraints/FederationPolicyConstraintHelper.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/constraints/FederationPolicyConstraintHelper.java
new file mode 100644
index 0000000..01c82bb
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/constraints/FederationPolicyConstraintHelper.java
@@ -0,0 +1,73 @@
+/*
+ * 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.oidfed.metadata.constraints;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.EntityStatementHelper;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+/**
+ * Static utility method related to federation policy constraints.
+ */
+public class FederationPolicyConstraintHelper {
+
+ /** Class logger. */
+ @Nonnull private final static Logger log = LoggerFactory.getLogger(FederationPolicyConstraintHelper.class);
+
+ /**
+ * Parses and verifies federation policy constraints set in the given subordinates statement against the given
+ * trust chain.
+ *
+ * @param objectMapper object mapper used for parsing the constraints claim
+ * @param subordinateStatement subordinate statement containing the constraints
+ * @param trustChain trust chain to be verified
+ * @param federationPolicyConstraints map of the federation policy constraint implementations
+ * @return true if trust chain meets the constraints. false otherwise
+ */
+ public static boolean verifyPolicyConstraints(@Nonnull final ObjectMapper objectMapper,
+ @Nullable final EntityStatement subordinateStatement, @Nonnull final List<EntityStatement> trustChain,
+ @Nonnull Map<String, FederationPolicyConstraint> federationPolicyConstraints) {
+ if (subordinateStatement == null) {
+ return true;
+ }
+ final Map<String, Object> constraints =
+ EntityStatementHelper.parseClaimAsMap(objectMapper, subordinateStatement, "constraints");
+ for (final String constraint : constraints.keySet()) {
+ final FederationPolicyConstraint validator = federationPolicyConstraints.get(constraint);
+ if (validator != null) {
+ log.trace("Validating federation policy constraint {} with {}", constraint, validator);
+ if (!validator.validate(constraints.get(constraint), trustChain)) {
+ log.warn("Subordinate statement issued by {} contained constraint {} that failed",
+ subordinateStatement.getClaimsSet().getIssuer(), constraint);
+ return false;
+ }
+ } else {
+ log.debug("Ignoring non-recognized federation policy constraint {}", constraint);
+ }
+ }
+ return true;
+ }
+
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/constraints/impl/AbstractFederationPolicyConstraint.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/constraints/impl/AbstractFederationPolicyConstraint.java
new file mode 100644
index 0000000..e0563b9
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/constraints/impl/AbstractFederationPolicyConstraint.java
@@ -0,0 +1,79 @@
+/*
+ * 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.oidfed.metadata.constraints.impl;
+
+import java.util.List;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.constraints.FederationPolicyConstraint;
+import net.shibboleth.shared.component.AbstractIdentifiableInitializableComponent;
+import net.shibboleth.shared.logic.ConstraintViolationException;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+/**
+ * Base implementation for the classes implementing {@link FederationPolicyConstraint}.
+ *
+ * @param <T> the data type for the constraint
+ */
+public abstract class AbstractFederationPolicyConstraint<T extends Object>
+ extends AbstractIdentifiableInitializableComponent implements FederationPolicyConstraint {
+
+ /** Class logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(AbstractFederationPolicyConstraint.class);
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean validate(@Nullable final Object constraint,
+ @Nonnull final List<EntityStatement> trustChain) {
+ checkComponentActive();
+ try {
+ log.trace("Attempting to parse raw constraint value: {}", constraint);
+ final T constraintData = parseConstraint(constraint);
+ if (constraintData != null) {
+ return doValidate(constraintData, trustChain);
+ } else {
+ return true;
+ }
+ } catch (final ConstraintViolationException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Parses the constraint data from the raw claim object value.
+ *
+ * @param constraint raw object value
+ * @return parsed constraint data
+ * @throws ConstraintViolationException if the parsing was not successful
+ */
+ @Nullable protected abstract T parseConstraint(@Nullable final Object constraint)
+ throws ConstraintViolationException;
+
+ /**
+ * Validate whether the given trust chain meets given federation policy constraint value,
+ *
+ * @param constraintData the non-null constraint value
+ * @param trustChain trust chain to be evaluated
+ * @return true if the trust chain is valid for this constraint, false otherwise.
+ */
+ protected abstract boolean doValidate(@Nonnull final T constraintData,
+ @Nonnull final List<EntityStatement> trustChain);
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/constraints/impl/DefaultAllowedEntityTypesConstraint.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/constraints/impl/DefaultAllowedEntityTypesConstraint.java
new file mode 100644
index 0000000..f18fe3e
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/constraints/impl/DefaultAllowedEntityTypesConstraint.java
@@ -0,0 +1,106 @@
+/*
+ * 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.oidfed.metadata.constraints.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.EntityStatementHelper;
+import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.logic.ConstraintViolationException;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+/**
+ * Default implementation for the 'allowed_entity_types' -constraint.
+ */
+public class DefaultAllowedEntityTypesConstraint extends AbstractFederationPolicyConstraint<List<String>> {
+
+ /** Class logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(DefaultAllowedEntityTypesConstraint.class);
+
+ /** JSON object mapper used for decoding JSON into Map. */
+ @NonnullAfterInit private ObjectMapper objectMapper;
+
+ /**
+ * Set the JSON {@link ObjectMapper} used for decoding JSON into Map.
+ *
+ * @param mapper object mapper
+ */
+ public void setObjectMapper(@Nonnull final ObjectMapper mapper) {
+ checkSetterPreconditions();
+
+ objectMapper = Constraint.isNotNull(mapper, "Object mapper cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+ if (objectMapper == null) {
+ throw new ComponentInitializationException("Object mapper cannot be null");
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override @Nullable
+ protected List<String> parseConstraint(@Nullable final Object constraint)
+ throws ConstraintViolationException {
+ if (constraint instanceof List<?> list) {
+ return list.stream().filter(String.class::isInstance).map(String::valueOf).toList();
+ } else if (constraint != null) {
+ throw new ConstraintViolationException("Unexpected value type for allowed_entity_types: " + constraint);
+ }
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected boolean doValidate(@Nonnull final List<String> constraintData,
+ @Nonnull final List<EntityStatement> trustChain) {
+ if (constraintData.contains("federation_entity")) {
+ log.warn("The value 'federation_entity' is not allowed for allowed_entity_types");
+ return false;
+ }
+ final List<String> allowedTypes = new ArrayList<>(constraintData);
+ allowedTypes.add("federation_entity");
+ log.trace("Allowed entity types: {}", allowedTypes);
+ for (final EntityStatement entityStatement : trustChain) {
+ assert entityStatement != null;
+ assert objectMapper != null;
+ final Map<String, Map<String,Object>> metadata =
+ EntityStatementHelper.parseMetadata(objectMapper, entityStatement);
+ for (final String entityType : metadata.keySet()) {
+ if (!allowedTypes.contains(entityType)) {
+ log.warn("The entity type {} is not allowed in entity statement {}", entityType,
+ entityStatement.getEntityID());
+ return false;
+ }
+ log.trace("The entity type {} is allowed for {}", entityType, entityStatement.getEntityID());
+ }
+ }
+ return true;
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/constraints/impl/DefaultMaxPathLengthConstraint.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/constraints/impl/DefaultMaxPathLengthConstraint.java
new file mode 100644
index 0000000..c3dca69
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/constraints/impl/DefaultMaxPathLengthConstraint.java
@@ -0,0 +1,66 @@
+/*
+ * 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.oidfed.metadata.constraints.impl;
+
+import java.util.List;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import net.shibboleth.shared.logic.ConstraintViolationException;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+/**
+ * Default implementation for the 'max_path_length' -constraint.
+ */
+public class DefaultMaxPathLengthConstraint extends AbstractFederationPolicyConstraint<Integer> {
+
+ /** Class logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(DefaultMaxPathLengthConstraint.class);
+
+ /** {@inheritDoc} */
+ @Override @Nullable
+ protected Integer parseConstraint(@Nullable final Object constraint)
+ throws ConstraintViolationException {
+ if (constraint instanceof Integer integer) {
+ return integer;
+ } else if (constraint != null) {
+ throw new ConstraintViolationException("Unexpected value type for max_path_length: " + constraint);
+ }
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected boolean doValidate(@Nonnull final Integer constraintData,
+ @Nonnull final List<EntityStatement> trustChain) {
+ final List<EntityStatement> intermediates = trustChain.stream()
+ .filter(es -> !es.getEntityID().getValue().equals(es.getClaimsSet().getIssuer().getValue()))
+ .toList();
+ final int length = intermediates.size();
+ log.trace("Maximum path length: {}, amount of intermediates is {}", constraintData, length);
+ if (constraintData < length) {
+ log.warn("Maximum path length is constricted to {}, amount of intermediates is {}",
+ constraintData, length);
+ return false;
+ }
+ return true;
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/constraints/impl/DefaultNamingConstraintsConstraint.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/constraints/impl/DefaultNamingConstraintsConstraint.java
new file mode 100644
index 0000000..c3ff2e2
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/constraints/impl/DefaultNamingConstraintsConstraint.java
@@ -0,0 +1,118 @@
+/*
+ * 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.oidfed.metadata.constraints.impl;
+
+import java.net.URI;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.bouncycastle.asn1.x509.GeneralName;
+import org.bouncycastle.asn1.x509.GeneralSubtree;
+import org.bouncycastle.asn1.x509.NameConstraintValidatorException;
+import org.bouncycastle.asn1.x509.PKIXNameConstraintValidator;
+import org.slf4j.Logger;
+
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import net.shibboleth.shared.collection.CollectionSupport;
+import net.shibboleth.shared.logic.ConstraintViolationException;
+import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.primitive.NonnullSupplier;
+
+/**
+ * Default implementation for the 'naming_constraints' -constraint.
+ */
+public class DefaultNamingConstraintsConstraint extends AbstractFederationPolicyConstraint<Map<String, List<String>>> {
+
+ /** Class logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(DefaultNamingConstraintsConstraint.class);
+
+ /** {@inheritDoc} */
+ @Override @Nullable
+ protected Map<String, List<String>> parseConstraint(@Nullable final Object constraint)
+ throws ConstraintViolationException {
+ if (constraint instanceof Map<?,?> map) {
+ return map.keySet().stream()
+ .filter(key -> "permitted".equals(key) || "excluded".equals(key))
+ .map(String::valueOf)
+ .collect(Collectors.toMap(key -> key, key -> parseListOfStrings(key, map.get(key))));
+ } else if (constraint != null) {
+ throw new ConstraintViolationException("Unexpected value type for naming_constraints: " + constraint);
+ }
+ return null;
+ }
+
+ /**
+ * Parses the raw object value into a list of strings.
+ *
+ * @param key the key (used solely in a potential exception)
+ * @param raw the value to be parsed
+ * @return the value as list of strings, or null if the input was null
+ * @throws ConstraintViolationException if a non-null value could not be parsed
+ */
+ @Nullable private List<String> parseListOfStrings(@Nullable final String key, @Nullable final Object raw)
+ throws ConstraintViolationException {
+ if (raw instanceof List<?> list) {
+ final List<String> result = list.stream().filter(Objects::nonNull).map(String::valueOf).toList();
+ return result;
+ } else if (raw != null) {
+ throw new ConstraintViolationException("The value for " + key + " is not a list: " + raw);
+ }
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected boolean doValidate(@Nonnull final Map<String, List<String>> constraintData,
+ @Nonnull final List<EntityStatement> trustChain) {
+ final PKIXNameConstraintValidator bcValidator = new PKIXNameConstraintValidator();
+
+ Optional.ofNullable(constraintData.get("excluded"))
+ .orElseGet(NonnullSupplier.of(CollectionSupport.emptyList()))
+ .forEach(item -> bcValidator.addExcludedSubtree(
+ new GeneralSubtree(new GeneralName(GeneralName.dNSName, item))));
+
+ Optional.ofNullable(constraintData.get("permitted"))
+ .orElseGet(NonnullSupplier.of(CollectionSupport.emptyList()))
+ .forEach(item -> bcValidator.intersectPermittedSubtree(
+ new GeneralSubtree(new GeneralName(GeneralName.dNSName, item))));
+
+ for (final EntityStatement entityStatement : trustChain) {
+ final String host = URI.create(entityStatement.getEntityID().getValue()).getHost();
+ try {
+ bcValidator.checkExcluded(new GeneralName(GeneralName.dNSName, host));
+ log.trace("Validation for 'excluded' was successful for {}", host);
+ } catch (final NameConstraintValidatorException e) {
+ log.warn("Constraint excludes entity name {}", host);
+ return false;
+ }
+ try {
+ bcValidator.checkPermitted(new GeneralName(GeneralName.dNSName, host));
+ log.trace("Validation for 'permitted' was successful for {}", host);
+ } catch (final NameConstraintValidatorException e) {
+ log.warn("Constraint does not permit entity name {}", host);
+ return false;
+ }
+ }
+ return true;
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/FederationMetadataPolicyDeserializer.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/FederationMetadataPolicyDeserializer.java
new file mode 100644
index 0000000..4db5a65
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/FederationMetadataPolicyDeserializer.java
@@ -0,0 +1,159 @@
+/*
+ * 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.oidfed.metadata.policy;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.type.MapType;
+import com.fasterxml.jackson.databind.type.TypeFactory;
+
+import net.shibboleth.oidc.metadata.policy.MetadataPolicy;
+import net.shibboleth.shared.annotation.ParameterName;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+/**
+ * Default deserializer for the {@link MetadataPolicy} used within OpenID Federation. If the value for the "value"
+ * -operator is explicitly set to null in JSON, this deserializer sets {@link MetadataPolicy#setValue(Object)} into
+ * {@link Optional#empty()}.
+ */
+public class FederationMetadataPolicyDeserializer extends JsonDeserializer<MetadataPolicy> {
+
+ /** Class logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(FederationMetadataPolicyDeserializer.class);
+
+ /** List of claim names who are transformed from a space-separated String into a List. */
+ @Nonnull private final List<String> arraysAsSpaceSeparatedList;
+
+ /**
+ * Constructor.
+ */
+ public FederationMetadataPolicyDeserializer() {
+ this("scope");
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param string comma-separated list of claim names who are transformed from a space-separated String into a List.
+ */
+ public FederationMetadataPolicyDeserializer(
+ @Nonnull @ParameterName(name = "arraysAsSpaceSeparatedList") final String string) {
+ final List<String> list = Arrays.asList(Constraint.isNotEmpty(string, "The string cannot be empty").split(","));
+ assert list != null;
+ arraysAsSpaceSeparatedList = list;
+ }
+
+ /** {@inheritDoc} */
+ @Override @Nonnull
+ public MetadataPolicy deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext)
+ throws IOException, JsonProcessingException {
+ final MetadataPolicy policy = new MetadataPolicy();
+ log.debug("Starting deseralize");
+ final JavaType objectType = TypeFactory.defaultInstance().constructType(Object.class);
+ final JavaType stringType = TypeFactory.defaultInstance().constructType(String.class);
+ final MapType objectMapType =
+ TypeFactory.defaultInstance().constructMapType(Map.class, stringType, objectType);
+
+ final Map<String,Object> map = deserializationContext.readValue(jsonParser, objectMapType);
+ final String claim = jsonParser.getParsingContext().getCurrentName();
+ if (claim == null) {
+ throw new IOException("Could not find the parent claim name for the metadata policy");
+ }
+ log.debug("Processing claim {}, value {}", claim, map);
+
+ if (map != null) {
+ log.debug("Processing map object {}", map);
+ for (final String key : map.keySet().stream().filter(Objects::nonNull).toList()) {
+ switch (key) {
+ case "value":
+ final Object value = FederationMetadataPolicyHelper.transformSpaceSeparatedStringIntoList(
+ arraysAsSpaceSeparatedList, claim, map.get("value"));
+ policy.setValue(value != null ? value : Optional.empty());
+ break;
+ case "add":
+ policy.setAdd(FederationMetadataPolicyHelper.transformSpaceSeparatedStringIntoList(
+ arraysAsSpaceSeparatedList, claim, map.get("add")));
+ break;
+ case "default":
+ policy.setDefaultValue(FederationMetadataPolicyHelper.transformSpaceSeparatedStringIntoList(
+ arraysAsSpaceSeparatedList, claim, map.get("default")));
+ break;
+ case "essential":
+ policy.setEssential(map.get("essential") != null ?
+ Boolean.valueOf(String.valueOf(map.get("essential"))).booleanValue() : false);
+ break;
+ case "one_of":
+ policy.setOneOfValues(transformObjectIntoList("one_of",
+ FederationMetadataPolicyHelper.transformSpaceSeparatedStringIntoList(
+ arraysAsSpaceSeparatedList, claim, map.get("one_of"))));
+ break;
+ case "subset_of":
+ policy.setSubsetOfValues(transformObjectIntoList("subset_of",
+ FederationMetadataPolicyHelper.transformSpaceSeparatedStringIntoList(
+ arraysAsSpaceSeparatedList, claim, map.get("subset_of"))));
+ break;
+ case "superset_of":
+ policy.setSupersetOfValues(transformObjectIntoList("superset_of",
+ FederationMetadataPolicyHelper.transformSpaceSeparatedStringIntoList(
+ arraysAsSpaceSeparatedList, claim, map.get("superset_of"))));
+ break;
+ case "regexp":
+ policy.setRegexp(map.get("regexp") == null ? null : "" + map.get("regexp"));
+ break;
+ default:
+ policy.setCustomOperator(key, map.get(key));
+ break;
+ }
+ }
+ } else {
+ log.debug("No map object could be parsed from the input, leaving the policy empty");
+ }
+ return policy;
+ }
+
+ /**
+ * Transforms the given value into a list of objects.
+ *
+ * @param id the key for the map of objects
+ * @param object the object value
+ * @return the value for the key as list or null
+ * @throws IOException if a non-null value could not be transformed into a list
+ */
+ @Nullable private List<Object> transformObjectIntoList(@Nonnull final String id,
+ @Nullable final Object object) throws IOException {
+ if (object instanceof List<?> list) {
+ return list.stream().filter(Object.class::isInstance).map(Object.class::cast).toList();
+ } else if (object != null) {
+ throw new IOException("The value '" + object + "' for '" + id + "' is not a list");
+ }
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/FederationMetadataPolicyHelper.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/FederationMetadataPolicyHelper.java
new file mode 100644
index 0000000..287e203
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/FederationMetadataPolicyHelper.java
@@ -0,0 +1,80 @@
+/*
+ * 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.oidfed.metadata.policy;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import net.shibboleth.shared.logic.ConstraintViolationException;
+
+/**
+ * Static utility method related to federation metadata policies.
+ */
+public class FederationMetadataPolicyHelper {
+
+ /**
+ * Transforms a list into a space-separated string. Operation is done for non-null values if the given claim is
+ * included in the given list of claims that are to be transformed.
+ *
+ * @param arraysAsSpaceSeparatedList the list of claim names to be transformed
+ * @param claim the candidate claim
+ * @param value the candidate claim value
+ * @return the claim value transformed into a space-separated string if it met the requirements, or initial value
+ * if not
+ * @throws ConstraintViolationException if the non-null value to be transformed was not a list
+ */
+ @Nullable
+ public static Object transformListIntoSpaceSeparatedString(@Nonnull final List<String> arraysAsSpaceSeparatedList,
+ @Nonnull final String claim, @Nullable final Object value) throws ConstraintViolationException {
+ if (arraysAsSpaceSeparatedList.contains(claim)) {
+ if (value instanceof List<?> list) {
+ return list.stream()
+ .map(item -> String.valueOf(item))
+ .collect(Collectors.joining(" "));
+ } else if (value != null) {
+ throw new ConstraintViolationException(
+ "Unexpected value for claim " + claim + ": the value is not a List");
+ }
+ }
+ return value;
+ }
+
+ /**
+ * Transforms a space-separated string into a list. Operation is done for non-null values if the given claim is
+ * included in the given list of claims that are to be transformed.
+ *
+ * @param arraysAsSpaceSeparatedList the list of claim names to be transformed
+ * @param claim the candidate claim
+ * @param value the candidate claim value
+ * @return the claim value transformed into a list if it met the requirements, or initial value
+ * @throws ConstraintViolationException if the non-null value to be transformed was not a string
+ */
+ @Nullable
+ public static Object transformSpaceSeparatedStringIntoList(@Nonnull final List<String> arraysAsSpaceSeparatedList,
+ @Nonnull final String claim, @Nullable final Object value) throws ConstraintViolationException {
+ if (arraysAsSpaceSeparatedList.contains(claim)) {
+ if (value instanceof String string) {
+ return List.of(string.split(" "));
+ } else if (value != null) {
+ throw new ConstraintViolationException(
+ "Unexpected value for claim " + claim + ": the value is not a String");
+ }
+ }
+ return value;
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/FederationMetadataPolicyOperator.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/FederationMetadataPolicyOperator.java
new file mode 100644
index 0000000..c6a367a
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/FederationMetadataPolicyOperator.java
@@ -0,0 +1,49 @@
+/*
+ * 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.oidfed.metadata.policy;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import net.shibboleth.oidc.metadata.policy.MetadataPolicy;
+import net.shibboleth.shared.logic.ConstraintViolationException;
+
+/**
+ * Interface to be implemented by the federation metadata policy operators.
+ *
+ * TODO: once moved to commons, merge with net.shibboleth.oidc.metadata.policy.impl.CustomMetadataPolicyOperator
+ */
+public interface FederationMetadataPolicyOperator {
+
+ /**
+ * Validate whether the operator is compatible with the other operators in the policy.
+ *
+ * @param policy The metadata policy to be used by the custom policy operator.
+ * @return true if the policy is valid for this operator, false otherwise.
+ */
+ public boolean validate(@Nonnull final MetadataPolicy policy);
+
+ /**
+ * Apply the operator for the given input that has the given metadata policy attached.
+ *
+ * @param inputValue The value to be used by the custom policy operator.
+ * @param policy The metadata policy to be used by the custom policy operator.
+ * @return The value returned by the custom policy operator.
+ * @throws ConstraintViolationException If the value-check of the custom operator fails.
+ */
+ @Nullable public Object apply(@Nullable final Object inputValue, @Nonnull final MetadataPolicy policy)
+ throws ConstraintViolationException;
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/AbstractFederationMetadataPolicyOperator.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/AbstractFederationMetadataPolicyOperator.java
new file mode 100644
index 0000000..926edbb
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/AbstractFederationMetadataPolicyOperator.java
@@ -0,0 +1,56 @@
+/*
+ * 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.oidfed.metadata.policy.impl;
+
+import java.util.List;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.policy.FederationMetadataPolicyOperator;
+import net.shibboleth.oidc.metadata.policy.MetadataPolicy;
+import net.shibboleth.shared.component.AbstractIdentifiableInitializableComponent;
+import net.shibboleth.shared.logic.ConstraintViolationException;
+
+/**
+ * Base implementation for the classes implementing {@link FederationMetadataPolicyOperator}.
+ */
+public abstract class AbstractFederationMetadataPolicyOperator extends AbstractIdentifiableInitializableComponent
+ implements FederationMetadataPolicyOperator {
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean validate(@Nonnull final MetadataPolicy policy) {
+ return true;
+ }
+
+ /**
+ * Parses a list from the given object.
+ *
+ * @param object the object to be parsed
+ * @return a list of it couöd be parsed from the object, or null if input was null
+ * @throws ConstraintViolationException thrown if non-null input value was not a list
+ */
+ @Nullable protected static List<Object> parseList(@Nullable final Object object)
+ throws ConstraintViolationException {
+ if (object instanceof List<?> list) {
+ return list.stream().filter(Object.class::isInstance).map(Object.class::cast).toList();
+ } else if (object != null) {
+ throw new ConstraintViolationException("Could not parse list from the given object");
+ }
+ return null;
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicyAddOperator.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicyAddOperator.java
new file mode 100644
index 0000000..e30ffc4
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicyAddOperator.java
@@ -0,0 +1,109 @@
+/*
+ * 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.oidfed.metadata.policy.impl;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.stream.Stream;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+
+import net.shibboleth.oidc.metadata.policy.MetadataPolicy;
+import net.shibboleth.oidc.metadata.policy.impl.MetadataPolicyHelper;
+import net.shibboleth.shared.collection.CollectionSupport;
+import net.shibboleth.shared.logic.ConstraintViolationException;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+/**
+ * Default implementation for the 'add'-operator.
+ */
+public class DefaultFederationMetadataPolicyAddOperator extends AbstractFederationMetadataPolicyOperator {
+
+ /** Class logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(DefaultFederationMetadataPolicyAddOperator.class);
+
+ /** {@inheritDoc} */
+ @Override
+ @Nullable public Object apply(@Nullable final Object candidate, @Nonnull final MetadataPolicy policy)
+ throws ConstraintViolationException {
+ final List<Object> add = parseList(policy.getAdd());
+ if (add != null) {
+ if (candidate instanceof List<?> list) {
+ log.debug("Combining candidate {} and add {}", list, add);
+ return buildResult(Stream.concat(list.stream(), add.stream()));
+ } else if (candidate == null) {
+ log.debug("Returning the contents of the add operator: {}", add);
+ return buildResult(add.stream());
+ } else {
+ log.debug("Candidate value {} is not a list/array", candidate);
+ throw new ConstraintViolationException("Candidate " + candidate + " is not a list/array");
+ }
+ }
+ return candidate;
+ }
+
+ /**
+ * Builds a list from the given stream.
+ *
+ * @param stream the stream
+ * @return the list
+ */
+ @Nonnull protected List<Object> buildResult(final Stream<?> stream) {
+ final List<Object> result = stream
+ .filter(Object.class::isInstance)
+ .map(Object.class::cast)
+ .distinct()
+ .toList();
+ assert result != null;
+ return CollectionSupport.copyToList(result);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean validate(@Nonnull final MetadataPolicy policy) {
+ final List<Object> add;
+ try {
+ add = parseList(policy.getAdd());
+ } catch (final ConstraintViolationException e) {
+ log.warn("The value for add operator {} is not a list/array", policy.getAdd());
+ return false;
+ }
+ if (add == null || add.isEmpty()) {
+ return true;
+ }
+ boolean validation = true;
+ final Object value = policy.getValue();
+ if (value instanceof Collection<?> valueCollection) {
+ if (!MetadataPolicyHelper.isSubsetOfValues(add, valueCollection)) {
+ log.debug("The value for add operator {} is not a subset of value {}", add, valueCollection);
+ validation = false;
+ }
+ } else if (value != null) {
+ log.warn("The value {} is not a list/array", value);
+ validation = false;
+ }
+ final List<Object> subsetOf = policy.getSubsetOfValues();
+ if (subsetOf != null && !MetadataPolicyHelper.isSubsetOfValues(add, subsetOf)) {
+ log.debug("The value for add operator {} is not a subset of value for the subset_of operator {}", add,
+ subsetOf);
+ validation = false;
+ }
+ return validation;
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicyDefaultOperator.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicyDefaultOperator.java
new file mode 100644
index 0000000..89bf483
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicyDefaultOperator.java
@@ -0,0 +1,38 @@
+/*
+ * 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.oidfed.metadata.policy.impl;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import net.shibboleth.oidc.metadata.policy.MetadataPolicy;
+import net.shibboleth.shared.logic.ConstraintViolationException;
+
+/**
+ * Default implementation for the 'default' -operator.
+ */
+public class DefaultFederationMetadataPolicyDefaultOperator extends AbstractFederationMetadataPolicyOperator {
+
+ /** {@inheritDoc} */
+ @Override
+ @Nullable public Object apply(@Nullable final Object candidate, @Nonnull final MetadataPolicy policy)
+ throws ConstraintViolationException {
+ if (candidate != null) {
+ return candidate;
+ }
+ final Object defaultValue = policy.getDefaultValue();
+ return defaultValue != null ? defaultValue : candidate;
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicyEnforcer.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicyEnforcer.java
new file mode 100644
index 0000000..8bbeda6
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicyEnforcer.java
@@ -0,0 +1,95 @@
+/*
+ * 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.oidfed.metadata.policy.impl;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.function.BiFunction;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.policy.FederationMetadataPolicyOperator;
+import net.shibboleth.oidc.metadata.policy.MetadataPolicy;
+import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.collection.Pair;
+import net.shibboleth.shared.component.AbstractIdentifiableInitializableComponent;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.logic.ConstraintViolationException;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+/**
+ * <p>A function that applies the given {@link MetadataPolicy} to the given object. The input is given as a {@link
+ * Pair} of the object and the policy. The policy is applied to the incoming object as specified in the OpenID
+ * Federation specification 1.0 (draft 42 / April 2025)</p>
+ *
+ * <p>In addition to the standard operators, we also support regular expression validation.</p>
+ *
+ * <p>The function returns a {@link Pair} of the object for which the value modifiers of the metadata policy have
+ * been applied to, and a flag indicating if the object was compatible with the value checks of the metadata policy.
+ * </p>
+ */
+public class DefaultFederationMetadataPolicyEnforcer extends AbstractIdentifiableInitializableComponent
+ implements BiFunction<Object,MetadataPolicy,Pair<Object,Boolean>> {
+
+ /** Class logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(DefaultFederationMetadataPolicyEnforcer.class);
+
+ /** The list of metadata policy operators used for enforcing the metadata policy. */
+ @NonnullAfterInit List<FederationMetadataPolicyOperator> operators;
+
+ /**
+ * Set the list of metadata policy operators used for enforcing the metadata policy.
+ *
+ * @param policyOperators What to set
+ */
+ public void setMetadataPolicyOperators(@Nonnull final List<FederationMetadataPolicyOperator> policyOperators) {
+ checkSetterPreconditions();
+ operators = Constraint.isNotNull(policyOperators, "List of metadata policy operators cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override @Nullable public Pair<Object, Boolean> apply(@Nullable final Object candidate,
+ @Nullable final MetadataPolicy policy) {
+ if (policy == null) {
+ return new Pair<>(candidate, Boolean.TRUE);
+ }
+ Object operatorResult = candidate;
+ for (final FederationMetadataPolicyOperator operator : operators) {
+ try {
+ operatorResult = operator.apply(operatorResult, policy);
+ } catch (final ConstraintViolationException e) {
+ log.debug("Operator {} returned a non-success result", operator.getClass());
+ return new Pair<>(operatorResult, Boolean.FALSE);
+ }
+ }
+ return new Pair<>(operatorResult, Boolean.TRUE);
+ }
+
+ /**
+ * Checks if the given result of metadata policy operator is a success result.
+ *
+ * @param result operator result to be verified
+ * @return true if success, false otherwise (including null)
+ */
+ protected boolean isSuccessResult(@Nullable final Pair<Object,Boolean> result) {
+ return Optional.ofNullable(result)
+ .map(pair -> pair.getSecond())
+ .map(second -> second.booleanValue())
+ .orElse(false);
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicyEssentialOperator.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicyEssentialOperator.java
new file mode 100644
index 0000000..8a1efc7
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicyEssentialOperator.java
@@ -0,0 +1,40 @@
+/*
+ * 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.oidfed.metadata.policy.impl;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import net.shibboleth.oidc.metadata.policy.MetadataPolicy;
+import net.shibboleth.shared.logic.ConstraintViolationException;
+
+/**
+ * Default implementation for the 'essential' -operator.
+ */
+public class DefaultFederationMetadataPolicyEssentialOperator extends AbstractFederationMetadataPolicyOperator {
+
+ /** {@inheritDoc} */
+ @Override
+ @Nullable public Object apply(@Nullable final Object candidate, @Nonnull final MetadataPolicy policy)
+ throws ConstraintViolationException {
+ if (candidate != null) {
+ return candidate;
+ }
+ if (policy.isEssential()) {
+ throw new ConstraintViolationException("Essential value is missing");
+ }
+ return candidate;
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicyMergingStrategy.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicyMergingStrategy.java
new file mode 100644
index 0000000..1fb28ca
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicyMergingStrategy.java
@@ -0,0 +1,102 @@
+/*
+ * 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.oidfed.metadata.policy.impl;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.BiFunction;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.policy.FederationMetadataPolicyOperator;
+import net.shibboleth.oidc.metadata.policy.MetadataPolicy;
+import net.shibboleth.oidc.metadata.policy.impl.MetadataPolicyHelper;
+import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.collection.Pair;
+import net.shibboleth.shared.component.AbstractIdentifiableInitializableComponent;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.logic.ConstraintViolationException;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+/**
+ * A function that merges two maps of metadata policies according to the rules specified in the OID federation spec
+ * (draft 42), section 6.1. The function returns a pair of map of merged metadata policies and a boolean indicating if
+ * the merging operators in the policies were compliant.
+ */
+public class DefaultFederationMetadataPolicyMergingStrategy extends AbstractIdentifiableInitializableComponent
+ implements BiFunction<Map<String, MetadataPolicy>, Map<String, MetadataPolicy>,
+ Pair<Map<String, MetadataPolicy>, Boolean>> {
+
+ /** Class logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(DefaultFederationMetadataPolicyMergingStrategy.class);
+
+ /** The list of metadata policy operators used for enforcing the metadata policy. */
+ @NonnullAfterInit List<FederationMetadataPolicyOperator> operators;
+
+ /**
+ * Set the list of metadata policy operators used for enforcing the metadata policy.
+ *
+ * @param policyOperators What to set
+ */
+ public void setMetadataPolicyOperators(@Nonnull final List<FederationMetadataPolicyOperator> policyOperators) {
+ checkSetterPreconditions();
+ operators = Constraint.isNotNull(policyOperators, "List of metadata policy operators cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Nonnull
+ public Pair<Map<String, MetadataPolicy>, Boolean> apply(@Nullable final Map<String,MetadataPolicy> first,
+ @Nullable final Map<String,MetadataPolicy> second) {
+ if (first == null || first.isEmpty()) {
+ return new Pair<>(second == null ? (first == null ? null : Collections.emptyMap()) : second , Boolean.TRUE);
+ } else if (second == null || second.isEmpty()) {
+ return new Pair<>(first, Boolean.TRUE);
+ }
+ final Set<String> combinedKeys = Stream.concat(first.keySet().stream(),
+ second.keySet().stream()).collect(Collectors.toSet());
+ final Map<String, MetadataPolicy> result = new HashMap<>();
+ boolean valid = true;
+ for (final String key : combinedKeys) {
+ try {
+ final MetadataPolicy merged =
+ MetadataPolicyHelper.mergeMetadataPolicies(first.get(key), second.get(key));
+ log.debug("Merging result of {} with {}: {}", first.get(key), second.get(key), merged);
+ if (merged != null && merged.getOneOfValues() != null && merged.getOneOfValues().isEmpty()) {
+ log.warn("Value of 'one_of' operator is empty after merging");
+ valid = false;
+ }
+ result.put(key, merged);
+ for (final FederationMetadataPolicyOperator operator : operators) {
+ if (merged != null && !operator.validate(merged)) {
+ valid = false;
+ }
+ }
+ } catch (final ConstraintViolationException e) {
+ log.warn("Incompatible metadata policies for claim '{}' that cannot be merged.", key);
+ valid = false;
+ }
+ }
+ return new Pair<>(result, Boolean.valueOf(valid));
+ }
+
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicyOneOfOperator.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicyOneOfOperator.java
new file mode 100644
index 0000000..04a39f0
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicyOneOfOperator.java
@@ -0,0 +1,66 @@
+/*
+ * 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.oidfed.metadata.policy.impl;
+
+import java.util.List;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+
+import net.shibboleth.oidc.metadata.policy.MetadataPolicy;
+import net.shibboleth.shared.logic.ConstraintViolationException;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+/**
+ * Default implementation for the 'one_of' -operator.
+ */
+public class DefaultFederationMetadataPolicyOneOfOperator extends AbstractFederationMetadataPolicyOperator {
+
+ /** Class logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(DefaultFederationMetadataPolicyOneOfOperator.class);
+
+ /** {@inheritDoc} */
+ @Override
+ @Nullable public Object apply(@Nullable final Object candidate, @Nonnull final MetadataPolicy policy)
+ throws ConstraintViolationException {
+ final List<Object> oneOf = policy.getOneOfValues();
+ if (candidate == null || oneOf == null) {
+ log.debug("No candidate or one_of value present. nothing to do");
+ return candidate;
+ }
+ if (!oneOf.contains(candidate)) {
+ throw new ConstraintViolationException(
+ "The candidate " + candidate + " is not included in the values for one_of: " + oneOf);
+ }
+ return candidate;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean validate(@Nonnull final MetadataPolicy policy) {
+ final List<Object> oneOf = policy.getOneOfValues();
+ if (oneOf == null) {
+ return true;
+ }
+ final Object value = policy.getValue();
+ if (value != null && !oneOf.contains(value)) {
+ log.debug("The value {} is not included in the values for one_of: {}", value, oneOf);
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicySubsetOfOperator.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicySubsetOfOperator.java
new file mode 100644
index 0000000..f5a05be
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicySubsetOfOperator.java
@@ -0,0 +1,88 @@
+/*
+ * 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.oidfed.metadata.policy.impl;
+
+import java.util.List;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+
+import net.shibboleth.oidc.metadata.policy.MetadataPolicy;
+import net.shibboleth.oidc.metadata.policy.impl.MetadataPolicyHelper;
+import net.shibboleth.shared.collection.CollectionSupport;
+import net.shibboleth.shared.logic.ConstraintViolationException;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+/**
+ * Default implementation for the 'subset_of' -operator.
+ */
+public class DefaultFederationMetadataPolicySubsetOfOperator extends AbstractFederationMetadataPolicyOperator {
+
+ /** Class logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(DefaultFederationMetadataPolicySubsetOfOperator.class);
+
+ /** {@inheritDoc} */
+ @Override
+ @Nullable public Object apply(@Nullable final Object candidate, @Nonnull final MetadataPolicy policy)
+ throws ConstraintViolationException {
+ final List<Object> subsetOf = policy.getSubsetOfValues();
+ if (candidate == null || subsetOf == null) {
+ log.debug("No candidate or subset_of value present. nothing to do");
+ return candidate;
+ }
+ if (candidate instanceof List<?> list) {
+ final List<Object> candidateList = list.stream()
+ .filter(Object.class::isInstance)
+ .map(Object.class::cast)
+ .filter(item -> subsetOf.contains(item))
+ .toList();
+ assert candidateList != null;
+ return CollectionSupport.copyToList(candidateList);
+ }
+ log.debug("Candidate value {} is not a list/array", candidate);
+ throw new ConstraintViolationException("Candidate value " + candidate + " is not a list/array");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean validate(@Nonnull final MetadataPolicy policy) {
+ final List<Object> subsetOf = policy.getSubsetOfValues();
+ if (subsetOf == null) {
+ return true;
+ }
+ boolean validation = true;
+ final Object value = policy.getValue();
+ if (value != null && !MetadataPolicyHelper.isSubsetOfValues(value, subsetOf)) {
+ log.debug("The value {} is not a subset of the values for subset_of operator {}", value, subsetOf);
+ validation = false;
+ }
+ final Object add = policy.getAdd();
+ if (add != null && !MetadataPolicyHelper.isSubsetOfValues(add, subsetOf)) {
+ log.debug("The value for add operator {} is not a subset of the values for subset_of operator {}", add,
+ subsetOf);
+ validation = false;
+ }
+ final List<Object> supersetOf = policy.getSupersetOfValues();
+ if (supersetOf != null && !MetadataPolicyHelper.isSupersetOfValues(subsetOf, supersetOf)) {
+ log.debug("The value for subset_of operator {} is not a subset of the values for superset_of operator {}",
+ subsetOf, supersetOf);
+ validation = false;
+ }
+ return validation;
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicySupersetOfOperator.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicySupersetOfOperator.java
new file mode 100644
index 0000000..5cea512
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicySupersetOfOperator.java
@@ -0,0 +1,86 @@
+/*
+ * 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.oidfed.metadata.policy.impl;
+
+import java.util.List;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+
+import net.shibboleth.oidc.metadata.policy.MetadataPolicy;
+import net.shibboleth.oidc.metadata.policy.impl.MetadataPolicyHelper;
+import net.shibboleth.shared.collection.CollectionSupport;
+import net.shibboleth.shared.logic.ConstraintViolationException;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+/**
+ * Default implementation for the 'superset_of' -operator.
+ */
+public class DefaultFederationMetadataPolicySupersetOfOperator extends AbstractFederationMetadataPolicyOperator {
+
+ /** Class logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(DefaultFederationMetadataPolicySupersetOfOperator.class);
+
+ /** {@inheritDoc} */
+ @Override
+ @Nullable public Object apply(@Nullable final Object candidate, @Nonnull final MetadataPolicy policy)
+ throws ConstraintViolationException {
+ final List<Object> supersetOf = policy.getSupersetOfValues();
+ if (candidate == null || supersetOf == null) {
+ return candidate;
+ }
+ final List<Object> candidateList;
+ if (candidate instanceof List<?> list) {
+ candidateList = list.stream().filter(Object.class::isInstance).map(Object.class::cast).toList();
+ } else {
+ log.warn("The value for superset_of is not a list/array {}", candidate);
+ throw new ConstraintViolationException("Candidate value " + candidate + " is not a list/array");
+ }
+ assert candidateList != null;
+
+ if (!candidateList.containsAll(supersetOf)) {
+ log.debug("The candidate {} did not contain all the values of superset_of: {}", candidate, supersetOf);
+ throw new ConstraintViolationException(
+ "Candidate value " + candidate + " did not contain all values of superset_of: " + supersetOf);
+ }
+
+ return CollectionSupport.copyToList(candidateList);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean validate(@Nonnull final MetadataPolicy policy) {
+ final List<Object> supersetOf = policy.getSupersetOfValues();
+ if (supersetOf == null) {
+ return true;
+ }
+
+ boolean validation = true;
+ final Object value = policy.getValue();
+ if (value != null && !MetadataPolicyHelper.isSupersetOfValues(value, supersetOf)) {
+ log.debug("The value {} is not a superset of the values for subset_of operator {}", value, supersetOf);
+ validation = false;
+ }
+ final List<Object> subsetOf = policy.getSubsetOfValues();
+ if (subsetOf != null && !MetadataPolicyHelper.isSupersetOfValues(subsetOf, supersetOf)) {
+ log.debug("The value for subset_of operator {} is not a superset of the values for superset_of operator {}",
+ subsetOf, supersetOf);
+ validation = false;
+ }
+ return validation;
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicyValueOperator.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicyValueOperator.java
new file mode 100644
index 0000000..fee597c
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicyValueOperator.java
@@ -0,0 +1,82 @@
+/*
+ * 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.oidfed.metadata.policy.impl;
+
+import java.util.List;
+import java.util.Optional;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+
+import net.shibboleth.oidc.metadata.policy.MetadataPolicy;
+import net.shibboleth.oidc.metadata.policy.impl.MetadataPolicyHelper;
+import net.shibboleth.shared.logic.ConstraintViolationException;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+/**
+ * Default implementation for the 'value' -operator.
+ */
+public class DefaultFederationMetadataPolicyValueOperator extends AbstractFederationMetadataPolicyOperator {
+
+ /** Class logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(DefaultFederationMetadataPolicyValueOperator.class);
+
+ /** {@inheritDoc} */
+ @Override
+ @Nullable public Object apply(@Nullable final Object candidate, @Nonnull final MetadataPolicy policy)
+ throws ConstraintViolationException {
+ final Object value = policy.getValue();
+ return value != null ?value instanceof Optional optional && optional.isEmpty() ? null : value : candidate;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean validate(@Nonnull final MetadataPolicy policy) {
+ final Object value = policy.getValue();
+ if (value instanceof Optional optional && optional.isEmpty()) {
+ if (policy.isEssential()) {
+ log.debug("Value for the value operator is null and essential is true");
+ return false;
+ }
+ if (policy.getDefaultValue() != null) {
+ log.debug("Null value cannot be combined with non-empty default: {}", policy.getDefaultValue());
+ return false;
+ }
+ log.debug("Value for the value operator is null and essential is false");
+ return true;
+ } else if (value == null) {
+ return true;
+ }
+ boolean validation = true;
+ final List<Object> oneOf = policy.getOneOfValues();
+ if (oneOf != null && !oneOf.contains(value)) {
+ log.debug("Value {} is not included in the one_of values {}", value, oneOf);
+ validation = false;
+ }
+ final List<Object> subsetOf = policy.getSubsetOfValues();
+ if (subsetOf != null && !MetadataPolicyHelper.isSubsetOfValues(value, subsetOf)) {
+ log.debug("Value {} is not included in the of subset_of values {}", value, subsetOf);
+ validation = false;
+ }
+ final List<Object> supersetOf = policy.getSupersetOfValues();
+ if (supersetOf != null && !MetadataPolicyHelper.isSupersetOfValues(value, supersetOf)) {
+ log.debug("Value {} is not included in the of superset_of values {}", value, supersetOf);
+ validation = false;
+ }
+ return validation;
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/package-info.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/package-info.java
new file mode 100644
index 0000000..a097e1a
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/package-info.java
@@ -0,0 +1,18 @@
+/*
+ * 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.
+ */
+
+/**
+ * Top level OIDC OP plugin classes.
+ */
+package net.shibboleth.idp.plugin.oidc.op.oidfed;
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/AbstractBuildEntityStatementAction.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/AbstractBuildEntityStatementAction.java
new file mode 100644
index 0000000..27fe3b9
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/AbstractBuildEntityStatementAction.java
@@ -0,0 +1,309 @@
+/*
+ * 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.oidfed.profile.impl;
+
+import java.text.ParseException;
+import java.time.Instant;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.messaging.context.navigate.ChildContextLookup;
+import org.opensaml.messaging.encoder.AbstractMessageEncoder;
+import org.opensaml.profile.action.ActionSupport;
+import org.opensaml.profile.action.EventIds;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.opensaml.profile.context.navigate.OutboundMessageContextLookup;
+import org.slf4j.Logger;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.nimbusds.jwt.JWT;
+import com.nimbusds.jwt.JWTClaimsSet;
+import com.nimbusds.jwt.PlainJWT;
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.navigate.AuthorityHintsLookupFunction;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.navigate.EntityStatementClaimsSetManipulationStrategyLookupFunction;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.tbd.ResponseUtil;
+import net.shibboleth.idp.profile.AbstractProfileAction;
+import net.shibboleth.idp.profile.IdPEventIds;
+import net.shibboleth.profile.context.navigate.IssuerLookupFunction;
+import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.logic.FunctionSupport;
+import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.security.IdentifierGenerationStrategy;
+import net.shibboleth.shared.security.impl.SecureRandomIdentifierGenerationStrategy;
+
+/**
+ * Abstract action used by actions that build {@link EntityStatement}s.
+ */
+public abstract class AbstractBuildEntityStatementAction extends AbstractProfileAction {
+
+ /** Class logger. */
+ @Nonnull private Logger log = LoggerFactory.getLogger(AbstractBuildEntityStatementAction.class);
+
+ /** Used to log protocol messages. */
+ @Nonnull protected Logger protocolMessageLog =
+ LoggerFactory.getLogger(AbstractMessageEncoder.BASE_PROTOCOL_MESSAGE_LOGGER_CATEGORY + ".OIDFED");
+
+ /** Strategy used to obtain the issuer value. */
+ @Nonnull private Function<ProfileRequestContext,String> issuerLookupStrategy;
+
+ /** Strategy used to obtain the subject value. */
+ @Nonnull private Function<ProfileRequestContext,String> subjectLookupStrategy;
+
+ /** Strategy used to locate the {@link IdentifierGenerationStrategy} to use. */
+ @Nonnull private Function<ProfileRequestContext,IdentifierGenerationStrategy> idGeneratorLookupStrategy;
+
+ /** Strategy used to locate the subcontext to hold the statement. */
+ @Nonnull private Function<ProfileRequestContext,EntityStatementContext> entityStatementContextLookupStrategy;
+
+ /** Strategy used to locate authority hints. */
+ @Nonnull private Function<ProfileRequestContext,List<String>> authorityHintsLookupStrategy;
+
+ /** Lookup function to supply strategy bi-function for manipulating entity statement claims set. */
+ @Nonnull
+ private Function<ProfileRequestContext,BiFunction<ProfileRequestContext,Map<String,Object>,Map<String,Object>>>
+ entityStatementClaimsSetManipulationStrategyLookupStrategy;
+
+ /** The strategy used for manipulating the entity statement claims set. */
+ @Nullable private BiFunction<ProfileRequestContext,Map<String,Object>,Map<String,Object>> manipulationStrategy;
+
+ /** Object mapper used for pretty-printing JWT contents. */
+ @NonnullAfterInit private ObjectMapper objectMapper;
+
+ /** The generator to use. */
+ @NonnullBeforeExec protected IdentifierGenerationStrategy idGenerator;
+
+ /** Entity statement context. */
+ @NonnullBeforeExec protected EntityStatementContext entityStatementCtx;
+
+ /** Constructor. */
+ public AbstractBuildEntityStatementAction() {
+ issuerLookupStrategy = new IssuerLookupFunction();
+ subjectLookupStrategy = new IssuerLookupFunction();
+
+ idGeneratorLookupStrategy = FunctionSupport.constant(new SecureRandomIdentifierGenerationStrategy());
+
+ final Function<ProfileRequestContext,EntityStatementContext> escls =
+ new ChildContextLookup<>(EntityStatementContext.class, true).compose(
+ new OutboundMessageContextLookup());
+ assert escls != null;
+ entityStatementContextLookupStrategy = escls;
+
+ authorityHintsLookupStrategy = new AuthorityHintsLookupFunction();
+
+ entityStatementClaimsSetManipulationStrategyLookupStrategy =
+ new EntityStatementClaimsSetManipulationStrategyLookupFunction();
+ }
+
+ /**
+ * Set the strategy used to locate the {@link IdentifierGenerationStrategy} to use.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setIdentifierGeneratorLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext,IdentifierGenerationStrategy> strategy) {
+ ifInitializedThrowUnmodifiabledComponentException();
+
+ idGeneratorLookupStrategy =
+ Constraint.isNotNull(strategy, "Identifier generation strategy cannot be null");
+ }
+
+ /**
+ * Set the strategy used to locate the issuer value to use.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setIssuerLookupStrategy(@Nonnull final Function<ProfileRequestContext,String> strategy) {
+ ifInitializedThrowUnmodifiabledComponentException();
+
+ issuerLookupStrategy = Constraint.isNotNull(strategy, "Issuer lookup strategy cannot be null");
+ }
+
+ /**
+ * Set the strategy used to locate the subject value to use.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setSubjectLookupStrategy(@Nonnull final Function<ProfileRequestContext,String> strategy) {
+ ifInitializedThrowUnmodifiabledComponentException();
+
+ subjectLookupStrategy = Constraint.isNotNull(strategy, "Subject lookup strategy cannot be null");
+ }
+
+ /**
+ * Set the strategy used to lookup the {@link EntityStatementContext} to use.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setEntityStatementContextLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext,EntityStatementContext> strategy) {
+ ifInitializedThrowUnmodifiabledComponentException();
+
+ entityStatementContextLookupStrategy =
+ Constraint.isNotNull(strategy, "EntityStatementContext lookup strategy cannot be null");
+ }
+
+ /**
+ * Set the lookup function to supply strategy bi-function for manipulating entity statement claims set.
+ *
+ * @param strategy What to set
+ */
+ public void setEntityStatementClaimsSetManipulationStrategyLookupStrategy(@Nonnull final
+ Function<ProfileRequestContext,BiFunction<ProfileRequestContext,Map<String,Object>,Map<String,Object>>>
+ strategy) {
+ ifInitializedThrowUnmodifiabledComponentException();
+
+ entityStatementClaimsSetManipulationStrategyLookupStrategy =
+ Constraint.isNotNull(strategy, "Manipulation strategy lookup strategy cannot be null");
+ }
+
+ /**
+ * Set the object mapper used for pretty-printing JWT contents.
+ *
+ * @param mapper What to set.
+ */
+ public void setObjectMapper(@Nonnull final ObjectMapper mapper) {
+ checkSetterPreconditions();
+ objectMapper = Constraint.isNotNull(mapper, "Object mapper cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+
+ if (objectMapper == null) {
+ throw new ComponentInitializationException("Object mapper cannot be null");
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+ if (!super.doPreExecute(profileRequestContext)) {
+ return false;
+ }
+
+ idGenerator = idGeneratorLookupStrategy.apply(profileRequestContext);
+ if (idGenerator == null) {
+ log.error("{} No identifier generation strategy", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
+ return false;
+ }
+
+ entityStatementCtx = entityStatementContextLookupStrategy.apply(profileRequestContext);
+ if (entityStatementCtx == null) {
+ log.error("{} Unable to fetch EntityStatementContext", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
+ return false;
+ }
+
+ manipulationStrategy =
+ entityStatementClaimsSetManipulationStrategyLookupStrategy.apply(profileRequestContext);
+
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+
+ final String issuer = issuerLookupStrategy.apply(profileRequestContext);
+ final String subject = subjectLookupStrategy.apply(profileRequestContext);
+
+ final Instant now = Instant.now();
+
+ final JWTClaimsSet.Builder builder = new JWTClaimsSet.Builder()
+ .issuer(issuer)
+ .subject(subject)
+ .issueTime(Date.from(now))
+ .claim("authority_hints", authorityHintsLookupStrategy.apply(profileRequestContext));
+ assert builder != null;
+ if (!populateClaimsSetBuilder(builder, profileRequestContext)) {
+ return;
+ }
+ final JWTClaimsSet claimsSet = builder.build();
+
+ assert claimsSet != null;
+ if (manipulationStrategy != null) {
+ log.debug("{} Manipulation strategy has been set, applying it to the claims set {}", getLogPrefix(),
+ claimsSet.toJSONObject());
+ assert manipulationStrategy != null;
+ final Map<String, Object> result = manipulationStrategy.apply(profileRequestContext,
+ claimsSet.toJSONObject());
+ if (result == null) {
+ log.debug("{} Manipulation strategy returned null, leaving statement claims set untouched.",
+ getLogPrefix());
+ } else {
+ log.debug("{} Applying the manipulated claims into the entity statement claims set", getLogPrefix());
+ try {
+ final JWTClaimsSet parsedSet = JWTClaimsSet.parse(result);
+ assert parsedSet != null;
+ logAndConstructEntityStatement(parsedSet);
+ return;
+ } catch (final ParseException e) {
+ log.error("{} The resulted claims set could not be transformed into ", getLogPrefix(), e);
+ ActionSupport.buildEvent(profileRequestContext, IdPEventIds.INVALID_PROFILE_CONFIG);
+ return;
+ }
+ }
+ } else {
+ log.debug("{} No manipulation strategy configured", getLogPrefix());
+ }
+ logAndConstructEntityStatement(claimsSet);
+ }
+
+ /**
+ * Populates the claims set builder with claims specific to the action extending this abstract action. If any
+ * problem occures during population, the profile request context should be populated with an appropriate
+ * event.
+ *
+ * @param builder the claims set builder
+ * @param profileRequestContext profile request context
+ * @return true if population was successful, false otherwise
+ */
+ protected abstract boolean populateClaimsSetBuilder(@Nonnull final JWTClaimsSet.Builder builder,
+ @Nonnull final ProfileRequestContext profileRequestContext);
+
+ /**
+ * Logs the entity statement contents via protocol message logger and constructs a plain (i.e. non-signed) JWT out
+ * of it and includes it to the {@link EntityStatementContext#setJWT(JWT)}.
+ *
+ * @param claimsSet the claims set
+ */
+ protected void logAndConstructEntityStatement(@Nonnull final JWTClaimsSet claimsSet) {
+ log.trace("{} Building JWT from the claims set {}", getLogPrefix(), claimsSet);
+ final JWT jwt = new PlainJWT(claimsSet);
+ assert objectMapper != null;
+ try {
+ protocolMessageLog.trace("Entity statement payload contents:\n{}",
+ ResponseUtil.getJwtProtocolMessage(jwt, objectMapper));
+ } catch (final ParseException e) {
+ log.error("{} Could not construct protocol log message", getLogPrefix(), e);
+ }
+ assert entityStatementCtx != null;
+ entityStatementCtx.setJWT(jwt);
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/AbstractTrustChainResolutionAction.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/AbstractTrustChainResolutionAction.java
new file mode 100644
index 0000000..12288d7
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/AbstractTrustChainResolutionAction.java
@@ -0,0 +1,312 @@
+/*
+ * 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.oidfed.profile.impl;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.function.BiFunction;
+import java.util.function.BiPredicate;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.profile.action.EventIds;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.opensaml.profile.context.navigate.InboundMessageContextLookup;
+import org.slf4j.Logger;
+
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import net.minidev.json.JSONObject;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.policy.FederationMetadataPolicyHelper;
+import net.shibboleth.idp.profile.AbstractProfileAction;
+import net.shibboleth.oidc.metadata.policy.MetadataPolicy;
+import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.collection.CollectionSupport;
+import net.shibboleth.shared.collection.Pair;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.logic.ConstraintViolationException;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+import org.opensaml.messaging.context.navigate.ChildContextLookup;
+
+/**
+ * Base action for actions initializing {@link RelyingPartyTrustChainContext} and performing metadata and metadata
+ * policy related operations.
+ *
+ * @event {@link EventIds#PROCEED_EVENT_ID}
+ * @event {@link EventIds#INVALID_MSG_CTX}
+ *
+ * @since 4.3.0
+ */
+public class AbstractTrustChainResolutionAction extends AbstractProfileAction {
+
+ /** Class logger. */
+ @Nonnull private Logger log = LoggerFactory.getLogger(AbstractTrustChainResolutionAction.class);
+
+ /** Strategy used to create the trust chain context. */
+ @Nonnull private Function<ProfileRequestContext, RelyingPartyTrustChainContext> trustChainContextCreationStrategy;
+
+ /** Strategy used to get combined entity metadata from trust chain. */
+ @Nonnull private Function<List<EntityStatement>,Map<String,Map<String,Object>>> metadataLookupStrategy;
+
+ /** Strategy used to merge metadata policies in trust chain for specific entity type. */
+ @NonnullAfterInit private BiFunction<List<EntityStatement>,String,Map<String, MetadataPolicy>>
+ metadataPolicyMergingStrategy;
+
+ /** Enforcer function for applying metadata policy for an item. */
+ @NonnullAfterInit private BiFunction<Object, MetadataPolicy, Pair<Object, Boolean>> metadataPolicyEnforcer;
+
+ /** Condition used to validate metadata for an entity type. */
+ @NonnullAfterInit private BiPredicate<String, Map<String, Object>> metadataValidationCondition;
+
+ /** List of claim names who are transformed from a space-separated String into a List. */
+ @Nonnull private List<String> arraysAsSpaceSeparatedList;
+
+ /**
+ * Constructor.
+ */
+ public AbstractTrustChainResolutionAction() {
+ final Function<ProfileRequestContext, RelyingPartyTrustChainContext> tccs =
+ new ChildContextLookup<>(RelyingPartyTrustChainContext.class, true).compose(
+ new InboundMessageContextLookup());
+ assert tccs != null;
+ trustChainContextCreationStrategy = tccs;
+ arraysAsSpaceSeparatedList = CollectionSupport.listOf("scope");
+ }
+
+ /**
+ * Set the strategy used to create the trust chain context.
+ *
+ * @param strategy creation strategy
+ */
+ public void setTrustChainContextCreationStrategy(
+ @Nonnull final Function<ProfileRequestContext, RelyingPartyTrustChainContext> strategy) {
+ checkSetterPreconditions();
+ trustChainContextCreationStrategy =
+ Constraint.isNotNull(strategy, "TrustChainContextCreationStrategy cannot be null");
+ }
+
+ /**
+ * Get the strategy used to create the trust chain context.
+ *
+ * @return creation strategy
+ */
+ @Nonnull
+ public Function<ProfileRequestContext, RelyingPartyTrustChainContext> getTrustChainContextCreationStrategy() {
+ checkComponentActive();
+ return trustChainContextCreationStrategy;
+ }
+
+ /**
+ * Set the strategy used to get combined entity metadata from trust chain.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setMetadataLookupStrategy(
+ @Nonnull final Function<List<EntityStatement>,Map<String,Map<String,Object>>> strategy) {
+ checkSetterPreconditions();
+ metadataLookupStrategy =
+ Constraint.isNotNull(strategy, "MetadataLookupStrategy cannot be null");
+ }
+
+ /**
+ * Get the strategy used to get combined entity metadata from trust chain.
+ *
+ * @return lookup strategy
+ */
+ @Nonnull public Function<List<EntityStatement>,Map<String,Map<String,Object>>> getMetadataLookupStrategy() {
+ checkComponentActive();
+ return metadataLookupStrategy;
+ }
+
+ /**
+ * Set the strategy used to merge metadata policies in trust chain for specific entity type.
+ *
+ * @param strategy merging strategy
+ */
+ public void setMetadataPolicyMergingStrategy(@Nonnull final
+ BiFunction<List<EntityStatement>,String,Map<String, MetadataPolicy>> strategy) {
+ checkSetterPreconditions();
+ metadataPolicyMergingStrategy =
+ Constraint.isNotNull(strategy, "MetadataPolicyMergingStrategy cannot be null");
+ }
+
+ /**
+ * Get the strategy used to merge metadata policies in trust chain for specific entity type.
+ *
+ * @return merging strategy
+ */
+ @Nonnull
+ public BiFunction<List<EntityStatement>,String,Map<String, MetadataPolicy>> getMetadataPolicyMergingStrategy() {
+ checkComponentActive();
+ assert metadataPolicyMergingStrategy != null;
+ return metadataPolicyMergingStrategy;
+ }
+
+ /**
+ * Set the enforcer function for applying metadata policy for an item.
+ *
+ * @param enforcer policy enforcer
+ */
+ public void setMetadataPolicyEnforcer(
+ @Nonnull final BiFunction<Object, MetadataPolicy, Pair<Object, Boolean>> enforcer) {
+ checkSetterPreconditions();
+ metadataPolicyEnforcer = Constraint.isNotNull(enforcer, "Metadata policy enforcer cannot be null");
+ }
+
+ /**
+ * Get the enforcer function for applying metadata policy for an item.
+ *
+ * @return policy enforcer
+ */
+ @Nonnull public BiFunction<Object, MetadataPolicy, Pair<Object, Boolean>> getMetadataPolicyEnforcer() {
+ checkComponentActive();
+ assert metadataPolicyEnforcer != null;
+ return metadataPolicyEnforcer;
+ }
+
+ /**
+ * Set the list of claim names who are transformed from a space-separated String into a List.
+ *
+ * @param list list of claim names
+ */
+ public void setArraysAsSpaceSeparatedList(@Nonnull final List<String> list) {
+ checkSetterPreconditions();
+ arraysAsSpaceSeparatedList = Constraint.isNotNull(list, "ArraysAsSpaceSeparatedList cannot be null");
+ }
+
+ /**
+ * Get the list of claim names who are transformed from a space-separated String into a List.
+ *
+ * @return list of claim names
+ */
+ @Nonnull public List<String> getArraysAsSpaceSeparatedList() {
+ checkComponentActive();
+ return arraysAsSpaceSeparatedList;
+ }
+
+ /**
+ * Set the condition used to validate metadata for an entity type.
+ *
+ * @param condition validation condition
+ */
+ public void setMetadataValidationCondition(@Nonnull final BiPredicate<String,Map<String,Object>> condition) {
+ checkSetterPreconditions();
+ metadataValidationCondition = Constraint.isNotNull(condition, "MetadataValidationCondition cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+
+ if (metadataPolicyMergingStrategy == null) {
+ throw new ComponentInitializationException("MetadataPolicyMergingStrategy cannot be null");
+ }
+ if (metadataPolicyEnforcer == null) {
+ throw new ComponentInitializationException("MetadataPolicyEnforcer cannot be null");
+ }
+ if (metadataValidationCondition == null) {
+ throw new ComponentInitializationException("MetadataValidationCondition cannot be null");
+ }
+ }
+
+ /**
+ * Populates the given policy compliant trust chains with the given trust chain if its metadata is policy compliant.
+ *
+ * @param chain the trust chain to be evaluated
+ * @param policyCompliantChains the list of policy-compliant trust chains to be populated
+ * @return error event ID if metadata policy merging or enforcement failed, null otherwise
+ */
+ @Nullable protected String populatePolicyComplaintChains(@Nonnull final List<EntityStatement> chain,
+ @Nonnull List<Pair<List<EntityStatement>, Map<String,Map<String,Object>>>> policyCompliantChains) {
+ final Map<String,Map<String,Object>> metadata = getMetadataLookupStrategy().apply(chain);
+ log.trace("{} Metadata resolved via lookup strategy: {}", getLogPrefix(), metadata);
+ if (metadata != null) {
+ final Map<String,Map<String,Object>> verifiedMetadata = new HashMap<>();
+ for (final String entityType : metadata.keySet()) {
+ final Map<String, MetadataPolicy> mergedPolicies;
+ try {
+ mergedPolicies = getMetadataPolicyMergingStrategy().apply(chain, entityType);
+ log.debug("{} Merged policy for type {} for chain {}", getLogPrefix(), entityType, mergedPolicies);
+ } catch (final ConstraintViolationException e) {
+ log.warn("{} Could not merge metadata policies", getLogPrefix(), e);
+ return OidFederationEventIds.INVALID_METADATA_POLICY;
+ }
+
+ final JSONObject requestMetadata = new JSONObject(metadata.get(entityType));
+ for (final String claim : mergedPolicies.keySet()) {
+ assert claim != null;
+ final MetadataPolicy policy = mergedPolicies.get(claim);
+ try {
+ final Object enforcedValue = enforceValue(claim, requestMetadata.get(claim), policy);
+ requestMetadata.put(claim, enforcedValue);
+ } catch (final ConstraintViolationException e) {
+ log.warn("{} The requested metadata is not compliant with the policy", getLogPrefix());
+ return OidFederationEventIds.INVALID_METADATA_AGAINST_POLICY;
+ }
+ }
+
+ log.debug("{} The requested metadata is compliant with the policy", getLogPrefix());
+ if (metadataValidationCondition.test(entityType, requestMetadata)) {
+ verifiedMetadata.put(entityType, requestMetadata);
+ log.debug("{} Policy-enforced metadata {}", getLogPrefix(), requestMetadata.toJSONString());
+ } else {
+ log.warn("{} Metadata validation failed for {} for entity type {}", getLogPrefix(),
+ chain.get(0).getEntityID(), entityType);
+ }
+ }
+ policyCompliantChains.add(new Pair<>(chain, verifiedMetadata));
+ log.debug("{} Policy-enforced metadata {}", getLogPrefix(), verifiedMetadata);
+ return null;
+ }
+ return EventIds.INVALID_MSG_CTX;
+ }
+
+ /**
+ * Enforces the given value with the given metadata policy.
+ *
+ * @param claim name of the claim to be enforced
+ * @param value value of the claim
+ * @param policy the metadata policy to be used for enforcing
+ * @return the enforced value
+ * @throws ConstraintViolationException if the operation was not successful
+ */
+ @Nullable protected Object enforceValue(@Nonnull final String claim, @Nullable final Object value,
+ @Nullable final MetadataPolicy policy) throws ConstraintViolationException {
+ log.debug("{} Claim {} set in policy included in the request: {}", getLogPrefix(), claim,
+ value == null);
+ final Object enforcerInput = FederationMetadataPolicyHelper.transformSpaceSeparatedStringIntoList(
+ arraysAsSpaceSeparatedList, claim, value);
+
+ final Pair<Object,Boolean> mergeResult = getMetadataPolicyEnforcer().apply(enforcerInput, policy);
+ final Boolean enforcerResult = mergeResult != null ? mergeResult.getSecond() : null;
+ if (enforcerResult == null || !enforcerResult.booleanValue()) {
+ throw new ConstraintViolationException("Metadata claim " + claim + " is not compliant with the policy");
+ }
+ log.trace("{} Validation result is OK for claim {}", getLogPrefix(), claim);
+ return Optional.ofNullable(mergeResult)
+ .map(pair -> pair.getFirst())
+ .map(result -> FederationMetadataPolicyHelper.transformListIntoSpaceSeparatedString(
+ arraysAsSpaceSeparatedList,claim, result))
+ .orElse(null);
+ }
+
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/AutoRegisteredTrustChainAuthorizationCodeClaimsSetDecorator.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/AutoRegisteredTrustChainAuthorizationCodeClaimsSetDecorator.java
new file mode 100644
index 0000000..bb948c0
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/AutoRegisteredTrustChainAuthorizationCodeClaimsSetDecorator.java
@@ -0,0 +1,75 @@
+/*
+ * 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.oidfed.profile.impl;
+
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.navigate.DefaultSelectedTrustChainIDsLookupStrategy;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.support.ClaimsSetExtensionSupport;
+import net.shibboleth.idp.plugin.oidc.op.profile.AuthorizationCodeClaimsSetDecorator;
+import net.shibboleth.shared.component.AbstractIdentifiableInitializableComponent;
+import net.shibboleth.shared.logic.Constraint;
+
+/**
+ * The decorator that adds a custom claim {@link ClaimsSetExtensionSupport#KEY_AUTO_REGISTERED_TRUST_CHAIN} to the
+ * builder if a value was resolved via {@link #selectedTrustChainIDsLookupStrategy}.
+ */
+public class AutoRegisteredTrustChainAuthorizationCodeClaimsSetDecorator extends AbstractIdentifiableInitializableComponent
+ implements AuthorizationCodeClaimsSetDecorator {
+
+ /** The strategy used to locate IDs for the selected trust chain. */
+ @Nonnull private Function<ProfileRequestContext,List<String>> selectedTrustChainIDsLookupStrategy;
+
+ /**
+ * Constructor.
+ */
+ public AutoRegisteredTrustChainAuthorizationCodeClaimsSetDecorator() {
+ selectedTrustChainIDsLookupStrategy = new DefaultSelectedTrustChainIDsLookupStrategy();
+ }
+
+ /**
+ * Set the lookup strategy used to locate IDs for the selected trust chain.
+ *
+ * @param strategy What to set
+ */
+ public void setSelectedTrustChainIDsLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext, List<String>> strategy) {
+ checkSetterPreconditions();
+
+ selectedTrustChainIDsLookupStrategy = Constraint.isNotNull(strategy,
+ "SelectedTrustChainIDsLookupStrategy lookup strategy cannot be null");
+ }
+ /** {@inheritDoc} */
+ @Override
+ public void accept(@Nullable final Map<String, Object> claimsSet,
+ @Nullable final ProfileRequestContext profileRequestContext) {
+ checkComponentActive();
+ if (claimsSet != null) {
+ final List<String> trustChainIds = selectedTrustChainIDsLookupStrategy.apply(profileRequestContext);
+ if (trustChainIds != null && !trustChainIds.isEmpty()) {
+ claimsSet.put(ClaimsSetExtensionSupport.KEY_AUTO_REGISTERED_TRUST_CHAIN, trustChainIds);
+ }
+
+ }
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/AutoRegisteredTrustChainRequestUriClaimsSetDecorator.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/AutoRegisteredTrustChainRequestUriClaimsSetDecorator.java
new file mode 100644
index 0000000..29ef55d
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/AutoRegisteredTrustChainRequestUriClaimsSetDecorator.java
@@ -0,0 +1,73 @@
+/*
+ * 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.oidfed.profile.impl;
+
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.navigate.DefaultSelectedTrustChainIDsLookupStrategy;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.support.ClaimsSetExtensionSupport;
+import net.shibboleth.idp.plugin.oidc.op.profile.RequestUriClaimsSetDecorator;
+import net.shibboleth.shared.component.AbstractIdentifiableInitializableComponent;
+import net.shibboleth.shared.logic.Constraint;
+
+/**
+ *
+ */
+public class AutoRegisteredTrustChainRequestUriClaimsSetDecorator extends AbstractIdentifiableInitializableComponent
+ implements RequestUriClaimsSetDecorator {
+
+ /** The strategy used to locate IDs for the selected trust chain. */
+ @Nonnull private Function<ProfileRequestContext,List<String>> selectedTrustChainIDsLookupStrategy;
+
+ /**
+ * Constructor.
+ */
+ public AutoRegisteredTrustChainRequestUriClaimsSetDecorator() {
+ selectedTrustChainIDsLookupStrategy = new DefaultSelectedTrustChainIDsLookupStrategy();
+ }
+
+ /**
+ * Set the lookup strategy used to locate IDs for the selected trust chain.
+ *
+ * @param strategy What to set
+ */
+ public void setSelectedTrustChainIDsLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext, List<String>> strategy) {
+ checkSetterPreconditions();
+
+ selectedTrustChainIDsLookupStrategy = Constraint.isNotNull(strategy,
+ "SelectedTrustChainIDsLookupStrategy lookup strategy cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void accept(@Nullable final Map<String, Object> claimsSet,
+ @Nullable final ProfileRequestContext profileRequestContext) {
+ checkComponentActive();
+
+ final List<String> trustChainIds = selectedTrustChainIDsLookupStrategy.apply(profileRequestContext);
+ if (trustChainIds != null && !trustChainIds.isEmpty()) {
+ claimsSet.put(ClaimsSetExtensionSupport.KEY_AUTO_REGISTERED_TRUST_CHAIN, trustChainIds);
+ }
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/BuildEntityConfiguration.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/BuildEntityConfiguration.java
new file mode 100644
index 0000000..c58a301
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/BuildEntityConfiguration.java
@@ -0,0 +1,148 @@
+/*
+ * 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.oidfed.profile.impl;
+
+import java.time.Duration;
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+
+import org.opensaml.profile.action.EventIds;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.opensaml.security.credential.Credential;
+import org.slf4j.Logger;
+
+import com.nimbusds.jose.jwk.JWK;
+import com.nimbusds.jose.jwk.JWKSet;
+import com.nimbusds.jwt.JWTClaimsSet;
+
+import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.navigate.EntityStatementLifetimeLookupFunction;
+import net.shibboleth.idp.profile.IdPEventIds;
+import net.shibboleth.oidc.profile.config.navigate.JWTSignatureSigningConfigurationLookupFunction;
+import net.shibboleth.oidc.security.CredentialConversionUtil;
+import net.shibboleth.oidc.security.jose.SignatureSigningConfiguration;
+import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
+import net.shibboleth.shared.collection.CollectionSupport;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+import org.opensaml.profile.action.ActionSupport;
+
+/**
+ * Action that creates an Entity Statement, and stores it to an {@link EntityStatementContext}.
+ *
+ * @event {@link EventIds#PROCEED_EVENT_ID}
+ * @event {@link EventIds#INVALID_PROFILE_CTX}
+ * @event {@link EventIds#IO_ERROR}
+ * @event {@link IdPEventIds#INVALID_PROFILE_CONFIG}
+ *
+ * @since 4.3.0
+ */
+public class BuildEntityConfiguration extends AbstractBuildEntityStatementAction {
+
+ /** Class logger. */
+ @Nonnull private Logger log = LoggerFactory.getLogger(BuildEntityConfiguration.class);
+
+ /** Strategy used to locate the {@link SignatureSigningConfiguration}s to fetch JWK set from. */
+ @Nonnull private
+ Function<ProfileRequestContext,List<SignatureSigningConfiguration>> signingConfigurationsLookupStrategy;
+
+ /** Strategy used to obtain the entity statement lifetime. */
+ @Nonnull private Function<ProfileRequestContext,Duration> entityConfigurationLifetimeLookupStrategy;
+
+ /** Metadata to publish. */
+ @NonnullBeforeExec private Map<String,Map<String,Object>> metadata;
+
+ /** Constructor. */
+ public BuildEntityConfiguration() {
+ signingConfigurationsLookupStrategy = new JWTSignatureSigningConfigurationLookupFunction();
+ entityConfigurationLifetimeLookupStrategy = new EntityStatementLifetimeLookupFunction();
+ }
+
+ /**
+ * Set the strategy used to obtain the entity configuration lifetime.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setEntityConfigurationLifetimeLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext,Duration> strategy) {
+ ifInitializedThrowUnmodifiabledComponentException();
+
+ entityConfigurationLifetimeLookupStrategy =
+ Constraint.isNotNull(strategy, "Entity configuration lifetime lookup strategy cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+ if (!super.doPreExecute(profileRequestContext)) {
+ return false;
+ }
+
+ metadata = entityStatementCtx.getMetadata();
+ if (metadata == null) {
+ log.error("{} Could not resolve provider metadata", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
+ return false;
+ }
+
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected boolean populateClaimsSetBuilder(@Nonnull final JWTClaimsSet.Builder builder,
+ @Nonnull final ProfileRequestContext profileRequestContext) {
+ final List<SignatureSigningConfiguration> signingConfigurations =
+ signingConfigurationsLookupStrategy.apply(profileRequestContext);
+ if (signingConfigurations == null || signingConfigurations.isEmpty()) {
+ log.error("{} Could not fetch any signature signing configurations", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, IdPEventIds.INVALID_PROFILE_CONFIG);
+ return false;
+ }
+
+ final List<JWK> jwks = new ArrayList<>();
+ for (final SignatureSigningConfiguration signingConfiguration : signingConfigurations) {
+ for (final Credential credential : signingConfiguration.getSigningCredentials()) {
+ final JWK jwk = CredentialConversionUtil.credentialToKey(credential);
+ if (jwk != null) {
+ jwks.add(jwk);
+ log.debug("{} Included {} to the keyset", getLogPrefix(), jwk.toJSONString());
+ }
+ }
+ }
+
+ final Duration lifetime = entityConfigurationLifetimeLookupStrategy.apply(profileRequestContext);
+ if (lifetime == null) {
+ log.error("{} No lifetime supplied for entity statement", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, IdPEventIds.INVALID_PROFILE_CONFIG);
+ return false;
+ }
+ final Instant now = Instant.now();
+ final Instant dateExp = now.plus(lifetime);
+ assert dateExp != null;
+
+ builder.expirationTime(Date.from(dateExp));
+ builder.claim("jwks", new JWKSet(jwks).toJSONObject(true));
+ builder.claim("metadata", CollectionSupport.copyToMap(metadata));
+ return true;
+ }
+
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/BuildExplicitRegistrationResponse.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/BuildExplicitRegistrationResponse.java
new file mode 100644
index 0000000..77742f8
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/BuildExplicitRegistrationResponse.java
@@ -0,0 +1,223 @@
+/*
+ * 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.oidfed.profile.impl;
+
+import java.time.Instant;
+import java.util.Date;
+import java.util.List;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+
+import org.opensaml.messaging.context.navigate.ChildContextLookup;
+import org.opensaml.profile.action.ActionSupport;
+import org.opensaml.profile.action.EventIds;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.opensaml.profile.context.navigate.InboundMessageContextLookup;
+import org.opensaml.profile.context.navigate.OutboundMessageContextLookup;
+import org.slf4j.Logger;
+
+import com.nimbusds.jose.jwk.JWKSet;
+import com.nimbusds.jwt.JWTClaimsSet;
+import com.nimbusds.openid.connect.sdk.rp.OIDCClientInformation;
+
+import net.shibboleth.idp.plugin.oidc.op.messaging.context.OIDCClientRegistrationResponseContext;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.navigate.DefaultSelectedTrustChainImmediateSuperiorLookupStrategy;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.navigate.DefaultSelectedTrustChainTrustAnchorLookupStrategy;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.navigate.ExplicitClientRegistrationRequestJWKSetLookupFunction;
+import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
+import net.shibboleth.shared.collection.CollectionSupport;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.primitive.StringSupport;
+
+/**
+ * An action that uses the information from {@link OIDCClientRegistrationResponseContext} attached to the message
+ * context for creating a new JWT to be used for creating a response to OpenID Federation Explicit Registration.
+ */
+public class BuildExplicitRegistrationResponse extends AbstractBuildEntityStatementAction {
+
+ /** Class logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(BuildExplicitRegistrationResponse.class);
+
+ /**
+ * Strategy used to locate the {@link OIDCClientRegistrationResponseContext}.
+ */
+ @Nonnull private Function<ProfileRequestContext,OIDCClientRegistrationResponseContext> oidcResponseContextLookupStrategy;
+
+ /** Strategy used to locate the JWK set to be included in the response entity statement. */
+ @Nonnull private Function<ProfileRequestContext,JWKSet> jwkSetLookupStrategy;
+
+ /** Strategy used to lookup the trust chain context. */
+ @Nonnull private Function<ProfileRequestContext, RelyingPartyTrustChainContext> trustChainContextLookupStrategy;
+
+ /** Strategy used to lookup the trust anchor. */
+ @Nonnull private Function<ProfileRequestContext, String> trustAnchorLookupStrategy;
+
+ /** Strategy used to lookup the immediate superior used for the authority_hints claim. */
+ @Nonnull private Function<ProfileRequestContext, String> immediateSuperiorLookupStrategy;
+
+ /** The {@link OIDCClientRegistrationResponseContext} to operate on. */
+ @NonnullBeforeExec private OIDCClientRegistrationResponseContext oidcResponseContext;
+
+ /** Trust chain context to operate on. */
+ @NonnullBeforeExec private RelyingPartyTrustChainContext trustChainContext;
+
+ /** Constructor. */
+ public BuildExplicitRegistrationResponse() {
+ final Function<ProfileRequestContext, OIDCClientRegistrationResponseContext> ocrrls =
+ new ChildContextLookup<>(OIDCClientRegistrationResponseContext.class)
+ .compose(new OutboundMessageContextLookup());
+ assert ocrrls != null;
+ oidcResponseContextLookupStrategy = ocrrls;
+ jwkSetLookupStrategy = new ExplicitClientRegistrationRequestJWKSetLookupFunction();
+ final Function<ProfileRequestContext, RelyingPartyTrustChainContext> tcls =
+ new ChildContextLookup<>(RelyingPartyTrustChainContext.class).compose(
+ new InboundMessageContextLookup());
+ assert tcls != null;
+ trustChainContextLookupStrategy = tcls;
+ trustAnchorLookupStrategy = new DefaultSelectedTrustChainTrustAnchorLookupStrategy();
+ immediateSuperiorLookupStrategy = new DefaultSelectedTrustChainImmediateSuperiorLookupStrategy();
+ }
+
+ /**
+ * Set the strategy used to locate the {@link OIDCClientRegistrationResponseContext}.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setOidcResponseContextLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext,OIDCClientRegistrationResponseContext> strategy) {
+ ifInitializedThrowUnmodifiabledComponentException();
+
+ oidcResponseContextLookupStrategy = Constraint.isNotNull(strategy,
+ "OIDCClientRegistrationResponseContext lookup strategy cannot be null");
+ }
+
+ /**
+ * Set the strategy used to locate the JWK set to be included in the response entity statement.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setJwkSetLookupStrategy(@Nonnull final Function<ProfileRequestContext,JWKSet> strategy) {
+ checkSetterPreconditions();
+ jwkSetLookupStrategy = Constraint.isNotNull(strategy, "JWK set loookup strategy cannot be null");
+ }
+
+ /**
+ * Set the strategy used to lookup the trust chain context.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setTrustChainContextLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext, RelyingPartyTrustChainContext> strategy) {
+ checkSetterPreconditions();
+ trustChainContextLookupStrategy =
+ Constraint.isNotNull(strategy, "TrustChainContextLookupStrategy cannot be null");
+ }
+
+ /**
+ * Set the strategy used to lookup the trust anchor.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setTrustAnchorLookupStrategy(@Nonnull final Function<ProfileRequestContext, String> strategy) {
+ checkSetterPreconditions();
+ trustAnchorLookupStrategy = Constraint.isNotNull(strategy, "TrustAnchorLookupStrategy cannot be null");
+ }
+
+ /**
+ * Set the strategy used to lookup the immediate superior used for the authority_hints claim.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setImmediateSuperiorLookupStrategy(@Nonnull final Function<ProfileRequestContext, String> strategy) {
+ checkSetterPreconditions();
+ immediateSuperiorLookupStrategy =
+ Constraint.isNotNull(strategy, "ImmediateSuperiorLookupStrategy cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+ if (!super.doPreExecute(profileRequestContext)) {
+ return false;
+ }
+
+ oidcResponseContext = oidcResponseContextLookupStrategy.apply(profileRequestContext);
+ if (oidcResponseContext == null) {
+ log.debug("{} No OIDCClientRegistrationResponseContext associated with this profile request",
+ getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
+ return false;
+ }
+
+ trustChainContext = trustChainContextLookupStrategy.apply(profileRequestContext);
+ if (trustChainContext == null) {
+ log.error("{} Unable to locate trust chain context", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MSG_CTX);
+ return false;
+ }
+
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected boolean populateClaimsSetBuilder(@Nonnull final JWTClaimsSet.Builder builder,
+ @Nonnull final ProfileRequestContext profileRequestContext) {
+ final OIDCClientInformation clientInformation = oidcResponseContext.getClientInformation();
+ if (clientInformation == null) {
+ log.debug("{} No client information set in the OIDC response context", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
+ return false;
+ }
+ builder.claim("metadata",
+ CollectionSupport.singletonMap("openid_relying_party", clientInformation.toJSONObject()));
+
+ final JWKSet jwkSet = jwkSetLookupStrategy.apply(profileRequestContext);
+ if (jwkSet == null) {
+ log.error("{} Coud not resolve JWK set to be included in the response statement", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MSG_CTX);
+ return false;
+ }
+ builder.claim("jwks", jwkSet.toJSONObject(true));
+
+ final Instant expirationTime = trustChainContext.getSelectedMetadataExpiration();
+ if (expirationTime == null) {
+ log.error("{} Coud not resolve expiration time from the selected trust chain context", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MSG_CTX);
+ return false;
+ }
+ builder.expirationTime(Date.from(expirationTime));
+
+ final String trustAnchor = trustAnchorLookupStrategy.apply(profileRequestContext);
+ if (StringSupport.trimOrNull(trustAnchor) == null) {
+ log.error("{} Unable to locate trust anchor from the context", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MSG_CTX);
+ return false;
+ }
+ builder.claim("trust_anchor", trustAnchor);
+
+ final String superior = immediateSuperiorLookupStrategy.apply(profileRequestContext);
+ if (StringSupport.trimOrNull(superior) == null) {
+ log.error("{} Unable to locate immediate superior from the context", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MSG_CTX);
+ return false;
+ }
+ builder.claim("authority_hints", List.of(superior));
+
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/BuildResolveEntityErrorResponseFromEvent.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/BuildResolveEntityErrorResponseFromEvent.java
new file mode 100644
index 0000000..c5c5b58
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/BuildResolveEntityErrorResponseFromEvent.java
@@ -0,0 +1,269 @@
+/*
+ * 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.oidfed.profile.impl;
+
+import java.time.Duration;
+import java.time.Instant;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+
+import org.opensaml.messaging.context.navigate.ChildContextLookup;
+import org.opensaml.profile.context.EventContext;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.opensaml.profile.context.navigate.CurrentOrPreviousEventLookup;
+import org.opensaml.profile.context.navigate.InboundMessageContextLookup;
+import org.slf4j.Logger;
+
+import com.nimbusds.oauth2.sdk.ErrorObject;
+import com.nimbusds.oauth2.sdk.ErrorResponse;
+import com.nimbusds.oauth2.sdk.http.HTTPResponse;
+
+import net.shibboleth.idp.plugin.oidc.op.oidfed.config.CachedErrorResponseLifetimeLookupFunction;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.messaging.impl.ResolveEntityRequest;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.NimbusResponseCriterion;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.ResolveEntityRequestCriterion;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.ResolveEntityResponseContainer;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.ResponseContainerExpirationCriterion;
+import net.shibboleth.idp.profile.AbstractProfileAction;
+import net.shibboleth.oidc.metadata.cache.MetadataCache;
+import net.shibboleth.oidc.metadata.cache.MetadataCacheException;
+import net.shibboleth.oidc.profile.messaging.JSONErrorResponse;
+import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.resolver.CriteriaSet;
+
+/**
+ * This action reads an event from the configured {@link EventContext} lookup strategy, constructs a JSON error response
+ * message and attaches it as the outbound message. If {@link RelyingPartyCachedMessageContext} is found, it's exploited
+ * for storing the response message in the configured {@link #responseCache}.
+ */
+public class BuildResolveEntityErrorResponseFromEvent extends AbstractProfileAction {
+
+ /** Default value for the error code in the error response messages. */
+ public static final String DEFAULT_ERROR_CODE = "invalid_request";
+
+ /** Default value for the HTTP response status code in the HTTP responses. */
+ public static final int DEFAULT_HTTP_STATUS_CODE = HTTPResponse.SC_BAD_REQUEST;
+
+ /** Class logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(BuildResolveEntityErrorResponseFromEvent.class);
+
+ /** Strategy function for access to {@link EventContext} to check. */
+ @Nonnull
+ private Function<ProfileRequestContext, EventContext> eventContextLookupStrategy;
+
+ /** Map of eventIds to pre-configured error objects. */
+ private Map<String, ErrorObject> mappedErrors;
+
+ /** The status code for unmapped events. */
+ private int defaultStatusCode;
+
+ /** The code for unmapped events. */
+ private String defaultCode;
+
+ /** Metadata cache for cached response containers. */
+ @NonnullAfterInit private MetadataCache<ResolveEntityResponseContainer> responseCache;
+
+ /** Strategy used to locate the lifetime for the cached response record. */
+ @Nonnull private Function<ProfileRequestContext,Duration> cachedResponseLifetimeLookupStrategy;
+
+ /** Strategy used to locate the resolve entity context. */
+ @Nonnull
+ private Function<ProfileRequestContext, RelyingPartyCachedMessageContext> resolveEntityContextLookupStrategy;
+
+ /**
+ * Constructor.
+ */
+ public BuildResolveEntityErrorResponseFromEvent() {
+ eventContextLookupStrategy = new CurrentOrPreviousEventLookup();
+ mappedErrors = new HashMap<>();
+ defaultStatusCode = DEFAULT_HTTP_STATUS_CODE;
+ defaultCode = DEFAULT_ERROR_CODE;
+ cachedResponseLifetimeLookupStrategy = new CachedErrorResponseLifetimeLookupFunction();
+ final Function<ProfileRequestContext, RelyingPartyCachedMessageContext> recls =
+ new ChildContextLookup<>(RelyingPartyCachedMessageContext.class).compose(
+ new InboundMessageContextLookup());
+ assert recls != null;
+ resolveEntityContextLookupStrategy = recls;
+
+ }
+
+ /**
+ * Set the status code for unmapped events.
+ *
+ * @param code The default status code for unmapped events.
+ */
+ public void setDefaultStatusCode(final int code) {
+ defaultStatusCode = code;
+ }
+
+ /**
+ * Set the code for unmapped events.
+ *
+ * @param code The default status code for unmapped events.
+ */
+ public void setDefaultCode(@Nonnull final String code) {
+ defaultCode = Constraint.isNotNull(code, "Default code cannot be null");
+ }
+
+ /**
+ * Set lookup strategy for {@link EventContext} to check.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setEventContextLookupStrategy(@Nonnull final Function<ProfileRequestContext, EventContext> strategy) {
+ ifInitializedThrowUnmodifiabledComponentException();
+
+ eventContextLookupStrategy = Constraint.isNotNull(strategy, "EventContext lookup strategy cannot be null");
+ }
+
+ /**
+ * Set map of eventIds to pre-configured error objects.
+ *
+ * @param errors map of eventIds to pre-configured error objects.
+ */
+ public void setMappedErrors(@Nonnull final Map<String, ErrorObject> errors) {
+ ifInitializedThrowUnmodifiabledComponentException();
+
+ mappedErrors = Constraint.isNotNull(errors, "Mapped errors cannot be null");
+ }
+
+ /**
+ * Set the metadata cache for cached response containers.
+ *
+ * @param cache What to set.
+ */
+ public void setResponseCache(@Nonnull final MetadataCache<ResolveEntityResponseContainer> cache) {
+ checkSetterPreconditions();
+ responseCache = Constraint.isNotNull(cache, "Response metadata cache cannot be null");
+ }
+
+ /**
+ * Set the strategy used to locate the lifetime for the cached response record.
+ *
+ * @param strategy What to set.
+ */
+ public void setCachedResponseLifetimeLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext, Duration> strategy) {
+ checkSetterPreconditions();
+ cachedResponseLifetimeLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null");
+ }
+
+ /**
+ * Set the strategy used to locate the resolve entity context
+ *
+ * @param strategy What to set.
+ */
+ public void setResolveEntityContextLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext,RelyingPartyCachedMessageContext> strategy) {
+ checkSetterPreconditions();
+ resolveEntityContextLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null!");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+
+ if (responseCache == null) {
+ throw new ComponentInitializationException("Response metadata cache cannot be null");
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+
+ if (!super.doPreExecute(profileRequestContext)) {
+ return false;
+ }
+
+ if (profileRequestContext.getOutboundMessageContext() == null) {
+ log.debug("{} No outbound message context initialized, nothing to do", getLogPrefix());
+ return false;
+ }
+
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+ final EventContext eventCtx = eventContextLookupStrategy.apply(profileRequestContext);
+ if (eventCtx == null || eventCtx.getEvent() == null) {
+ log.error("{} No event to be included in the response, nothing to do", getLogPrefix());
+ return;
+ }
+ assert eventCtx != null;
+ final Object event = eventCtx.getEvent();
+ assert event != null;
+ final String eventValue = event.toString();
+ final ErrorObject error;
+ if (mappedErrors.containsKey(eventValue)) {
+ log.debug("{} Found mapped event for {}", getLogPrefix(), eventValue);
+ error = mappedErrors.get(eventValue);
+ } else {
+ log.debug("{} No mapped event found for {}, creating general {}", getLogPrefix(), eventValue, defaultCode);
+ error = new ErrorObject(defaultCode, eventValue, defaultStatusCode);
+ }
+ assert error != null;
+ final ErrorResponse errorResponse = buildErrorResponse(error, profileRequestContext);
+ if (errorResponse != null) {
+ profileRequestContext.ensureOutboundMessageContext().setMessage(errorResponse);
+ log.debug("{} ErrorResponse successfully set as the outbound message", getLogPrefix());
+ } else {
+ log.debug("{} Error response not formed", getLogPrefix());
+ }
+ }
+
+ protected JSONErrorResponse buildErrorResponse(final ErrorObject error,
+ final ProfileRequestContext profileRequestContext) {
+ final JSONErrorResponse response = new JSONErrorResponse(error);
+ final RelyingPartyCachedMessageContext resolveEntityContext =
+ resolveEntityContextLookupStrategy.apply(profileRequestContext);
+
+ if (resolveEntityContext != null &&
+ resolveEntityContext.getValidatedRequest() instanceof ResolveEntityRequest resolveEntityRequest) {
+ final NimbusResponseCriterion responseCriterion = new NimbusResponseCriterion(response);
+ final Duration cachedResponseLifetime = cachedResponseLifetimeLookupStrategy.apply(profileRequestContext);
+ final Instant expiration = Instant.now().plus(cachedResponseLifetime);
+ assert expiration != null;
+ final ResponseContainerExpirationCriterion expirationCriterion =
+ new ResponseContainerExpirationCriterion(expiration);
+ final ResolveEntityRequestCriterion requestCriterion =
+ new ResolveEntityRequestCriterion(resolveEntityRequest);
+ final CriteriaSet criteria = new CriteriaSet(requestCriterion, responseCriterion, expirationCriterion);
+ try {
+ final List<ResolveEntityResponseContainer> result = responseCache.get(criteria);
+ if (result.size() != 1) {
+ log.error("{} Unexpected result (size={}) when storing response record into the metadata cache",
+ getLogPrefix(), result.size());
+ } else {
+ log.debug("{} Response stored into the cache", getLogPrefix());
+ }
+ } catch (final MetadataCacheException e) {
+ log.error("{} Could not store the response record into the metadata cache", getLogPrefix(), e);
+ }
+ }
+
+ return response;
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/BuildResolveEntityResponse.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/BuildResolveEntityResponse.java
new file mode 100644
index 0000000..a17184a
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/BuildResolveEntityResponse.java
@@ -0,0 +1,226 @@
+/*
+ * 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.oidfed.profile.impl;
+
+import java.text.ParseException;
+import java.time.Instant;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.messaging.context.navigate.ChildContextLookup;
+import org.opensaml.profile.action.ActionSupport;
+import org.opensaml.profile.action.EventIds;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.opensaml.profile.context.navigate.InboundMessageContextLookup;
+import org.slf4j.Logger;
+
+import com.nimbusds.jwt.JWTClaimsSet;
+import com.nimbusds.jwt.SignedJWT;
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.navigate.DefaultEntityTypesLookupFunction;
+import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
+import net.shibboleth.shared.collection.Pair;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+/**
+ * An action that uses the information from {@link RelyingPartyTrustChainContext} for creating a new JWT to be used for
+ * creating a response to OpenID Federation Resolve Entity API.
+ */
+public class BuildResolveEntityResponse extends AbstractBuildEntityStatementAction {
+
+ /** Class logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(BuildResolveEntityResponse.class);
+
+ /** Strategy used to lookup the trust chain context. */
+ @Nonnull private Function<ProfileRequestContext, RelyingPartyTrustChainContext> trustChainContextLookupStrategy;
+
+ /** Strategy used to lookup the entity types included in the response metadata. */
+ @Nonnull private Function<ProfileRequestContext, List<String>> entityTypesLookupStrategy;
+
+ /** Trust chain context to operate on. */
+ @NonnullBeforeExec private RelyingPartyTrustChainContext trustChainContext;
+
+ /** Constructor. */
+ public BuildResolveEntityResponse() {
+ final Function<ProfileRequestContext, RelyingPartyTrustChainContext> tcls =
+ new ChildContextLookup<>(RelyingPartyTrustChainContext.class).compose(
+ new InboundMessageContextLookup());
+ assert tcls != null;
+ trustChainContextLookupStrategy = tcls;
+ entityTypesLookupStrategy = new DefaultEntityTypesLookupFunction();
+ }
+
+ /**
+ * Set the strategy used to lookup the trust chain context.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setTrustChainContextLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext, RelyingPartyTrustChainContext> strategy) {
+ checkSetterPreconditions();
+ trustChainContextLookupStrategy =
+ Constraint.isNotNull(strategy, "TrustChainContextLookupStrategy cannot be null");
+ }
+
+ /**
+ * Set the strategy used to lookup the entity types included in the response metadata.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setEntityTypesLookupStrategy(@Nonnull final Function<ProfileRequestContext, List<String>> strategy) {
+ checkSetterPreconditions();
+ entityTypesLookupStrategy = Constraint.isNotNull(strategy, "EntityTypesLookupStrategy cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+ if (!super.doPreExecute(profileRequestContext)) {
+ return false;
+ }
+
+ trustChainContext = trustChainContextLookupStrategy.apply(profileRequestContext);
+ if (trustChainContext == null) {
+ log.error("{} Unable to locate trust chain context", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MSG_CTX);
+ return false;
+ }
+
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected boolean populateClaimsSetBuilder(@Nonnull final JWTClaimsSet.Builder builder,
+ @Nonnull final ProfileRequestContext profileRequestContext) {
+ final Pair<List<EntityStatement>,Map<String,Map<String,Object>>> selectedTrustChain =
+ trustChainContext.getSelectedTrustChain();
+ if (selectedTrustChain == null) {
+ log.debug("{} No selected trust chain found form the context", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, OidFederationEventIds.INVALID_METADATA);
+ return false;
+ }
+ final Map<String,Map<String,Object>> metadata = selectedTrustChain.getSecond();
+ if (metadata == null) {
+ log.debug("{} No metadata set for the selected trust chain", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, OidFederationEventIds.INVALID_METADATA);
+ return false;
+ }
+ final List<String> entityTypes = entityTypesLookupStrategy.apply(profileRequestContext);
+ log.trace("{} The following entity types were requested: {}", getLogPrefix(), entityTypes);
+ if (entityTypes != null && !entityTypes.isEmpty()) {
+ final Map<String,Object> filteredMetadata = metadata.entrySet()
+ .stream()
+ .filter(entry -> entityTypes.contains(entry.getKey()))
+ .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
+ if (filteredMetadata.isEmpty()) {
+ log.warn("{} No metadata for entity types {} found for the selected trust chain", getLogPrefix(),
+ entityTypes);
+ ActionSupport.buildEvent(profileRequestContext, OidFederationEventIds.INVALID_METADATA);
+ return false;
+ }
+ builder.claim("metadata", filteredMetadata);
+ } else {
+ builder.claim("metadata", metadata);
+ }
+
+ final List<EntityStatement> trustChain = selectedTrustChain.getFirst();
+ if (trustChain == null || trustChain.isEmpty()) {
+ log.debug("{} No selected trust chain set in the trust chain context", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, OidFederationEventIds.INVALID_METADATA);
+ return false;
+ }
+ builder.claim("trust_chain", trustChain.stream()
+ .map(statement -> statement.getSignedStatement().serialize())
+ .toList());
+
+ final Instant expirationTime = resolveTrustChainExpiration(trustChain);
+ if (expirationTime == null) {
+ log.error("{} Coud not resolve expiration time from the selected trust chain context", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MSG_CTX);
+ return false;
+ }
+ builder.expirationTime(Date.from(expirationTime));
+
+ final String entityId = trustChain.get(0).getEntityID().getValue();
+ assert entityId != null;
+ final Map<String, String> trustMarks = buildTrustMarks(entityId, trustChainContext.getVerifiedTrustMarks());
+ if (trustMarks != null && !trustMarks.isEmpty()) {
+ builder.claim("trust_marks", trustMarks);
+ }
+ return true;
+ }
+
+ /**
+ * Builds value for the trust_marks claim in the resolve entity response entity statement.
+ *
+ * @param entityId the subject entity ID
+ * @param trustMarks trust marks for the selected trust chain
+ * @return map of trust marks, keyed with trust mark IDs
+ */
+ @Nullable private Map<String, String> buildTrustMarks(@Nonnull final String entityId,
+ @Nullable final Map<String, List<SignedJWT>> trustMarks) {
+ return Optional.ofNullable(trustMarks)
+ .map(marks -> marks.get(entityId))
+ .filter(Objects::nonNull)
+ .map(list -> list.stream()
+ .map(trustMark -> new Pair<String, String>(getTrustMarkId(trustMark), trustMark.serialize()))
+ .filter(Objects::nonNull)
+ .collect(Collectors.toMap(pair -> pair.getFirst(), pair -> pair.getSecond())))
+ .orElse(null);
+ }
+
+ /**
+ * Parses the trust mark ID for the given trust mark.
+ *
+ * @param trustMark the trust mark
+ * @return the ID, or null if it could not be parsed
+ */
+ @Nullable private String getTrustMarkId(@Nullable final SignedJWT trustMark) {
+ try {
+ return trustMark == null ? null : trustMark.getJWTClaimsSet().getStringClaim("trust_mark_id");
+ } catch (final ParseException e) {
+ log.error("{} Could not parse the TrustMark JWT contents", getLogPrefix(), e);
+ }
+ return null;
+ }
+
+ /**
+ * Resolve expiration time for the given trust chain.
+ *
+ * @param trustChain trust chain
+ * @return expiration time
+ */
+ @Nullable private Instant resolveTrustChainExpiration(@Nonnull final List<EntityStatement> trustChain) {
+ Instant metadataExpiration = null;
+ for (final EntityStatement statement : trustChain) {
+ final Instant statementExpiration = statement.getClaimsSet().getExpirationTime().toInstant();
+ metadataExpiration = metadataExpiration == null ? statementExpiration :
+ statementExpiration.isBefore(metadataExpiration) ? statementExpiration : metadataExpiration;
+ }
+ return metadataExpiration;
+ }
+
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/EntityStatementContext.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/EntityStatementContext.java
new file mode 100644
index 0000000..7eebe3a
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/EntityStatementContext.java
@@ -0,0 +1,109 @@
+/*
+ * 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.oidfed.profile.impl;
+
+import java.time.Duration;
+import java.util.Map;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.messaging.context.BaseContext;
+
+import com.nimbusds.jwt.JWT;
+
+/**
+ * Subcontext carrying information used to produce entity statements.
+ *
+ * @since 4.3.0
+ */
+public final class EntityStatementContext extends BaseContext {
+
+ /** Metadata. */
+ @Nullable private Map<String,Map<String,Object>> metadata;
+
+ /** Lifetime of the statement. */
+ @Nullable private Duration lifetime;
+
+ /** The entity statement. */
+ @Nullable private JWT jwt;
+
+ /**
+ * Get the metadata.
+ *
+ * @return the metadata
+ */
+ @Nullable public Map<String,Map<String,Object>> getMetadata() {
+ return metadata;
+ }
+
+ /**
+ * Set the metadata.
+ *
+ * @param map the metadata
+ *
+ * @return this context
+ */
+ @Nonnull public EntityStatementContext setMetadata(@Nullable final Map<String,Map<String,Object>> map) {
+ metadata = map;
+ return this;
+ }
+
+ /**
+ * Get the entity statement JWT.
+ *
+ * <p>May be in various states prior to signing.</p>
+ *
+ * @return the JWT
+ */
+ @Nullable public JWT getJWT() {
+ return jwt;
+ }
+
+ /**
+ * Set the entity statement JWT.
+ *
+ * <p>May be in various states prior to signing.</p>
+ *
+ * @param token the JWT
+ *
+ * @return this context
+ */
+ @Nonnull public EntityStatementContext setJWT(@Nullable final JWT token) {
+ jwt = token;
+ return this;
+ }
+
+ /**
+ * Get the statement lifetime.
+ *
+ * @return lifetime
+ */
+ @Nullable public Duration getLifetime() {
+ return lifetime;
+ }
+
+ /**
+ * Set the statement lifetime.
+ *
+ * @param lt lifetime
+ *
+ * @return this context
+ */
+ @Nonnull public EntityStatementContext setLifetime(@Nullable final Duration lt) {
+ lifetime = lt;
+ return this;
+ }
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/EntityStatementUpdateStrategy.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/EntityStatementUpdateStrategy.java
new file mode 100644
index 0000000..7931267
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/EntityStatementUpdateStrategy.java
@@ -0,0 +1,59 @@
+/*
+ * 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.oidfed.profile.impl;
+
+import java.util.function.BiConsumer;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+
+import org.opensaml.messaging.context.MessageContext;
+import org.opensaml.messaging.context.navigate.ChildContextLookup;
+
+import com.nimbusds.jwt.JWT;
+
+/**
+ * Add the {@link JWT} back to the {@link EntityStatementContext}.
+ *
+ * @since 4.3.0
+ */
+public class EntityStatementUpdateStrategy implements BiConsumer<JWT, MessageContext> {
+
+ /** Strategy used to locate the subcontext with the statement. */
+ @Nonnull private Function<MessageContext,EntityStatementContext> entityStatementContextLookupStrategy;
+
+ /**
+ * Constructor.
+ */
+ public EntityStatementUpdateStrategy() {
+ final Function<MessageContext,EntityStatementContext> escls =
+ new ChildContextLookup<>(EntityStatementContext.class);
+ assert escls != null;
+ entityStatementContextLookupStrategy = escls;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void accept(final JWT jwt, final MessageContext messageContext) {
+ if (messageContext == null) {
+ return;
+ }
+ final EntityStatementContext entityStatementCtx = entityStatementContextLookupStrategy.apply(messageContext);
+ if (entityStatementCtx == null) {
+ return;
+ }
+ entityStatementCtx.setJWT(jwt);
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/FormExplicitRegistrationResponse.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/FormExplicitRegistrationResponse.java
new file mode 100644
index 0000000..425971d
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/FormExplicitRegistrationResponse.java
@@ -0,0 +1,118 @@
+/*
+ * 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.oidfed.profile.impl;
+
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.messaging.context.navigate.ChildContextLookup;
+import org.opensaml.profile.action.ActionSupport;
+import org.opensaml.profile.action.EventIds;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.opensaml.profile.context.navigate.OutboundMessageContextLookup;
+import org.slf4j.Logger;
+
+import com.nimbusds.jwt.SignedJWT;
+import com.nimbusds.oauth2.sdk.ParseException;
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import net.shibboleth.idp.plugin.oidc.op.oidfed.messaging.impl.ExplicitClientRegistrationResponse;
+import net.shibboleth.idp.profile.AbstractProfileAction;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+/**
+ * This action builds a response for the OpenID federation explicit registration request. The response contains an
+ * {@link EntityStatement}.
+ *
+ * @since 4.3.0
+ */
+public class FormExplicitRegistrationResponse extends AbstractProfileAction {
+
+ /** Class logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(FormExplicitRegistrationResponse.class);
+
+ /** Strategy used to locate the subcontext to hold the statement. */
+ @Nonnull private Function<ProfileRequestContext,EntityStatementContext> entityStatementContextLookupStrategy;
+
+ /** JWT used to build entity statement. */
+ @Nullable private SignedJWT jwt;
+
+ /**
+ * Constructor.
+ */
+ public FormExplicitRegistrationResponse() {
+ final Function<ProfileRequestContext,EntityStatementContext> escls =
+ new ChildContextLookup<>(EntityStatementContext.class).compose(
+ new OutboundMessageContextLookup());
+ assert escls != null;
+ entityStatementContextLookupStrategy = escls;
+ }
+
+ /**
+ * Set the strategy used to locate the subcontext to hold the statement
+ *
+ * @param strategy What to set.
+ */
+ public void setEntityStatementContextLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext,EntityStatementContext> strategy) {
+ checkSetterPreconditions();
+ entityStatementContextLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null!");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+
+ if (!super.doPreExecute(profileRequestContext)) {
+ return false;
+ }
+ final EntityStatementContext entityStatementContext =
+ entityStatementContextLookupStrategy.apply(profileRequestContext);
+ if (entityStatementContext == null) {
+ log.error("{} Could not resolve entity statement context", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
+ return false;
+ }
+ if (entityStatementContext.getJWT() instanceof SignedJWT signedJwt) {
+ jwt = signedJwt;
+ } else {
+ log.error("{} No signed JWT found from the entity statement context", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
+ return false;
+ }
+
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+ final EntityStatement entityStatement;
+ try {
+ entityStatement = EntityStatement.parse(jwt);
+ } catch (ParseException e) {
+ log.error("{} Could not parse entity statement from JWT", getLogPrefix(), e);
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
+ return;
+ }
+ assert entityStatement != null;
+ final ExplicitClientRegistrationResponse response = new ExplicitClientRegistrationResponse(entityStatement);
+ log.debug("{} Response message set to the outbound message context", getLogPrefix());
+ profileRequestContext.ensureOutboundMessageContext().setMessage(response);
+ }
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/FormOutboundFederationConfigurationResponse.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/FormOutboundFederationConfigurationResponse.java
new file mode 100644
index 0000000..226c971
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/FormOutboundFederationConfigurationResponse.java
@@ -0,0 +1,225 @@
+/*
+ * 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.oidfed.profile.impl;
+
+import java.time.Duration;
+import java.time.Instant;
+import java.util.List;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.messaging.context.navigate.ChildContextLookup;
+import org.opensaml.profile.action.ActionSupport;
+import org.opensaml.profile.action.EventIds;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.opensaml.profile.context.navigate.OutboundMessageContextLookup;
+import org.slf4j.Logger;
+
+import com.nimbusds.jwt.SignedJWT;
+import com.nimbusds.oauth2.sdk.ParseException;
+import com.nimbusds.oauth2.sdk.Response;
+import com.nimbusds.openid.connect.sdk.federation.config.FederationEntityConfigurationSuccessResponse;
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import net.shibboleth.idp.plugin.oidc.op.oidfed.config.CachedSuccessResponseLifetimeLookupFunction;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.NimbusResponseContainer;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.NimbusResponseCriterion;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.ResponseContainerExpirationCriterion;
+import net.shibboleth.idp.profile.AbstractProfileAction;
+import net.shibboleth.oidc.metadata.cache.MetadataCache;
+import net.shibboleth.oidc.metadata.cache.MetadataCacheException;
+import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.resolver.CriteriaSet;
+
+/**
+ * This action builds a response for the OpenID federation configuration request. The response contains an
+ * {@link EntityStatement}.
+ *
+ * @since 4.3.0
+ */
+public class FormOutboundFederationConfigurationResponse extends AbstractProfileAction {
+
+ /** Class logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(FormOutboundFederationConfigurationResponse.class);
+
+ /** Metadata cache for cached response containers. */
+ @NonnullAfterInit private MetadataCache<NimbusResponseContainer> responseCache;
+
+ /** Strategy used to locate the cached message context. */
+ @Nonnull
+ private Function<ProfileRequestContext, RelyingPartyCachedMessageContext> cachedMessageContextLookupStrategy;
+
+ /** Strategy used to locate the subcontext to hold the statement. */
+ @Nonnull private Function<ProfileRequestContext,EntityStatementContext> entityStatementContextLookupStrategy;
+
+ /** Strategy used to locate the lifetime for the cached response record. */
+ @Nonnull private Function<ProfileRequestContext,Duration> cachedResponseLifetimeLookupStrategy;
+
+ /** JWT used to build entity statement. */
+ @Nullable private SignedJWT jwt;
+
+ /** The resolve entity context to operate on. */
+ @NonnullBeforeExec private RelyingPartyCachedMessageContext cachedMessageContext;
+
+ /**
+ * Constructor.
+ */
+ public FormOutboundFederationConfigurationResponse() {
+ final Function<ProfileRequestContext,EntityStatementContext> escls =
+ new ChildContextLookup<>(EntityStatementContext.class).compose(
+ new OutboundMessageContextLookup());
+ assert escls != null;
+ entityStatementContextLookupStrategy = escls;
+ cachedMessageContextLookupStrategy = new ChildContextLookup<>(RelyingPartyCachedMessageContext.class);
+ cachedResponseLifetimeLookupStrategy = new CachedSuccessResponseLifetimeLookupFunction();
+ }
+
+ /**
+ * Set the strategy used to locate the subcontext to hold the statement
+ *
+ * @param strategy What to set.
+ */
+ public void setEntityStatementContextLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext,EntityStatementContext> strategy) {
+ checkSetterPreconditions();
+ entityStatementContextLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null!");
+ }
+
+ /**
+ * Set the strategy used to locate the cached message context
+ *
+ * @param strategy What to set.
+ */
+ public void setCachedMessageContextLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext,RelyingPartyCachedMessageContext> strategy) {
+ checkSetterPreconditions();
+ cachedMessageContextLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null!");
+ }
+
+ /**
+ * Set the metadata cache for cached response containers.
+ *
+ * @param cache What to set.
+ */
+ public void setResponseCache(@Nonnull final MetadataCache<NimbusResponseContainer> cache) {
+ checkSetterPreconditions();
+ responseCache = Constraint.isNotNull(cache, "Response metadata cache cannot be null");
+ }
+
+ /**
+ * Set the strategy used to locate the lifetime for the cached response record.
+ *
+ * @param strategy What to set.
+ */
+ public void setCachedResponseLifetimeLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext, Duration> strategy) {
+ checkSetterPreconditions();
+ cachedResponseLifetimeLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+
+ if (responseCache == null) {
+ throw new ComponentInitializationException("Response metadata cache cannot be null");
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+
+ if (!super.doPreExecute(profileRequestContext)) {
+ return false;
+ }
+ cachedMessageContext = cachedMessageContextLookupStrategy.apply(profileRequestContext);
+ if (cachedMessageContext == null) {
+ log.error("{} Could not resolve cached message context", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
+ return false;
+ }
+
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+ final Response cachedResponse = cachedMessageContext.getCachedResponse();
+ if (cachedResponse != null) {
+ log.debug("{} Cached response found, storing in to the outbound message context", getLogPrefix());
+ profileRequestContext.ensureOutboundMessageContext().setMessage(cachedResponse);
+ return;
+ }
+ log.debug("{} No cached response found, resolving the response JWT from the context", getLogPrefix());
+ final EntityStatementContext entityStatementContext =
+ entityStatementContextLookupStrategy.apply(profileRequestContext);
+ if (entityStatementContext == null) {
+ log.error("{} Could not resolve entity statement context", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
+ return;
+ }
+ if (entityStatementContext.getJWT() instanceof SignedJWT signedJwt) {
+ jwt = signedJwt;
+ } else {
+ log.error("{} No signed JWT found from the entity statement context", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
+ return;
+ }
+
+ assert jwt != null;
+ final FederationEntityConfigurationSuccessResponse response;
+ try {
+ response = new FederationEntityConfigurationSuccessResponse(EntityStatement.parse(jwt));
+ } catch (ParseException e) {
+ log.error("{} No signed JWT found from the entity statement context", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
+ return;
+ }
+ final NimbusResponseCriterion responseCriterion = new NimbusResponseCriterion(response);
+ final Duration lifetime = cachedResponseLifetimeLookupStrategy.apply(profileRequestContext);
+ if (lifetime == null) {
+ log.error("{} Could not resolve lifetime for the cached response record", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
+ return;
+ }
+ final Instant expiration = Instant.now().plus(lifetime);
+ assert expiration != null;
+ final ResponseContainerExpirationCriterion expirationCriterion =
+ new ResponseContainerExpirationCriterion(expiration);
+ final CriteriaSet criteria = new CriteriaSet(responseCriterion, expirationCriterion);
+ try {
+ final List<NimbusResponseContainer> result = responseCache.get(criteria);
+ if (result.size() != 1) {
+ log.error("{} Unexpected result (size={}) when storing response record into the metadata cache",
+ getLogPrefix(), result.size());
+ } else {
+ log.debug("{} Response stored into the cache", getLogPrefix());
+ }
+ } catch (final MetadataCacheException e) {
+ log.error("{} Could not store the response record into tht metadata cache", getLogPrefix(), e);
+ }
+
+ profileRequestContext.ensureOutboundMessageContext().setMessage(response);
+ }
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/FormOutboundResolveEntityResponse.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/FormOutboundResolveEntityResponse.java
new file mode 100644
index 0000000..86cd0b8
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/FormOutboundResolveEntityResponse.java
@@ -0,0 +1,231 @@
+/*
+ * 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.oidfed.profile.impl;
+
+import java.time.Duration;
+import java.time.Instant;
+import java.util.List;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+
+import org.opensaml.messaging.context.navigate.ChildContextLookup;
+import org.opensaml.profile.action.ActionSupport;
+import org.opensaml.profile.action.EventIds;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.opensaml.profile.context.navigate.InboundMessageContextLookup;
+import org.opensaml.profile.context.navigate.OutboundMessageContextLookup;
+import org.slf4j.Logger;
+
+import com.nimbusds.jwt.SignedJWT;
+import com.nimbusds.oauth2.sdk.Response;
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import net.shibboleth.idp.plugin.oidc.op.oidfed.config.CachedSuccessResponseLifetimeLookupFunction;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.messaging.impl.ResolveEntityRequest;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.messaging.impl.ResolveEntityResponse;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.ResponseContainerExpirationCriterion;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.ResolveEntityRequestCriterion;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.ResolveEntityResponseContainer;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.NimbusResponseCriterion;
+import net.shibboleth.idp.profile.AbstractProfileAction;
+import net.shibboleth.oidc.metadata.cache.MetadataCache;
+import net.shibboleth.oidc.metadata.cache.MetadataCacheException;
+import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.resolver.CriteriaSet;
+
+/**
+ * This action builds a response for the OpenID federation resolve entity request. The response contains an
+ * {@link EntityStatement}. The response is put in the {@link #responseCache} using the lifetime resolved via
+ * {@link #cachedResponseLifetimeLookupStrategy}.
+ *
+ * @since 4.3.0
+ */
+public class FormOutboundResolveEntityResponse extends AbstractProfileAction {
+
+ /** Class logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(FormOutboundResolveEntityResponse.class);
+
+ /** Metadata cache for cached response containers. */
+ @NonnullAfterInit private MetadataCache<ResolveEntityResponseContainer> responseCache;
+
+ /** Strategy used to locate the resolve entity context. */
+ @Nonnull
+ private Function<ProfileRequestContext, RelyingPartyCachedMessageContext> cachedMessageContextLookupStrategy;
+
+ /** Strategy used to locate the subcontext to hold the statement. */
+ @Nonnull private Function<ProfileRequestContext,EntityStatementContext> entityStatementContextLookupStrategy;
+
+ /** Strategy used to locate the lifetime for the cached response record. */
+ @Nonnull private Function<ProfileRequestContext,Duration> cachedResponseLifetimeLookupStrategy;
+
+ /** JWT used to build entity statement. */
+ @NonnullBeforeExec private SignedJWT jwt;
+
+ /** The resolve entity context to operate on. */
+ @NonnullBeforeExec private RelyingPartyCachedMessageContext cachedMessageContext;
+
+ /**
+ * Constructor.
+ */
+ public FormOutboundResolveEntityResponse() {
+ final Function<ProfileRequestContext,EntityStatementContext> escls =
+ new ChildContextLookup<>(EntityStatementContext.class).compose(
+ new OutboundMessageContextLookup());
+ assert escls != null;
+ entityStatementContextLookupStrategy = escls;
+ final Function<ProfileRequestContext, RelyingPartyCachedMessageContext> recls =
+ new ChildContextLookup<>(RelyingPartyCachedMessageContext.class).compose(
+ new InboundMessageContextLookup());
+ assert recls != null;
+ cachedMessageContextLookupStrategy = recls;
+ cachedResponseLifetimeLookupStrategy = new CachedSuccessResponseLifetimeLookupFunction();
+ }
+
+ /**
+ * Set the strategy used to locate the subcontext to hold the statement
+ *
+ * @param strategy What to set.
+ */
+ public void setEntityStatementContextLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext,EntityStatementContext> strategy) {
+ checkSetterPreconditions();
+ entityStatementContextLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null!");
+ }
+
+ /**
+ * Set the strategy used to locate the cached message context
+ *
+ * @param strategy What to set.
+ */
+ public void setCachedMessageContextLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext,RelyingPartyCachedMessageContext> strategy) {
+ checkSetterPreconditions();
+ cachedMessageContextLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null!");
+ }
+
+ /**
+ * Set the metadata cache for cached response containers.
+ *
+ * @param cache What to set.
+ */
+ public void setResponseCache(@Nonnull final MetadataCache<ResolveEntityResponseContainer> cache) {
+ checkSetterPreconditions();
+ responseCache = Constraint.isNotNull(cache, "Response metadata cache cannot be null");
+ }
+
+ /**
+ * Set the strategy used to locate the lifetime for the cached response record.
+ *
+ * @param strategy What to set.
+ */
+ public void setCachedResponseLifetimeLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext, Duration> strategy) {
+ checkSetterPreconditions();
+ cachedResponseLifetimeLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+
+ if (responseCache == null) {
+ throw new ComponentInitializationException("Response metadata cache cannot be null");
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+
+ if (!super.doPreExecute(profileRequestContext)) {
+ return false;
+ }
+ cachedMessageContext = cachedMessageContextLookupStrategy.apply(profileRequestContext);
+ if (cachedMessageContext == null) {
+ log.error("{} Could not resolve cached message context", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
+ return false;
+ }
+
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+ final Response cachedResponse = cachedMessageContext.getCachedResponse();
+ if (cachedResponse != null) {
+ log.debug("{} Cached response found, storing in to the outbound message context", getLogPrefix());
+ profileRequestContext.ensureOutboundMessageContext().setMessage(cachedResponse);
+ return;
+ }
+ log.debug("{} No cached response found, resolving the response JWT from the context", getLogPrefix());
+ final EntityStatementContext entityStatementContext =
+ entityStatementContextLookupStrategy.apply(profileRequestContext);
+ if (entityStatementContext == null) {
+ log.error("{} Could not resolve entity statement context", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
+ return;
+ }
+ if (entityStatementContext.getJWT() instanceof SignedJWT signedJwt) {
+ jwt = signedJwt;
+ } else {
+ log.error("{} No signed JWT found from the entity statement context", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
+ return;
+ }
+
+ assert jwt != null;
+ final ResolveEntityResponse response = new ResolveEntityResponse(jwt);
+ final NimbusResponseCriterion responseCriterion = new NimbusResponseCriterion(response);
+ final Duration lifetime = cachedResponseLifetimeLookupStrategy.apply(profileRequestContext);
+ if (lifetime == null) {
+ log.error("{} Could not resolve lifetime for the cached response record", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
+ return;
+ }
+ final Instant expiration = Instant.now().plus(lifetime);
+ assert expiration != null;
+ final ResponseContainerExpirationCriterion expirationCriterion =
+ new ResponseContainerExpirationCriterion(expiration);
+ if (cachedMessageContext.getValidatedRequest() instanceof ResolveEntityRequest validatedRequest) {
+ final ResolveEntityRequestCriterion requestCriterion = new ResolveEntityRequestCriterion(validatedRequest);
+ final CriteriaSet criteria = new CriteriaSet(requestCriterion, responseCriterion, expirationCriterion);
+ try {
+ final List<ResolveEntityResponseContainer> result = responseCache.get(criteria);
+ if (result.size() != 1) {
+ log.error("{} Unexpected result (size={}) when storing response record into the metadata cache",
+ getLogPrefix(), result.size());
+ } else {
+ log.debug("{} Response stored into the cache", getLogPrefix());
+ }
+ } catch (final MetadataCacheException e) {
+ log.error("{} Could not store the response record into tht metadata cache", getLogPrefix(), e);
+ }
+ } else {
+ log.error("{} No validated request found from the resolve entity context", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
+ return;
+ }
+
+ profileRequestContext.ensureOutboundMessageContext().setMessage(response);
+ }
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/GenerateClientID.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/GenerateClientID.java
new file mode 100644
index 0000000..6ee91f5
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/GenerateClientID.java
@@ -0,0 +1,140 @@
+/*
+ * 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.oidfed.profile.impl;
+
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.messaging.context.MessageContext;
+import org.opensaml.messaging.context.navigate.ChildContextLookup;
+import org.opensaml.profile.action.ActionSupport;
+import org.opensaml.profile.action.EventIds;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.opensaml.profile.context.navigate.OutboundMessageContextLookup;
+import org.slf4j.Logger;
+
+import com.nimbusds.oauth2.sdk.id.ClientID;
+
+import net.shibboleth.idp.plugin.oidc.op.messaging.context.OIDCClientRegistrationResponseContext;
+import net.shibboleth.idp.profile.AbstractProfileAction;
+import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+/**
+ * Reuses the entity ID as the client ID for the registration.
+ */
+public class GenerateClientID extends AbstractProfileAction {
+
+ /** Class logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(GenerateClientID.class);
+
+ /** Strategy used to locate the {@link OIDCClientRegistrationResponseContext} associated with a given request. */
+ @Nonnull private Function<ProfileRequestContext,OIDCClientRegistrationResponseContext>
+ oidcResponseContextLookupStrategy;
+
+ /** Strategy used to obtain the client id value for authorize/token request. */
+ @NonnullAfterInit private Function<MessageContext, ClientID> clientIDLookupStrategy;
+
+ /** The OIDCClientRegistrationResponseContext to create the client ID to. */
+ @Nullable private OIDCClientRegistrationResponseContext oidcResponseCtx;
+
+ /** The entity id to be used as client id. */
+ @NonnullBeforeExec private String entityId;
+
+ /** Constructor. */
+ public GenerateClientID() {
+ final Function<ProfileRequestContext,OIDCClientRegistrationResponseContext> orcls =
+ new ChildContextLookup<>(OIDCClientRegistrationResponseContext.class).compose(
+ new OutboundMessageContextLookup());
+ assert orcls != null;
+ oidcResponseContextLookupStrategy = orcls;
+ }
+
+ /**
+ * Set the strategy used to locate the {@link OIDCClientRegistrationResponseContext} associated with a given
+ * {@link MessageContext}.
+ *
+ * @param strategy strategy used to locate the {@link OIDCClientRegistrationResponseContext} associated with a
+ * given {@link MessageContext}
+ */
+ public void setOidcResponseContextLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext,OIDCClientRegistrationResponseContext> strategy) {
+ checkSetterPreconditions();
+
+ oidcResponseContextLookupStrategy = Constraint.isNotNull(strategy,
+ "OIDCClientRegistrationResponseContext lookup strategy cannot be null");
+ }
+
+ /**
+ * Set the strategy used to locate the client id of the request.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setClientIDLookupStrategy(@Nonnull final Function<MessageContext, ClientID> strategy) {
+ checkSetterPreconditions();
+ clientIDLookupStrategy =
+ Constraint.isNotNull(strategy, "ClientIDLookupStrategy cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+
+ if (clientIDLookupStrategy == null) {
+ throw new ComponentInitializationException("ClientIDLookupStrategy cannot be null");
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+
+ if (!super.doPreExecute(profileRequestContext)) {
+ return false;
+ }
+
+ oidcResponseCtx = oidcResponseContextLookupStrategy.apply(profileRequestContext);
+ if (oidcResponseCtx == null) {
+ log.debug("{} No OIDC client registration response context associated with this profile request",
+ getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MSG_CTX);
+ return false;
+ }
+
+ final ClientID clientId = clientIDLookupStrategy.apply(profileRequestContext.getInboundMessageContext());
+ if (clientId == null || clientId.getValue() == null) {
+ log.error("{} No client ID could be resolved via inbound message context", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MSG_CTX);
+ return false;
+ }
+ entityId = clientId.getValue();
+
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+ assert oidcResponseCtx != null;
+ oidcResponseCtx.setClientId(entityId);
+ }
+
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/InitializeEntityStatementContext.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/InitializeEntityStatementContext.java
new file mode 100644
index 0000000..9433124
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/InitializeEntityStatementContext.java
@@ -0,0 +1,197 @@
+/*
+ * 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.oidfed.profile.impl;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+
+import org.opensaml.profile.action.EventIds;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.opensaml.profile.context.navigate.OutboundMessageContextLookup;
+import org.slf4j.Logger;
+
+import com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata;
+
+import net.shibboleth.idp.plugin.oidc.op.metadata.resolver.ProviderMetadataResolver;
+import net.shibboleth.idp.profile.AbstractProfileAction;
+import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
+import net.shibboleth.shared.collection.CollectionSupport;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.primitive.NonnullSupplier;
+import net.shibboleth.shared.resolver.CriteriaSet;
+import net.shibboleth.shared.resolver.ResolverException;
+
+import org.opensaml.messaging.context.navigate.ChildContextLookup;
+import org.opensaml.profile.action.ActionSupport;
+
+/**
+ * Action that creates and initializes the {@link EntityStatementContext}.
+ *
+ * @event {@link EventIds#PROCEED_EVENT_ID}
+ * @event {@link EventIds#INVALID_PROFILE_CTX}
+ * @event {@link EventIds#IO_ERROR}
+ *
+ * @since 4.3.0
+ */
+public class InitializeEntityStatementContext extends AbstractProfileAction {
+
+ /** Class logger. */
+ @Nonnull private Logger log = LoggerFactory.getLogger(InitializeEntityStatementContext.class);
+
+ /** The resolver for the metadata that is being distributed. */
+ @NonnullAfterInit private ProviderMetadataResolver metadataResolver;
+
+ /** Strategy used to locate skeleton for the metadata claim. */
+ @NonnullAfterInit
+ private Function<CriteriaSet,Map<String,Map<String,Object>>> metadataSkeletonLookupStrategy;
+
+ /** Strategy used to create the subcontext to hold the statement. */
+ @Nonnull private Function<ProfileRequestContext,EntityStatementContext> entityStatementContextCreationStrategy;
+
+ /** Entity statement context. */
+ @NonnullBeforeExec private EntityStatementContext entityStatementCtx;
+
+ /** Metadata skeleton. */
+ @NonnullBeforeExec private Map<String,Map<String,Object>> metadataSkeleton;
+
+ /** Constructor. */
+ public InitializeEntityStatementContext() {
+ final Function<ProfileRequestContext,EntityStatementContext> esccs =
+ new ChildContextLookup<>(EntityStatementContext.class, true).compose(
+ new OutboundMessageContextLookup());
+ assert esccs != null;
+ entityStatementContextCreationStrategy = esccs;
+ }
+
+ /**
+ * Set the resolver for the metadata that is being distributed.
+ *
+ * @param resolver What to set.
+ */
+ public void setMetadataResolver(@Nonnull final ProviderMetadataResolver resolver) {
+ metadataResolver = Constraint.isNotNull(resolver, "The metadata resolver cannot be null!");
+ }
+
+ /**
+ * Set the strategy used to locate skeleton for the metadata claim.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setMetadataSkeletonLookupStrategy(
+ @Nonnull final Function<CriteriaSet,Map<String,Map<String,Object>>> strategy) {
+ checkSetterPreconditions();
+
+ metadataSkeletonLookupStrategy =
+ Constraint.isNotNull(strategy, "MetadataSkeletonLookupStrategy cannot be null");
+ }
+
+ /**
+ * Set the strategy used to create the {@link EntityStatementContext} to use.
+ *
+ * @param strategy creation strategy
+ */
+ public void setEntityStatementContextCreationStrategy(
+ @Nonnull final Function<ProfileRequestContext,EntityStatementContext> strategy) {
+ checkSetterPreconditions();
+
+ entityStatementContextCreationStrategy =
+ Constraint.isNotNull(strategy, "EntityStatementContext creation strategy cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+
+ if (metadataResolver == null) {
+ throw new ComponentInitializationException("The metadata resolver cannot be null!");
+ }
+ if (metadataSkeletonLookupStrategy == null) {
+ throw new ComponentInitializationException("MetadataSkeletonLookupStrategy cannot be null");
+ }
+ }
+
+ // Checkstyle: CyclomaticComplexity|MethodLength OFF
+ /** {@inheritDoc} */
+ @Override
+ protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+ if (!super.doPreExecute(profileRequestContext)) {
+ return false;
+ }
+
+ entityStatementCtx = entityStatementContextCreationStrategy.apply(profileRequestContext);
+ if (entityStatementCtx == null) {
+ log.error("{} Unable to create EntityStatementContext", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
+ return false;
+ }
+
+ metadataSkeleton = Optional.ofNullable(metadataSkeletonLookupStrategy.apply(new CriteriaSet()))
+ .orElseGet(NonnullSupplier.of(CollectionSupport.emptyMap()));
+
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+
+ final OIDCProviderMetadata metadata;
+ try {
+ metadata = metadataResolver.resolveSingle(profileRequestContext);
+ } catch (final ResolverException e) {
+ log.error("{} Could not resolve provider metadata", getLogPrefix(), e);
+ ActionSupport.buildEvent(profileRequestContext, EventIds.IO_ERROR);
+ return;
+ }
+ if (metadata == null) {
+ log.error("{} Could not resolve provider metadata", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.IO_ERROR);
+ return;
+ }
+ //TODO more types? (esp. OAuth2 AS)
+ entityStatementCtx.setMetadata(mergeMetadata(metadataSkeleton, "openid_provider", metadata.toJSONObject()));
+ }
+
+ /**
+ * Merge the given key and input to the given metadata skeleton. The input will overwrite the possibly existing
+ * values for the same key.
+ *
+ * @param metadata the metadata skeleton
+ * @param key the key in the skeleton to be merged
+ * @param input the data to be merged (overwrites possibly already existing attributes)
+ * @return the merged metadata
+ */
+ protected Map<String,Map<String,Object>> mergeMetadata(@Nonnull final Map<String,Map<String,Object>> metadata,
+ @Nonnull final String key, @Nonnull final Map<String,Object> input) {
+ final Map<String,Map<String,Object>> result = new HashMap<>(metadata);
+ final Map<String,Object> base = metadata.get(key);
+ if (base != null) {
+ final Map<String,Object> values = new HashMap<>(base);
+ values.putAll(input);
+ result.put(key, values);
+ } else {
+ result.put(key, input);
+ }
+ return result;
+ }
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/JWTClaimsSetFromEntityStatementLookupFunction.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/JWTClaimsSetFromEntityStatementLookupFunction.java
new file mode 100644
index 0000000..b81ae0f
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/JWTClaimsSetFromEntityStatementLookupFunction.java
@@ -0,0 +1,87 @@
+/*
+ * 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.oidfed.profile.impl;
+
+import java.text.ParseException;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.messaging.context.MessageContext;
+import org.opensaml.messaging.context.navigate.ChildContextLookup;
+import org.slf4j.Logger;
+
+import com.nimbusds.jwt.JWT;
+import com.nimbusds.jwt.JWTClaimsSet;
+
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+/**
+ * Extract the {@link JWTClaimsSet} from the JWT in {@link EntityStatementContext}.
+ *
+ * @since 4.3.0
+ */
+public class JWTClaimsSetFromEntityStatementLookupFunction implements Function<MessageContext, JWTClaimsSet> {
+
+ /** Class logger. */
+ @Nonnull private Logger log = LoggerFactory.getLogger(JWTClaimsSetFromEntityStatementLookupFunction.class);
+
+ /** Strategy used to locate the subcontext with the token. */
+ @Nonnull private Function<MessageContext,EntityStatementContext> entityStatementContextLookupStrategy;
+
+ /**
+ * Constructor.
+ */
+ public JWTClaimsSetFromEntityStatementLookupFunction() {
+ // message context -> OIDC response context -> ATC
+ final Function<MessageContext,EntityStatementContext> escl = new ChildContextLookup<>(EntityStatementContext.class);
+ assert escl != null;
+ entityStatementContextLookupStrategy = escl;
+ }
+
+ /**
+ * Set the strategy used to lookup the {@link EntityStatementContext} to use.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setEntityStatementContextCreationStrategy(
+ @Nonnull final Function<MessageContext,EntityStatementContext> strategy) {
+ entityStatementContextLookupStrategy =
+ Constraint.isNotNull(strategy, "EntityStatementContext lookup strategy cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ @Nullable public JWTClaimsSet apply(@Nullable final MessageContext messageContext) {
+ if (messageContext == null) {
+ return null;
+ }
+ final EntityStatementContext entityStatementCtx = entityStatementContextLookupStrategy.apply(messageContext);
+ if (entityStatementCtx == null) {
+ return null;
+ }
+ final JWT jwt = entityStatementCtx.getJWT();
+ try {
+ if (jwt != null) {
+ return jwt.getJWTClaimsSet();
+ }
+ } catch (final ParseException e) {
+ log.error("Could not fetch the claims set from entity statement", e);
+ }
+ return null;
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/LookupCachedEntityConfigurationResponse.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/LookupCachedEntityConfigurationResponse.java
new file mode 100644
index 0000000..5b38b73
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/LookupCachedEntityConfigurationResponse.java
@@ -0,0 +1,142 @@
+/*
+ * 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.oidfed.profile.impl;
+
+import java.util.List;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+
+import org.opensaml.messaging.context.navigate.ChildContextLookup;
+import org.opensaml.profile.action.ActionSupport;
+import org.opensaml.profile.action.EventIds;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.slf4j.Logger;
+
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.NimbusResponseContainer;
+import net.shibboleth.idp.profile.AbstractProfileAction;
+import net.shibboleth.oidc.metadata.cache.MetadataCache;
+import net.shibboleth.oidc.metadata.cache.MetadataCacheException;
+import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.resolver.CriteriaSet;
+
+/**
+ * Lookup if a cached response already exists for entity configuration. If yes, the response is
+ * stored into {@link RelyingPartyCachedMessageContext} and a corresponding event ID is published.
+ *
+ * @event {@link EventIds#PROCEED_EVENT_ID}
+ * @event {@link EventIds#INVALID_PROFILE_CTX}
+ * @event {@link OidFederationEventIds#CACHED_ENTITY_CONFIGURATION_RESPONSE}
+ *
+ * @since 4.3.0
+ */
+public class LookupCachedEntityConfigurationResponse extends AbstractProfileAction {
+
+ /** Class logger. */
+ @Nonnull private Logger log = LoggerFactory.getLogger(LookupCachedEntityConfigurationResponse.class);
+
+ /** Strategy used to create the cached message context. */
+ @Nonnull
+ private Function<ProfileRequestContext, RelyingPartyCachedMessageContext> cachedMessageContextCreationStrategy;
+
+ /** Metadata cache for cached response containers. */
+ @NonnullAfterInit private MetadataCache<NimbusResponseContainer> responseCache;
+
+ /** Cached message context to operate on. */
+ @NonnullBeforeExec private RelyingPartyCachedMessageContext cachedMessageContext;
+
+ /**
+ * Constructor.
+ */
+ public LookupCachedEntityConfigurationResponse() {
+ final Function<ProfileRequestContext, RelyingPartyCachedMessageContext> recls =
+ new ChildContextLookup<>(RelyingPartyCachedMessageContext.class, true);
+ assert recls != null;
+ cachedMessageContextCreationStrategy = recls;
+ }
+
+ /**
+ * Set the strategy used to create the cached message context
+ *
+ * @param strategy What to set.
+ */
+ public void setCachedMessageContextCreationStrategy(
+ @Nonnull final Function<ProfileRequestContext,RelyingPartyCachedMessageContext> strategy) {
+ checkSetterPreconditions();
+ cachedMessageContextCreationStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null!");
+ }
+
+ /**
+ * Set the metadata cache for cached response containers.
+ *
+ * @param cache What to set.
+ */
+ public void setResponseCache(@Nonnull final MetadataCache<NimbusResponseContainer> cache) {
+ checkSetterPreconditions();
+ responseCache = Constraint.isNotNull(cache, "Response metadata cache cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+ if (responseCache == null) {
+ throw new ComponentInitializationException("Response metadata cache cannot be null");
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+ if (!super.doPreExecute(profileRequestContext)) {
+ return false;
+ }
+
+ cachedMessageContext = cachedMessageContextCreationStrategy.apply(profileRequestContext);
+ if (cachedMessageContext == null) {
+ log.error("{} Could not create cached response context", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
+ return false;
+ }
+
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+ final CriteriaSet criteria = new CriteriaSet();
+ try {
+ final List<NimbusResponseContainer> result = responseCache.get(criteria);
+ if (result.size() != 1) {
+ log.debug("{} No cached response record found from the metadata cache", getLogPrefix(), result.size());
+ } else {
+ final NimbusResponseContainer cachedResponse = result.get(0);
+ cachedMessageContext.setCachedResponse(cachedResponse.getResponse());
+ log.debug("{} Response found from the cache, publishing event {}", getLogPrefix(),
+ OidFederationEventIds.CACHED_ENTITY_CONFIGURATION_RESPONSE);
+ ActionSupport.buildEvent(profileRequestContext,
+ OidFederationEventIds.CACHED_ENTITY_CONFIGURATION_RESPONSE);
+ return;
+ }
+ } catch (final MetadataCacheException e) {
+ log.error("{} Could not fetch response record from the metadata cache", getLogPrefix(), e);
+ }
+ }
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/LookupCachedResolveEntityResponse.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/LookupCachedResolveEntityResponse.java
new file mode 100644
index 0000000..1701d69
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/LookupCachedResolveEntityResponse.java
@@ -0,0 +1,158 @@
+/*
+ * 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.oidfed.profile.impl;
+
+import java.util.List;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+
+import org.opensaml.messaging.context.navigate.ChildContextLookup;
+import org.opensaml.profile.action.ActionSupport;
+import org.opensaml.profile.action.EventIds;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.opensaml.profile.context.navigate.InboundMessageContextLookup;
+import org.slf4j.Logger;
+
+import net.shibboleth.idp.plugin.oidc.op.oidfed.messaging.impl.ResolveEntityRequest;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.ResolveEntityRequestCriterion;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.ResolveEntityResponseContainer;
+import net.shibboleth.idp.profile.AbstractProfileAction;
+import net.shibboleth.oidc.metadata.cache.MetadataCache;
+import net.shibboleth.oidc.metadata.cache.MetadataCacheException;
+import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.resolver.CriteriaSet;
+
+/**
+ * Lookup if a cached response already exists for the validated resolve entity API request. If yes, the response is
+ * stored into {@link RelyingPartyCachedMessageContext} and a corresponding event ID is published.
+ *
+ * @event {@link EventIds#PROCEED_EVENT_ID}
+ * @event {@link EventIds#INVALID_PROFILE_CTX}
+ * @event {@link OidFederationEventIds#CACHED_RESOLVE_ENTITY_RESPONSE}
+ *
+ * @since 4.3.0
+ */
+public class LookupCachedResolveEntityResponse extends AbstractProfileAction {
+
+ /** Class logger. */
+ @Nonnull private Logger log = LoggerFactory.getLogger(LookupCachedResolveEntityResponse.class);
+
+ /** Strategy used to locate the cached message context. */
+ @Nonnull
+ private Function<ProfileRequestContext, RelyingPartyCachedMessageContext> cachedMessageContextLookupStrategy;
+
+ /** Metadata cache for cached response containers. */
+ @NonnullAfterInit private MetadataCache<ResolveEntityResponseContainer> responseCache;
+
+ /** Cached message context to operate on. */
+ @NonnullBeforeExec private RelyingPartyCachedMessageContext cachedMessageContext;
+
+ /** Request message to operate on. */
+ @NonnullBeforeExec private ResolveEntityRequest validatedRequest;
+
+ /**
+ * Constructor.
+ */
+ public LookupCachedResolveEntityResponse() {
+ final Function<ProfileRequestContext, RelyingPartyCachedMessageContext> recls =
+ new ChildContextLookup<>(RelyingPartyCachedMessageContext.class).compose(
+ new InboundMessageContextLookup());
+ assert recls != null;
+ cachedMessageContextLookupStrategy = recls;
+ }
+
+ /**
+ * Set the strategy used to locate the cached message context
+ *
+ * @param strategy What to set.
+ */
+ public void setCachedMessageContextLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext,RelyingPartyCachedMessageContext> strategy) {
+ checkSetterPreconditions();
+ cachedMessageContextLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null!");
+ }
+
+ /**
+ * Set the metadata cache for cached response containers.
+ *
+ * @param cache What to set.
+ */
+ public void setResponseCache(@Nonnull final MetadataCache<ResolveEntityResponseContainer> cache) {
+ checkSetterPreconditions();
+ responseCache = Constraint.isNotNull(cache, "Response metadata cache cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+ if (responseCache == null) {
+ throw new ComponentInitializationException("Response metadata cache cannot be null");
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+ if (!super.doPreExecute(profileRequestContext)) {
+ return false;
+ }
+
+ cachedMessageContext = cachedMessageContextLookupStrategy.apply(profileRequestContext);
+ if (cachedMessageContext == null) {
+ log.error("{} Could not resolve cached response context", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
+ return false;
+ }
+
+ if (cachedMessageContext.getValidatedRequest() instanceof ResolveEntityRequest resolveEntityRequest) {
+ validatedRequest = resolveEntityRequest;
+ } else {
+ log.error("{} Could not resolve validated resolve entity request", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
+ return false;
+ }
+
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+ assert validatedRequest != null;
+ final ResolveEntityRequestCriterion requestCriterion = new ResolveEntityRequestCriterion(validatedRequest);
+ final CriteriaSet criteria = new CriteriaSet(requestCriterion);
+ try {
+ final List<ResolveEntityResponseContainer> result = responseCache.get(criteria);
+ if (result.size() != 1) {
+ log.debug("{} No cached response record found from the metadata cache", getLogPrefix(), result.size());
+ } else {
+ final ResolveEntityResponseContainer cachedResponse = result.get(0);
+ cachedMessageContext.setCachedResponse(cachedResponse.getResponse());
+ log.debug("{} Response found from the cache, publishing event {}", getLogPrefix(),
+ OidFederationEventIds.CACHED_RESOLVE_ENTITY_RESPONSE);
+ ActionSupport.buildEvent(profileRequestContext, OidFederationEventIds.CACHED_RESOLVE_ENTITY_RESPONSE);
+ return;
+ }
+ } catch (final MetadataCacheException e) {
+ log.error("{} Could not fetch response record from the metadata cache", getLogPrefix(), e);
+ }
+ }
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/OidFederationEventIds.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/OidFederationEventIds.java
new file mode 100644
index 0000000..2558d9f
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/OidFederationEventIds.java
@@ -0,0 +1,67 @@
+/*
+ * 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.oidfed.profile.impl;
+
+import javax.annotation.Nonnull;
+
+import net.shibboleth.shared.annotation.constraint.NotEmpty;
+
+/**
+ * OpenID Federation -specific constants to use for {@link org.opensaml.profile.action.ProfileAction}
+ * {@link org.opensaml.profile.context.EventContext}s.
+ */
+public class OidFederationEventIds {
+
+ /**
+ * ID of event returned if a flow wishes to indicate that another trust chain should be selected instead
+ */
+ @Nonnull @NotEmpty public static final String RESELECT_TRUST_CHAIN = "ReselectTrustChain";
+
+ /**
+ * ID of event returned if cached resolve entity response was found and set to the context.
+ */
+ @Nonnull @NotEmpty public static final String CACHED_RESOLVE_ENTITY_RESPONSE = "CachedResolveEntityResponseFound";
+
+ /**
+ * ID of event returned if cached entity configuration response was found and set to the context.
+ */
+ @Nonnull @NotEmpty public static final String CACHED_ENTITY_CONFIGURATION_RESPONSE =
+ "CachedEntityConfigurationResponseFound";
+
+ /**
+ * ID of event returned if the given trust anchor is invalid.
+ */
+ @Nonnull @NotEmpty public static final String INVALID_TRUST_ANCHOR = "InvalidTrustAnchor";
+
+ /**
+ * ID of event returned if the given subject is invalid.
+ */
+ @Nonnull @NotEmpty public static final String INVALID_SUBJECT = "InvalidSubject";
+
+ /**
+ * ID of event returned if the given metadata is invalid.
+ */
+ @Nonnull @NotEmpty public static final String INVALID_METADATA = "InvalidMetadata";
+
+ /**
+ * ID of event returned if the given metadata policy is invalid.
+ */
+ @Nonnull @NotEmpty public static final String INVALID_METADATA_POLICY = "InvalidMetadataPolicy";
+
+ /**
+ * ID of event returned if the given metadata is invalid against policy.
+ */
+ @Nonnull @NotEmpty public static final String INVALID_METADATA_AGAINST_POLICY = "InvalidMetadataAgainstPolicy";
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/RelyingPartyCachedMessageContext.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/RelyingPartyCachedMessageContext.java
new file mode 100644
index 0000000..938485b
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/RelyingPartyCachedMessageContext.java
@@ -0,0 +1,77 @@
+/*
+ * 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.oidfed.profile.impl;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.messaging.context.BaseContext;
+
+import com.nimbusds.oauth2.sdk.Request;
+import com.nimbusds.oauth2.sdk.Response;
+
+/**
+ * Subcontext carrying information for request and response messages related to a relying party.
+ *
+ * @since 4.3.0
+ */
+public final class RelyingPartyCachedMessageContext extends BaseContext {
+
+ /** Validated (possibly modified) request message. */
+ @Nullable private Request validatedRequest;
+
+ /** Cached response message. */
+ @Nullable private Response cachedResponse;
+
+ /**
+ * Get the validated (possibly modified) resolve entity request.
+ *
+ * @return the validated request
+ */
+ @Nullable public Request getValidatedRequest() {
+ return validatedRequest;
+ }
+
+ /**
+ * Set the the validated (possibly modified) resolve entity request.
+ *
+ * @param request the validated request
+ * @return this context
+ */
+ @Nonnull public RelyingPartyCachedMessageContext setValidatedRequest(@Nullable final Request request) {
+ validatedRequest = request;
+ return this;
+ }
+
+ /**
+ * Get the cached response message.
+ *
+ * @return the cached response
+ */
+ @Nullable public Response getCachedResponse() {
+ return cachedResponse;
+ }
+
+ /**
+ * Set the cached response message.
+ *
+ * @param response cached response
+ * @return this context
+ */
+ @Nonnull public RelyingPartyCachedMessageContext setCachedResponse(@Nullable final Response response) {
+ cachedResponse = response;
+ return this;
+ }
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/RelyingPartyTrustChainContext.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/RelyingPartyTrustChainContext.java
new file mode 100644
index 0000000..c9acadc
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/RelyingPartyTrustChainContext.java
@@ -0,0 +1,212 @@
+/*
+ * 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.oidfed.profile.impl;
+
+import java.time.Instant;
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.messaging.context.BaseContext;
+
+import com.nimbusds.jwt.SignedJWT;
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import net.shibboleth.shared.collection.Pair;
+
+/**
+ * Subcontext carrying information for trust chains related to a relying party.
+ *
+ * @since 4.3.0
+ */
+public final class RelyingPartyTrustChainContext extends BaseContext {
+
+ /** All resolved trust chains for the relying party. */
+ @Nullable private List<List<EntityStatement>> resolvedTrustChains;
+
+ /** Policy-compliant trust chains for the relying party. */
+ @Nullable private List<Pair<List<EntityStatement>,Map<String,Map<String,Object>>>> policyCompliantTrustChains;
+
+ /** Selected trust chain for the relying party. */
+ @Nullable private Pair<List<EntityStatement>,Map<String,Map<String,Object>>> selectedTrustChain;
+
+ /** Expiration instant for the selected metadata. */
+ @Nullable private Instant selectedMetadataExpiration;
+
+ /** Verified trust mark IDs for the selected trust chain. */
+ @Nullable private Map<String, List<String>> verifiedTrustMarkIds;
+
+ /** Verified trust marks for the selected trust chain. */
+ @Nullable private Map<String, List<SignedJWT>> verifiedTrustMarks;
+
+ /** All previously selected but rejected trust chains. */
+ @Nullable private List<List<EntityStatement>> rejectedTrustChains;
+
+ /**
+ * Get the resolved trust chains for the relying party.
+ *
+ * @return the trust chains
+ */
+ @Nullable public List<List<EntityStatement>> getResolvedTrustChains() {
+ return resolvedTrustChains;
+ }
+
+ /**
+ * Set the resolved trust chains for the relying party.
+ *
+ * @param trustChains the trust chains
+ *
+ * @return this context
+ */
+ @Nonnull public RelyingPartyTrustChainContext setResolvedTrustChains(
+ @Nullable final List<List<EntityStatement>> trustChains) {
+ resolvedTrustChains = trustChains;
+ return this;
+ }
+
+ /**
+ * Get the policy-compliant trust chains for the relying party.
+ *
+ * @return the trust chains
+ */
+ @Nullable public List<Pair<List<EntityStatement>,Map<String,Map<String,Object>>>> getPolicyCompliantTrustChains() {
+ return policyCompliantTrustChains;
+ }
+
+ /**
+ * Set the policy-compliant trust chains for the relying party.
+ *
+ * @param chains the trust chains and client informations
+ *
+ * @return this context
+ */
+ @Nonnull public RelyingPartyTrustChainContext setPolicyCompliantTrustChains(
+ @Nullable final List<Pair<List<EntityStatement>,Map<String,Map<String,Object>>>> chains) {
+ policyCompliantTrustChains = chains;
+ return this;
+ }
+
+ /**
+ * Get the selected trust chain for the relying party.
+ *
+ * @return the trust chain
+ */
+ @Nullable public Pair<List<EntityStatement>,Map<String,Map<String,Object>>> getSelectedTrustChain() {
+ return selectedTrustChain;
+ }
+
+ /**
+ * Set the selected trust chain for the relying party.
+ *
+ * @param chain the selected trust chain
+ *
+ * @return this context
+ */
+ @Nonnull public RelyingPartyTrustChainContext setSelectedTrustChains(
+ @Nullable final Pair<List<EntityStatement>,Map<String,Map<String,Object>>> chain) {
+ selectedTrustChain = chain;
+ return this;
+ }
+
+ /**
+ * Get the expiration instant for the selected metadata.
+ *
+ * @return the expiration instant
+ */
+ @Nullable public Instant getSelectedMetadataExpiration() {
+ return selectedMetadataExpiration;
+ }
+
+ /**
+ * Set the expiration instant for the selected metadata.
+ *
+ * @param expiration the expiration instant
+ *
+ * @return this context
+ */
+ @Nonnull public RelyingPartyTrustChainContext setSelectedMetadataExpiration(@Nullable final Instant expiration) {
+ selectedMetadataExpiration = expiration;
+ return this;
+ }
+
+ /**
+ * Get the verified trust mark IDs for the selected trust chain.
+ *
+ * @return verified trust mark IDs
+ */
+ @Nullable public Map<String, List<String>> getVerifiedTrustMarkIds() {
+ return verifiedTrustMarkIds;
+ }
+
+ /**
+ * Set the verified trust mark IDs for the selected trust chain.
+ *
+ * @param ids verified trust mark IDs
+ *
+ * @return this context
+ */
+ @Nonnull public RelyingPartyTrustChainContext setVerifiedTrustMarkIds(
+ @Nullable final Map<String, List<String>> ids) {
+ verifiedTrustMarkIds = ids;
+ return this;
+ }
+
+ /**
+ * Get the verified trust marks for the selected trust chain.
+ *
+ * @return verified trust marks
+ */
+ @Nullable public Map<String, List<SignedJWT>> getVerifiedTrustMarks() {
+ return verifiedTrustMarks;
+ }
+
+ /**
+ * Set the verified trust marks for the selected trust chain.
+ *
+ * @param trustMarks verified trust marks
+ *
+ * @return this context
+ */
+ @Nonnull public RelyingPartyTrustChainContext setVerifiedTrustMarks(
+ @Nullable final Map<String, List<SignedJWT>> trustMarks) {
+ verifiedTrustMarks = trustMarks;
+ return this;
+ }
+
+ /**
+ * Get the previously selected but rejected trust chains for the relying party.
+ *
+ * @return the trust chains
+ */
+ @Nullable public List<List<EntityStatement>> getRejectedTrustChains() {
+ return rejectedTrustChains;
+ }
+
+ /**
+ * Set the previously selected but rejected trust chains for the relying party.
+ *
+ * @param trustChains the trust chains
+ *
+ * @return this context
+ */
+ @Nonnull public RelyingPartyTrustChainContext setRejectedTrustChains(
+ @Nullable final List<List<EntityStatement>> trustChains) {
+ rejectedTrustChains = trustChains;
+ return this;
+ }
+
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ResolveTrustChains.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ResolveTrustChains.java
new file mode 100644
index 0000000..dd942fa
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ResolveTrustChains.java
@@ -0,0 +1,263 @@
+/*
+ * 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.oidfed.profile.impl;
+
+import java.net.MalformedURLException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+import javax.annotation.Nonnull;
+
+import org.opensaml.profile.action.EventIds;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.slf4j.Logger;
+
+import com.nimbusds.oauth2.sdk.id.ClientID;
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import net.shibboleth.idp.authn.AuthnEventIds;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.SubjectEntityIDCriterion;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.SubjectEntityStatementCriterion;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.navigate.DefaultPreSelectedTrustChainIDsLookupStrategy;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.navigate.DefaultTrustChainIDsLookupStrategy;
+import net.shibboleth.oidc.metadata.cache.MetadataCache;
+import net.shibboleth.oidc.metadata.cache.MetadataCacheException;
+import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
+import net.shibboleth.shared.collection.CollectionSupport;
+import net.shibboleth.shared.collection.Pair;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.logic.FunctionSupport;
+import net.shibboleth.shared.logic.PredicateSupport;
+import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.resolver.CriteriaSet;
+
+import org.opensaml.messaging.context.MessageContext;
+import org.opensaml.profile.action.ActionSupport;
+
+/**
+ * Resolves metadata policy-compliant trust chains from the configurable trust chain cache, metadata policy merging
+ * strategy and enforcer. The data is populated to the {@link RelyingPartyTrustChainContext}.
+ *
+ * @event {@link EventIds#PROCEED_EVENT_ID}
+ * @event {@link EventIds#INVALID_MSG_CTX}
+ *
+ * @since 4.3.0
+ */
+public class ResolveTrustChains extends AbstractTrustChainResolutionAction {
+
+ /** Class logger. */
+ @Nonnull private Logger log = LoggerFactory.getLogger(ResolveTrustChains.class);
+
+ /** Metadata cache for trust chains. */
+ @NonnullAfterInit private MetadataCache<List<List<EntityStatement>>> trustChainCache;
+
+ /** Strategy used to obtain the client id value of the request. */
+ @NonnullAfterInit private Function<MessageContext, ClientID> clientIDLookupStrategy;
+
+ /** Strategy used to fetch the pre-selected trust chain entity IDs. */
+ @Nonnull private Function<ProfileRequestContext, List<String>> preSelectedTrustChainIdsLookupStrategy;
+
+ /** Strategy used to get entity IDs from a trust chain. */
+ @Nonnull private Function<List<EntityStatement>, List<String>> trustChainIDsLookupStrategy;
+
+ /** Strategy used to fetch entity configuration delivered to the trust chain cache. */
+ @Nonnull private Function<ProfileRequestContext, EntityStatement> entityConfigurationLookupStrategy;
+
+ /** Condition to require entity configuration via {@link #entityConfigurationLookupStrategy}. */
+ @Nonnull private Predicate<ProfileRequestContext> requireEntityConfigurationCondition;
+
+ /** OAuth2 client id. */
+ @NonnullBeforeExec private String clientId;
+
+ /**
+ * Constructor.
+ */
+ public ResolveTrustChains() {
+ super();
+ preSelectedTrustChainIdsLookupStrategy = new DefaultPreSelectedTrustChainIDsLookupStrategy();
+ trustChainIDsLookupStrategy = new DefaultTrustChainIDsLookupStrategy();
+ entityConfigurationLookupStrategy = FunctionSupport.constant(null);
+ requireEntityConfigurationCondition = PredicateSupport.alwaysFalse();
+ }
+
+ /**
+ * Set the metadata cache for trust chains.
+ *
+ * @param cache metadata cache
+ */
+ public void setTrustChainCache(@Nonnull final MetadataCache<List<List<EntityStatement>>> cache) {
+ checkSetterPreconditions();
+ trustChainCache = Constraint.isNotNull(cache, "TrustChainCache cannot be null");
+ }
+
+ /**
+ * Set the strategy used to locate the client id of the request.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setClientIDLookupStrategy(@Nonnull final Function<MessageContext, ClientID> strategy) {
+ checkSetterPreconditions();
+ clientIDLookupStrategy =
+ Constraint.isNotNull(strategy, "ClientIDLookupStrategy cannot be null");
+ }
+
+ /**
+ * Set the strategy used to fetch the pre-selected trust chain entity IDs.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setPreSelectedTrustChainIdsLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext, List<String>> strategy) {
+ checkSetterPreconditions();
+ preSelectedTrustChainIdsLookupStrategy = Constraint.isNotNull(strategy,
+ "PreSelectedTrustChainIdsLookupStrategy cannot be null");
+ }
+
+ /**
+ * Set the strategy used to get entity IDs from a trust chain.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setTrustChainIDsLookupStrategy(@Nonnull final Function<List<EntityStatement>, List<String>> strategy) {
+ checkSetterPreconditions();
+ trustChainIDsLookupStrategy = Constraint.isNotNull(strategy, "TrustChainIDsLookupStrategy cannot be null");
+ }
+
+ /**
+ * Set the strategy used to fetch entity configuration delivered to the trust chain cache.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setEntityConfigurationLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext, EntityStatement> strategy) {
+ checkSetterPreconditions();
+ entityConfigurationLookupStrategy = Constraint.isNotNull(strategy,
+ "EntityConfigurationLookupStrategy cannot be null");
+ }
+
+ /**
+ * Set the condition to require entity configuration via {@link #entityConfigurationLookupStrategy}.
+ * @param predicate condition
+ */
+ public void setRequireEntityConfigurationCondition(@Nonnull final Predicate<ProfileRequestContext> predicate) {
+ checkSetterPreconditions();
+ requireEntityConfigurationCondition =
+ Constraint.isNotNull(predicate, "RequireEntityConfigurationCondition cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+
+ if (trustChainCache == null) {
+ throw new ComponentInitializationException("TrustChainCache cannot be null");
+ }
+ if (clientIDLookupStrategy == null) {
+ throw new ComponentInitializationException("ClientIDLookupStrategy cannot be null");
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+ if (!super.doPreExecute(profileRequestContext)) {
+ return false;
+ }
+
+ final ClientID id = clientIDLookupStrategy.apply(profileRequestContext.getInboundMessageContext());
+ if (id == null) {
+ log.error("{} Unable to obtain client ID", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MSG_CTX);
+ return false;
+ }
+ clientId = id.getValue();
+ try {
+ new URL(clientId).toURI();
+ } catch (final URISyntaxException | MalformedURLException e) {
+ log.debug("{} The client ID {} is not a valid URL, nothing to do", getLogPrefix(), clientId);
+ return false;
+ }
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+ log.debug("{} Resolving trust chain for {}", getLogPrefix(), clientId);
+ assert clientId != null;
+ final CriteriaSet criteriaSet = new CriteriaSet(new SubjectEntityIDCriterion(clientId));
+ final EntityStatement entityConfiguration = entityConfigurationLookupStrategy.apply(profileRequestContext);
+ if (entityConfiguration != null) {
+ log.debug("{} Entity configuration resolved and included to the criteria set", getLogPrefix());
+ criteriaSet.add(new SubjectEntityStatementCriterion(entityConfiguration));
+ } else if (requireEntityConfigurationCondition.test(profileRequestContext)) {
+ log.error("{} Mandatory entity configuration could not be resolved", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, AuthnEventIds.INVALID_CREDENTIALS);
+ return;
+ }
+ final List<List<List<EntityStatement>>> cacheResult;
+ try {
+ cacheResult = trustChainCache.get(criteriaSet);
+ } catch (final MetadataCacheException e) {
+ log.warn("{} Could fetch trust chains for {}", getLogPrefix(), clientId);
+ return;
+ }
+ if (cacheResult.isEmpty()) {
+ log.debug("{} No trust chains resolved for {}", getLogPrefix(), clientId);
+ return;
+ }
+ final List<String> preSelectedChain =
+ Optional.ofNullable(preSelectedTrustChainIdsLookupStrategy.apply(profileRequestContext))
+ .orElse(CollectionSupport.emptyList());
+
+ final RelyingPartyTrustChainContext trustChainContext =
+ getTrustChainContextCreationStrategy().apply(profileRequestContext);
+ trustChainContext.setResolvedTrustChains(cacheResult.get(0));
+ final List<Pair<List<EntityStatement>, Map<String,Map<String,Object>>>> policyCompliantChains =
+ new ArrayList<>();
+
+ String errorEventId = null;
+ for (final List<EntityStatement> chain : cacheResult.get(0)) {
+ assert chain != null;
+ if (!preSelectedChain.isEmpty() && !preSelectedChain.equals(trustChainIDsLookupStrategy.apply(chain))) {
+ log.debug("{} Ignored resolved trust chain that doesn't match with preselected chain", getLogPrefix());
+ continue;
+ }
+ errorEventId = populatePolicyComplaintChains(chain, policyCompliantChains);
+ }
+
+ if (policyCompliantChains.isEmpty()) {
+ if (errorEventId == null) {
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
+ } else {
+ ActionSupport.buildEvent(profileRequestContext, errorEventId);
+ }
+ return;
+ }
+ log.debug("{} Setting the policy compliant trust chains into the context: {}", getLogPrefix(),
+ policyCompliantChains);
+ trustChainContext.setPolicyCompliantTrustChains(policyCompliantChains);
+ }
+
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ResolveTrustMarks.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ResolveTrustMarks.java
new file mode 100644
index 0000000..5f2da39
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ResolveTrustMarks.java
@@ -0,0 +1,553 @@
+/*
+ * 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.oidfed.profile.impl;
+
+import java.text.ParseException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.messaging.context.navigate.ChildContextLookup;
+import org.opensaml.profile.action.ActionSupport;
+import org.opensaml.profile.action.EventIds;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.opensaml.profile.context.navigate.InboundMessageContextLookup;
+import org.opensaml.security.SecurityException;
+import org.opensaml.security.trust.TrustEngine;
+import org.slf4j.Logger;
+
+import com.nimbusds.jwt.JWTClaimsSet;
+import com.nimbusds.jwt.SignedJWT;
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultTrustChainTrustMarksParsingStrategy;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.SubjectEntityIDCriterion;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.SubjectEntityStatementCriterion;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.TrustMarkOwnersCriterion;
+import net.shibboleth.idp.profile.AbstractProfileAction;
+import net.shibboleth.oidc.jwt.claims.ClaimsValidator;
+import net.shibboleth.oidc.jwt.claims.JWTValidationException;
+import net.shibboleth.oidc.metadata.cache.MetadataCache;
+import net.shibboleth.oidc.metadata.cache.MetadataCacheException;
+import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
+import net.shibboleth.shared.collection.CollectionSupport;
+import net.shibboleth.shared.collection.Pair;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.logic.PredicateSupport;
+import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.primitive.NonnullSupplier;
+import net.shibboleth.shared.primitive.StringSupport;
+import net.shibboleth.shared.resolver.CriteriaSet;
+
+/**
+ * Resolves the trust marks for the selected trust chain and stores the data into {@link RelyingPartyTrustChainContext}.
+ *
+ * @event {@link EventIds#PROCEED_EVENT_ID}
+ * @event {@link EventIds#INVALID_MSG_CTX}
+ *
+ * @since 4.3.0
+ */
+public class ResolveTrustMarks extends AbstractProfileAction {
+
+ /** Class logger. */
+ @Nonnull private Logger log = LoggerFactory.getLogger(ResolveTrustMarks.class);
+
+ /** Strategy used to lookup the trust chain context. */
+ @Nonnull private Function<ProfileRequestContext, RelyingPartyTrustChainContext> trustChainContextLookupStrategy;
+
+ /** Strategy used to parse trust marks from the selected trust chain. */
+ @Nonnull private Function<List<EntityStatement>,Map<String,List<SignedJWT>>> trustChainTrustMarksParsingStrategy;
+
+ /** Strategy used to lookup trusted trust mark issuers for the trust chain. */
+ @NonnullAfterInit
+ private Function<List<EntityStatement>, Map<String, List<String>>> trustedTrustMarkIssuersLookupStrategy;
+
+ /** Strategy used to lookup trusted trust mark owners for the trust chain. */
+ @NonnullAfterInit
+ private Function<List<EntityStatement>, Map<String, Map<String, Object>>> trustedTrustMarkOwnersLookupStrategy;
+
+ /** Condition to solely take trusted trust mark issuers into account. */
+ @Nonnull private Predicate<ProfileRequestContext> trustedTrustMarkIssuersOnlyCondition;
+
+ /** Metadata cache for trust chains (for trust mark issuers). */
+ @NonnullAfterInit private MetadataCache<List<List<EntityStatement>>> trustChainCache;
+
+ /** Trust engine used to validate a trust mark signature. */
+ @NonnullAfterInit private TrustEngine<SignedJWT> trustEngine;
+
+ /** Trust engine used to validate a delegated trust mark signature. */
+ @NonnullAfterInit private TrustEngine<SignedJWT> delegationTrustEngine;
+
+ /** Strategy used to lookup trust mark claims validator. */
+ @NonnullAfterInit private Function<ProfileRequestContext,ClaimsValidator> trustMarkClaimsValidationLookupStrategy;
+
+ /** Strategy used to lookup delegated trust mark claims validator. */
+ @NonnullAfterInit
+ private Function<ProfileRequestContext,ClaimsValidator> delegatedTrustMarkClaimsValidationLookupStrategy;
+
+ /** Trust chain context to operate on. */
+ @NonnullBeforeExec private RelyingPartyTrustChainContext trustChainContext;
+
+ /** The selected trust chain to resolve trust marks from. */
+ @NonnullBeforeExec private List<EntityStatement> selectedTrustChain;
+
+ /** Trust mark claims validator. */
+ @NonnullBeforeExec private ClaimsValidator trustMarkClaimsValidator;
+
+ /** Delegated trust mark claims validator. */
+ @NonnullBeforeExec private ClaimsValidator delegatedTrustMarkClaimsValidator;
+
+ /**
+ * Constructor.
+ */
+ public ResolveTrustMarks() {
+ final Function<ProfileRequestContext, RelyingPartyTrustChainContext> tcls =
+ new ChildContextLookup<>(RelyingPartyTrustChainContext.class).compose(
+ new InboundMessageContextLookup());
+ assert tcls != null;
+ trustChainContextLookupStrategy = tcls;
+ trustChainTrustMarksParsingStrategy = new DefaultTrustChainTrustMarksParsingStrategy();
+ trustedTrustMarkIssuersOnlyCondition = PredicateSupport.alwaysTrue();
+ }
+
+ /**
+ * Set the strategy used to lookup the trust chain context.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setTrustChainContextLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext, RelyingPartyTrustChainContext> strategy) {
+ checkSetterPreconditions();
+ trustChainContextLookupStrategy =
+ Constraint.isNotNull(strategy, "TrustChainContextLookupStrategy cannot be null");
+ }
+
+ /**
+ * Set the strategy used to lookup trusted trust mark issuers for the trust chain.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setTrustedTrustMarkIssuersLookupStrategy(
+ @Nonnull final Function<List<EntityStatement>, Map<String, List<String>>> strategy) {
+ checkSetterPreconditions();
+ trustedTrustMarkIssuersLookupStrategy =
+ Constraint.isNotNull(strategy, "trustedTrustMarkIssuersLookupStrategy cannot be null");
+ }
+
+ /**
+ * Set the strategy used to lookup trusted trust mark issuers for the trust chain.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setTrustedTrustMarkOwnersLookupStrategy(
+ @Nonnull final Function<List<EntityStatement>, Map<String, Map<String, Object>>> strategy) {
+ checkSetterPreconditions();
+ trustedTrustMarkOwnersLookupStrategy =
+ Constraint.isNotNull(strategy, "trustedTrustMarkOwnersLookupStrategy cannot be null");
+ }
+
+ /**
+ * Set the condition to solely take trusted trust mark issuers into account.
+ *
+ * @param condition condition to set
+ */
+ public void setTrustedTrustMarkIssuersOnlyCondition(@Nonnull final Predicate<ProfileRequestContext> condition) {
+ checkSetterPreconditions();
+ trustedTrustMarkIssuersOnlyCondition =
+ Constraint.isNotNull(condition, "TrustedTrustMarkIssuersOnlyCondition cannot be null");
+ }
+
+ /**
+ * Set the metadata cache for trust chains.
+ *
+ * @param cache metadata cache
+ */
+ public void setTrustChainCache(@Nonnull final MetadataCache<List<List<EntityStatement>>> cache) {
+ checkSetterPreconditions();
+ trustChainCache = Constraint.isNotNull(cache, "TrustChainCache cannot be null");
+ }
+
+ /**
+ * Set trust engine used to validate a signature.
+ *
+ * @param engine trust engine
+ */
+ public void setTrustEngine(@Nonnull final TrustEngine<SignedJWT> engine) {
+ checkSetterPreconditions();
+ trustEngine = Constraint.isNotNull(engine, "Trust Engine cannot be null");
+ }
+
+ /**
+ * Set trust engine used to validate a delegated trust mark signature.
+ *
+ * @param engine trust engine
+ */
+ public void setDelegationTrustEngine(@Nonnull final TrustEngine<SignedJWT> engine) {
+ checkSetterPreconditions();
+ delegationTrustEngine = Constraint.isNotNull(engine, "Delegation Trust Engine cannot be null");
+ }
+
+ /**
+ * Set the strategy used to lookup trust mark claims validator.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setTrustMarkClaimsValidationLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext, ClaimsValidator> strategy) {
+ checkSetterPreconditions();
+ trustMarkClaimsValidationLookupStrategy =
+ Constraint.isNotNull(strategy, "TrustMarkClaimsValidationLookupStrategy cannot be null");
+ }
+
+ /**
+ * Set the strategy used to lookup delegated trust mark claims validator.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setDelegatedTrustMarkClaimsValidationLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext, ClaimsValidator> strategy) {
+ checkSetterPreconditions();
+ delegatedTrustMarkClaimsValidationLookupStrategy =
+ Constraint.isNotNull(strategy, "DelegatedTrustMarkClaimsValidationLookupStrategy cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+
+ if (trustChainCache == null) {
+ throw new ComponentInitializationException("TrustChainCache cannot be null");
+ }
+ if (trustEngine == null) {
+ throw new ComponentInitializationException("Trust Engine cannot be null");
+ }
+ if (delegationTrustEngine == null) {
+ throw new ComponentInitializationException("Delegation Trust Engine cannot be null");
+ }
+ if (trustedTrustMarkIssuersLookupStrategy == null) {
+ throw new ComponentInitializationException("Trusted trust mark issuers lookup strategy cannot be null");
+ }
+ if (trustedTrustMarkOwnersLookupStrategy == null) {
+ throw new ComponentInitializationException("Trusted trust mark owners lookup strategy cannot be null");
+ }
+ if (trustMarkClaimsValidationLookupStrategy == null) {
+ throw new ComponentInitializationException("TrustMarkClaimsValidationLookupStrategy cannot be null");
+ }
+ if (delegatedTrustMarkClaimsValidationLookupStrategy == null) {
+ throw new ComponentInitializationException(
+ "DelegatedTrustMarkClaimsValidationLookupStrategy cannot be null");
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+ if (!super.doPreExecute(profileRequestContext)) {
+ return false;
+ }
+
+ trustChainContext = trustChainContextLookupStrategy.apply(profileRequestContext);
+ if (trustChainContext == null || trustChainContext.getPolicyCompliantTrustChains() == null) {
+ log.error("{} Unable to locate policy-compliant trust chains", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MSG_CTX);
+ return false;
+ }
+
+ final Pair<List<EntityStatement>, Map<String,Map<String,Object>>> selectedChain =
+ trustChainContext.getSelectedTrustChain();
+
+ if (selectedChain == null || selectedChain.getFirst() == null) {
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MSG_CTX);
+ log.error("{} No selected trust chain could be resolved", getLogPrefix());
+ return false;
+ }
+
+ selectedTrustChain = selectedChain.getFirst();
+ assert selectedTrustChain != null;
+ if (selectedTrustChain.size() < 3) {
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MSG_CTX);
+ log.error("{} Unexpected length in the selected trust chain: {}", getLogPrefix(),
+ selectedTrustChain.size());
+ return false;
+ }
+
+ trustMarkClaimsValidator = trustMarkClaimsValidationLookupStrategy.apply(profileRequestContext);
+ if (trustMarkClaimsValidator == null) {
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
+ log.error("{} Unable to locate trust mark claims validator", getLogPrefix());
+ return false;
+ }
+
+ delegatedTrustMarkClaimsValidator =
+ delegatedTrustMarkClaimsValidationLookupStrategy.apply(profileRequestContext);
+ if (delegatedTrustMarkClaimsValidator == null) {
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
+ log.error("{} Unable to locate delegated trust mark claims validator", getLogPrefix());
+ return false;
+ }
+
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+ final boolean onlyTrustedIssuers = trustedTrustMarkIssuersOnlyCondition.test(profileRequestContext);
+
+ final Map<String, List<SignedJWT>> chainTrustMarks =
+ Optional.ofNullable(trustChainTrustMarksParsingStrategy.apply(selectedTrustChain))
+ .orElseGet(NonnullSupplier.of(CollectionSupport.emptyMap()))
+ .entrySet().stream()
+ .collect(Collectors.toMap(entry -> entry.getKey(),
+ entry -> entry.getValue().stream()
+ .filter(trustMark ->
+ validateClaims(trustMarkClaimsValidator, trustMark, profileRequestContext))
+ .toList()));
+ if (chainTrustMarks == null || chainTrustMarks.isEmpty()) {
+ log.debug("{} No valid trust marks found from the selected trust chain", getLogPrefix());
+ return;
+ }
+
+ final Map<String, List<String>> trustedIssuers =
+ Optional.ofNullable(trustedTrustMarkIssuersLookupStrategy.apply(selectedTrustChain))
+ .orElseGet(NonnullSupplier.of(CollectionSupport.emptyMap()));
+ log.debug("{} Trusted trust mark issuers {}", getLogPrefix(), trustedIssuers);
+ assert trustedIssuers != null;
+
+ final Map<String, Map<String, Object>> trustedOwners =
+ Optional.ofNullable(trustedTrustMarkOwnersLookupStrategy.apply(selectedTrustChain))
+ .orElseGet(NonnullSupplier.of(CollectionSupport.emptyMap()));
+ log.debug("{} Trusted trust mark owners {}", getLogPrefix(), trustedOwners);
+ assert trustedOwners != null;
+
+ final Map<String, List<SignedJWT>> verifiedTrustMarks = new HashMap<>();
+ for (final EntityStatement statement : selectedTrustChain) {
+ final List<SignedJWT> trustMarks = chainTrustMarks.get(statement.getEntityID().getValue());
+ if (trustMarks == null || trustMarks.isEmpty()) {
+ break;
+ }
+ verifiedTrustMarks.put(
+ statement.getEntityID().getValue(),
+ trustMarks.stream()
+ .filter(entry -> onlyTrustedIssuers ?
+ checkTrustedIssuer(entry, trustedIssuers, trustedOwners) : true)
+ .filter(entry -> verifyTrustMark(entry, trustedOwners, profileRequestContext))
+ .filter(Objects::nonNull)
+ .toList());
+ }
+ trustChainContext.setVerifiedTrustMarks(verifiedTrustMarks);
+ final Map<String, List<String>> verifiedTrustMarkIds = verifiedTrustMarks.entrySet().stream()
+ .collect(Collectors.toMap(entry -> entry.getKey(), entry -> entry.getValue().stream()
+ .map(list -> getTrustMarkId(list))
+ .toList()));
+ log.debug("{} The following trust marks are validated: {}", getLogPrefix(), verifiedTrustMarkIds);
+ trustChainContext.setVerifiedTrustMarkIds(verifiedTrustMarkIds);
+ }
+
+ /**
+ * Validates the given trust mark JWT against the given claims validator.
+ *
+ * @param claimsValidator the claims validator (chain)
+ * @param jwt the trust mark
+ * @param profileRequestContext the profile request context
+ * @return true if validation succeeded, false otherwise
+ */
+ protected boolean validateClaims(@Nullable final ClaimsValidator claimsValidator, @Nullable final SignedJWT jwt,
+ @Nonnull final ProfileRequestContext profileRequestContext) {
+ if (claimsValidator == null || jwt == null) {
+ return false;
+ }
+ try {
+ final JWTClaimsSet claimsSet = jwt.getJWTClaimsSet();
+ assert claimsSet != null;
+ claimsValidator.validate(claimsSet, profileRequestContext);
+ return true;
+ } catch (final JWTValidationException | ParseException e) {
+ log.debug("{} Claims validation failed", getLogPrefix(), e);
+ }
+ return false;
+ }
+
+ /**
+ * Verifies the given trust mark meets configuration for trusted trust mark issuers.
+ *
+ * @param jwt the trust mark to be verified
+ * @param trustedIssuers the trusted trust mark issuers
+ * @param trustedOwners the trusted trust mark owners
+ * @return true if the trust mark meets configuration, false otherwise
+ */
+ protected boolean checkTrustedIssuer(@Nullable final SignedJWT jwt,
+ @Nonnull final Map<String, List<String>> trustedIssuers,
+ @Nonnull final Map<String, Map<String, Object>> trustedOwners) {
+ if (jwt == null) {
+ return false;
+ }
+ try {
+ final JWTClaimsSet claimsSet = jwt.getJWTClaimsSet();
+ final String id = StringSupport.trimOrNull(getTrustMarkId(jwt));
+ if (id == null) {
+ return false;
+ }
+ if (trustedIssuers.containsKey(id)) {
+ final String issuer = claimsSet.getIssuer();
+ assert issuer != null;
+ final List<String> validIssuers = trustedIssuers.get(id);
+ if (validIssuers == null || !validIssuers.contains(issuer)) {
+ log.debug("{} Issuer {} is not valid trust mark issuer", getLogPrefix(), issuer);
+ return false;
+ }
+ } else if (trustedOwners.containsKey(id)) {
+ log.debug("{} Trust mark ID {} is included in trusted owners", getLogPrefix(), id);
+ if (claimsSet.getStringClaim("delegation") == null) {
+ log.debug("(} Trust mark ID {} does not contain a delegation claim", getLogPrefix(), id);
+ return false;
+ }
+ } else {
+ log.debug("{} Trust mark ID {} is not included in the trusted issuers", getLogPrefix(), id);
+ return false;
+ }
+ } catch (final ParseException e) {
+ log.error("{} Could not parse TrustMark JWT contents", getLogPrefix(), e);
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Verifies the given trust mark by exploiting (1) the trust chain cache for fetching the trust chain for the issuer
+ * entity configuration and (2) the trust engine for validating the trust mark signature.
+ *
+ * @param jwt the trust mark to be verified
+ * @param trustedOwners the trusted trust mark owners
+ * @param profileRequestContext the profile request context
+ * @return true if trust mark verification was successful, false otherwise
+ */
+ protected boolean verifyTrustMark(@Nullable final SignedJWT jwt,
+ @Nonnull final Map<String, Map<String, Object>> trustedOwners,
+ @Nonnull final ProfileRequestContext profileRequestContext) {
+ if (jwt == null) {
+ return false;
+ }
+ final JWTClaimsSet trustMarkClaims;
+ try {
+ trustMarkClaims = jwt.getJWTClaimsSet();
+ } catch (final ParseException e) {
+ log.error("{} Could not parse the TrustMark JWT contents", getLogPrefix(), e);
+ return false;
+ }
+ final String issuer = trustMarkClaims.getIssuer();
+ assert issuer != null;
+ log.debug("{} Resolving trust chain for {}", getLogPrefix(), issuer);
+ final List<List<List<EntityStatement>>> cacheResult;
+ try {
+ cacheResult = trustChainCache.get(new CriteriaSet(new SubjectEntityIDCriterion(issuer)));
+ } catch (final MetadataCacheException e) {
+ log.warn("{} Exception while fetching trust chains for {}", getLogPrefix(), issuer, e);
+ return false;
+ }
+ if (cacheResult.isEmpty() || cacheResult.get(0).isEmpty()) {
+ log.warn("{} No trust chains resolved for {}", getLogPrefix(), issuer);
+ return false;
+ }
+ final List<EntityStatement> trustMarkChain = cacheResult.get(0).get(0);
+ final EntityStatement trustMarkIssuer = trustMarkChain.get(0);
+ assert trustMarkIssuer != null;
+ final CriteriaSet criteria = new CriteriaSet(new SubjectEntityStatementCriterion(trustMarkIssuer));
+ try {
+ if (trustEngine.validate(jwt, criteria)) {
+ final String id = getTrustMarkId(jwt);
+ assert id != null;
+ log.debug("{} Successfully validated trust mark {} issued by {}", getLogPrefix(), id, issuer);
+ if (trustedOwners.containsKey(id)) {
+ return validateDelegatedTrustMark(trustMarkClaims, id, trustedOwners, profileRequestContext);
+ } else {
+ return true;
+ }
+ }
+ } catch (final SecurityException e) {
+ log.debug("{} Security exception while validating trust mark signature for {}", getLogPrefix(), issuer, e);
+ }
+ return false;
+ }
+
+ /**
+ * Validates a delegated trust mark.
+ *
+ * @param trustMarkClaims the claims set containing delegation claim
+ * @param id the trust mark identifier
+ * @param trustedOwners the trusted trust mark owners
+ * @param profileRequestContext the profile request context
+ * @return true if delegation JWT was valid, false otherwise
+ */
+ protected boolean validateDelegatedTrustMark(@Nonnull final JWTClaimsSet trustMarkClaims,
+ @Nonnull final String id,
+ @Nonnull final Map<String, Map<String, Object>> trustedOwners,
+ @Nonnull final ProfileRequestContext profileRequestContext) {
+ log.debug("{} Validating delegated trust mark {}", getLogPrefix(), id);
+ try {
+ final SignedJWT delegationJwt = SignedJWT.parse(trustMarkClaims.getStringClaim("delegation"));
+ final CriteriaSet delegationCriteria = new CriteriaSet(
+ new TrustMarkOwnersCriterion(trustedOwners),
+ new SubjectEntityIDCriterion(id));
+ if (validateClaims(delegatedTrustMarkClaimsValidator, delegationJwt, profileRequestContext)) {
+ assert delegationJwt != null;
+ if (delegationTrustEngine.validate(delegationJwt, delegationCriteria)) {
+ final String issuer = delegationJwt.getJWTClaimsSet().getIssuer();
+ log.debug("{} Successfully validated delegated {} signature issued by {}", getLogPrefix(), id,
+ issuer);
+ if (issuer != null && issuer.equals(trustMarkClaims.getSubject())) {
+ return true;
+ } else {
+ log.debug("{} The issuer of the delegation {} does not match with the subject {}",
+ getLogPrefix(), issuer, trustMarkClaims.getSubject());
+ }
+ }
+ }
+ } catch (final SecurityException e) {
+ log.debug("{} Security exception while validating trust mark signature for {}", getLogPrefix(),
+ trustMarkClaims.getIssuer(), e);
+ } catch (final ParseException e) {
+ log.debug("{} Parsing exception while processing delegated trust mark from {}", getLogPrefix(),
+ trustMarkClaims.getIssuer(), e);
+ }
+ return false;
+ }
+
+ /**
+ * Parses the trust mark ID for the given trust mark.
+ *
+ * @param trustMark the trust mark
+ * @return the ID, or null if it could not be parsed
+ */
+ @Nullable private String getTrustMarkId(@Nullable final SignedJWT trustMark) {
+ try {
+ return trustMark == null ? null : trustMark.getJWTClaimsSet().getStringClaim("trust_mark_id");
+ } catch (final ParseException e) {
+ log.error("{} Could not parse the TrustMark JWT contents", getLogPrefix(), e);
+ }
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/SelectTrustChain.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/SelectTrustChain.java
new file mode 100644
index 0000000..085ffdb
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/SelectTrustChain.java
@@ -0,0 +1,174 @@
+/*
+ * 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.oidfed.profile.impl;
+
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+
+import org.opensaml.messaging.context.navigate.ChildContextLookup;
+import org.opensaml.profile.action.ActionSupport;
+import org.opensaml.profile.action.EventIds;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.opensaml.profile.context.navigate.InboundMessageContextLookup;
+import org.slf4j.Logger;
+
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.navigate.DefaultTrustChainSelectionStrategy;
+import net.shibboleth.idp.profile.AbstractProfileAction;
+import net.shibboleth.profile.context.RelyingPartyContext;
+import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
+import net.shibboleth.shared.collection.Pair;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+/**
+ * Selects the trust chain to be used for automatic registration via configurable lookup strategy and stores it to the
+ * {@link RelyingPartyTrustChainContext}.
+ *
+ * @event {@link EventIds#PROCEED_EVENT_ID}
+ * @event {@link EventIds#INVALID_MSG_CTX}
+ *
+ * @since 4.3.0
+ */
+public class SelectTrustChain extends AbstractProfileAction {
+
+ /** Class logger. */
+ @Nonnull private Logger log = LoggerFactory.getLogger(SelectTrustChain.class);
+
+ /** Strategy used to lookup the trust chain context. */
+ @Nonnull private Function<ProfileRequestContext, RelyingPartyTrustChainContext> trustChainContextLookupStrategy;
+
+ /** Strategy used to create the relying party context where to signal the selected trust anchor. */
+ @Nonnull private Function<ProfileRequestContext, RelyingPartyContext> relyingPartyContextCreationStrategy;
+
+ /** Strategy used to fetch the selected trust chain and metadata. */
+ @NonnullAfterInit
+ private Function<ProfileRequestContext,Pair<List<EntityStatement>, Map<String,Map<String,Object>>>>
+ selectedTrustChainLookupStrategy;
+
+ /** Trust chain context to operate on. */
+ @NonnullBeforeExec private RelyingPartyTrustChainContext trustChainContext;
+
+ /**
+ * Constructor.
+ */
+ public SelectTrustChain() {
+ final Function<ProfileRequestContext, RelyingPartyTrustChainContext> tcls =
+ new ChildContextLookup<>(RelyingPartyTrustChainContext.class).compose(
+ new InboundMessageContextLookup());
+ assert tcls != null;
+ trustChainContextLookupStrategy = tcls;
+ final Function<ProfileRequestContext, RelyingPartyContext> rpccs =
+ new ChildContextLookup<>(RelyingPartyContext.class, true).compose(tcls);
+ assert rpccs != null;
+ relyingPartyContextCreationStrategy = rpccs;
+ selectedTrustChainLookupStrategy = new DefaultTrustChainSelectionStrategy();
+ }
+
+ /**
+ * Set the strategy used to return or create the {@link RelyingPartyContext}
+ *
+ * @param strategy
+ * creation strategy
+ */
+ public void setRelyingPartyContextCreationStrategy(
+ @Nonnull final Function<ProfileRequestContext, RelyingPartyContext> strategy) {
+ checkSetterPreconditions();
+ relyingPartyContextCreationStrategy = Constraint.isNotNull(strategy,
+ "RelyingPartyContext creation strategy cannot be null");
+ }
+
+ /**
+ * Set the strategy used to lookup the trust chain context.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setTrustChainContextLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext, RelyingPartyTrustChainContext> strategy) {
+ checkSetterPreconditions();
+ trustChainContextLookupStrategy =
+ Constraint.isNotNull(strategy, "TrustChainContextLookupStrategy cannot be null");
+ }
+
+ /**
+ * Set the strategy used to fetch the selected trust chain and metadata.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setSelectedTrustChainLookupStrategy(@Nonnull final
+ Function<ProfileRequestContext,Pair<List<EntityStatement>, Map<String,Map<String,Object>>>> strategy) {
+ checkSetterPreconditions();
+ selectedTrustChainLookupStrategy =
+ Constraint.isNotNull(strategy, "SelectedTrustChainLookupStrategy cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+ if (selectedTrustChainLookupStrategy == null) {
+ throw new ComponentInitializationException("Trust chain selection strategy cannot be null");
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+ if (!super.doPreExecute(profileRequestContext)) {
+ return false;
+ }
+
+ trustChainContext = trustChainContextLookupStrategy.apply(profileRequestContext);
+ if (trustChainContext == null || trustChainContext.getPolicyCompliantTrustChains() == null) {
+ log.debug("{} Unable to locate policy-compliant trust chains, nothing to do", getLogPrefix());
+ return false;
+ }
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+ final Pair<List<EntityStatement>, Map<String,Map<String,Object>>> selectedChain =
+ selectedTrustChainLookupStrategy.apply(profileRequestContext);
+
+ if (selectedChain == null || selectedChain.getFirst() == null || selectedChain.getSecond() == null) {
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MSG_CTX);
+ log.error("{} No selected trust chain could be resolved", getLogPrefix());
+ return;
+ }
+
+ final List<List<EntityStatement>> rejectedTrustChains = trustChainContext.getRejectedTrustChains();
+ if (rejectedTrustChains != null && rejectedTrustChains.contains(selectedChain.getFirst())) {
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MSG_CTX);
+ log.error("{} The selected trust chain has been previously rejected", getLogPrefix());
+ return;
+ }
+ trustChainContext.setSelectedTrustChains(selectedChain);
+ final List<EntityStatement> selectedTrustChain = selectedChain.getFirst();
+ assert selectedTrustChain != null;
+ final RelyingPartyContext relyingPartyContext =
+ relyingPartyContextCreationStrategy.apply(profileRequestContext);
+ relyingPartyContext.setRelyingPartyId(
+ selectedTrustChain.get(selectedTrustChain.size() - 1).getEntityID().getValue());
+ relyingPartyContext.setVerified(true);
+ }
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/StoreAutomaticRegistration.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/StoreAutomaticRegistration.java
new file mode 100644
index 0000000..6be3b65
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/StoreAutomaticRegistration.java
@@ -0,0 +1,190 @@
+/*
+ * 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.oidfed.profile.impl;
+
+import java.time.Instant;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+
+import org.opensaml.messaging.context.navigate.ChildContextLookup;
+import org.opensaml.profile.action.ActionSupport;
+import org.opensaml.profile.action.EventIds;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.opensaml.profile.context.navigate.InboundMessageContextLookup;
+import org.slf4j.Logger;
+
+import com.nimbusds.oauth2.sdk.id.ClientID;
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+import com.nimbusds.openid.connect.sdk.rp.OIDCClientInformation;
+import com.nimbusds.openid.connect.sdk.rp.OIDCClientMetadata;
+
+import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.navigate.DefaultSelectedTrustChainMetadataLookupStrategy;
+import net.shibboleth.idp.profile.AbstractProfileAction;
+import net.shibboleth.oidc.metadata.ClientInformationManager;
+import net.shibboleth.oidc.metadata.ClientInformationManagerException;
+import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
+import net.shibboleth.shared.collection.Pair;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+/**
+ * Stores the automatically registered client information via configurable {@link ClientInformationManager}.
+ * The client information and its expiration time are fetched from {@link RelyingPartyTrustChainContext}.
+ */
+public class StoreAutomaticRegistration extends AbstractProfileAction {
+
+ /** Class logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(StoreAutomaticRegistration.class);
+
+ /** The client information manager used for storing the information. */
+ @NonnullAfterInit private ClientInformationManager clientInformationManager;
+
+ /** Strategy used to lookup the trust chain context. */
+ @Nonnull private Function<ProfileRequestContext, RelyingPartyTrustChainContext> trustChainContextLookupStrategy;
+
+ /** Strategy used to lookup the selected metadata. */
+ @Nonnull private Function<ProfileRequestContext, OIDCClientMetadata> selectedMetadataLookupStrategy;
+
+ /** The client information to be stored. */
+ @NonnullBeforeExec private OIDCClientInformation clientInformation;
+
+ /** The expiration instant for the client informatiom. */
+ @NonnullBeforeExec private Instant expiration;
+
+ /**
+ * Constructor.
+ */
+ public StoreAutomaticRegistration() {
+ final Function<ProfileRequestContext, RelyingPartyTrustChainContext> tcls =
+ new ChildContextLookup<>(RelyingPartyTrustChainContext.class).compose(
+ new InboundMessageContextLookup());
+ assert tcls != null;
+ trustChainContextLookupStrategy = tcls;
+ selectedMetadataLookupStrategy = new DefaultSelectedTrustChainMetadataLookupStrategy();
+ }
+
+ /**
+ * Get the client information manager used for storing the information.
+ *
+ * @return The client information manager used for storing the information
+ */
+ @NonnullAfterInit public ClientInformationManager getClientInformationManager() {
+ return clientInformationManager;
+ }
+
+ /**
+ * Set the client information manager used for storing the information.
+ * @param manager The client information manager used for storing the information.
+ */
+ public void setClientInformationManager(@Nonnull final ClientInformationManager manager) {
+ ifInitializedThrowUnmodifiabledComponentException();
+ clientInformationManager = Constraint.isNotNull(manager, "The client information manager cannot be null!");
+ }
+
+ /**
+ * Set the strategy used to lookup the trust chain context.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setTrustChainContextLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext, RelyingPartyTrustChainContext> strategy) {
+ checkSetterPreconditions();
+ trustChainContextLookupStrategy =
+ Constraint.isNotNull(strategy, "TrustChainContextLookupStrategy cannot be null");
+ }
+
+ /**
+ * Set the strategy used to lookup the selected metadata.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setSelectedMetadataLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext, OIDCClientMetadata> strategy) {
+ checkSetterPreconditions();
+ selectedMetadataLookupStrategy =
+ Constraint.isNotNull(strategy, "SelectedMetadataLookupStrategy cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+
+ if (clientInformationManager == null) {
+ throw new ComponentInitializationException("ClientInformationManager cannot be null");
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+ if (!super.doPreExecute(profileRequestContext)) {
+ return false;
+ }
+
+ final RelyingPartyTrustChainContext trustChainContext =
+ trustChainContextLookupStrategy.apply(profileRequestContext);
+ if (trustChainContext == null || trustChainContext.getSelectedTrustChain() == null) {
+ log.error("{} Unable to locate selected trust chain", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MSG_CTX);
+ return false;
+ }
+
+ final OIDCClientMetadata metadata = selectedMetadataLookupStrategy.apply(profileRequestContext);
+ if (metadata == null) {
+ log.error("{} Unable to parse the RP metadata for storing", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MSG_CTX);
+ return false;
+ }
+
+ final Pair<List<EntityStatement>,Map<String,Map<String,Object>>> selectedTrustChain =
+ trustChainContext.getSelectedTrustChain();
+ assert selectedTrustChain != null;
+
+ clientInformation = new OIDCClientInformation(
+ new ClientID(selectedTrustChain.getFirst().get(0).getEntityID().getValue()), metadata);
+
+ expiration = trustChainContext.getSelectedMetadataExpiration();
+ if (expiration == null) {
+ log.error("{} Unable to resolve expiration time for the selected metadata", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MSG_CTX);
+ return false;
+ }
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+ log.debug("{} Storing automatically registered client information", getLogPrefix());
+
+ try {
+ log.debug("{} Registration will expire on {}", getLogPrefix(), expiration);
+ assert clientInformation != null;
+ clientInformationManager.storeClientInformation(clientInformation, expiration, true);
+ } catch (final ClientInformationManagerException e) {
+ log.error("{} Could not store the client information", getLogPrefix(), e);
+ ActionSupport.buildEvent(profileRequestContext, EventIds.IO_ERROR);
+ return;
+ }
+ log.info("{} Client information successfully stored for {}", getLogPrefix(),
+ clientInformation.getID().getValue());
+ }
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ValidateAutomaticRegistrationProfileConfiguration.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ValidateAutomaticRegistrationProfileConfiguration.java
new file mode 100644
index 0000000..530c3ca
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ValidateAutomaticRegistrationProfileConfiguration.java
@@ -0,0 +1,265 @@
+/*
+ * 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.oidfed.profile.impl;
+
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.profile.action.EventIds;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.opensaml.profile.context.navigate.InboundMessageContextLookup;
+import org.slf4j.Logger;
+
+import com.nimbusds.oauth2.sdk.id.ClientID;
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+import com.nimbusds.openid.connect.sdk.rp.OIDCClientInformation;
+import com.nimbusds.openid.connect.sdk.rp.OIDCClientMetadata;
+
+import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.navigate.MandatoryTrustMarksLookupFunction;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.navigate.DefaultSelectedTrustChainMetadataLookupStrategy;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.navigate.LocalMetadataPolicyLookupFunction;
+import net.shibboleth.idp.profile.AbstractProfileAction;
+import net.shibboleth.oidc.metadata.context.OIDCMetadataContext;
+import net.shibboleth.oidc.metadata.policy.MetadataPolicy;
+import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
+import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.collection.CollectionSupport;
+import net.shibboleth.shared.collection.Pair;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+import org.opensaml.messaging.context.navigate.ChildContextLookup;
+import org.opensaml.profile.action.ActionSupport;
+
+/**
+ * Resolves metadata policy-compliant trust chains from the configurable trust chain cache, metadata policy merging
+ * strategy and enforcer. The data is populated to the {@link RelyingPartyTrustChainContext}.
+ *
+ * @event {@link EventIds#PROCEED_EVENT_ID}
+ * @event {@link EventIds#INVALID_MSG_CTX}
+ * @event {@link ValidateAutomaticRegistrationProfileConfiguration#RESELECT_TRUST_CHAIN}
+ *
+ * @since 4.3.0
+ */
+public class ValidateAutomaticRegistrationProfileConfiguration extends AbstractProfileAction {
+
+ /** ID of event returned if a flow wishes to indicate that another trust chain should be selected instead. */
+ @Nonnull @NotEmpty public static final String RESELECT_TRUST_CHAIN = "ReselectTrustChain";
+
+ /** Class logger. */
+ @Nonnull private Logger log = LoggerFactory.getLogger(ValidateAutomaticRegistrationProfileConfiguration.class);
+
+ /** Strategy used to lookup the trust chain context. */
+ @Nonnull private Function<ProfileRequestContext, RelyingPartyTrustChainContext> trustChainContextLookupStrategy;
+
+ /** Strategy used to lookup the selected metadata. */
+ @Nonnull private Function<ProfileRequestContext, OIDCClientMetadata> selectedMetadataLookupStrategy;
+
+ /** Strategy used to lookup mandatory trust marks. */
+ @Nonnull private Function<ProfileRequestContext, List<String>> mandatoryTrustMarksLookupStrategy;
+
+ /** Strategy used to lookup local metadata policy to be merged to the client metadata. */
+ @Nonnull private Function<ProfileRequestContext, Map<String, MetadataPolicy>> localMetadataPolicyLookupStrategy;
+
+ /** Strategy used to merge local metadata policy into the client metadata. */
+ @NonnullAfterInit private BiFunction<OIDCClientInformation,Map<String, MetadataPolicy>,OIDCClientInformation>
+ localMetadataPolicyMergingStrategy;
+
+ /** Trust chain context to operate on. */
+ @NonnullBeforeExec private RelyingPartyTrustChainContext trustChainContext;
+
+ /** Selected trust chain to operate on. */
+ @NonnullBeforeExec private Pair<List<EntityStatement>, Map<String,Map<String,Object>>> selectedTrustChain;
+
+ /**
+ * Constructor.
+ */
+ public ValidateAutomaticRegistrationProfileConfiguration() {
+ final Function<ProfileRequestContext, RelyingPartyTrustChainContext> tcls =
+ new ChildContextLookup<>(RelyingPartyTrustChainContext.class).compose(
+ new InboundMessageContextLookup());
+ assert tcls != null;
+ trustChainContextLookupStrategy = tcls;
+ selectedMetadataLookupStrategy = new DefaultSelectedTrustChainMetadataLookupStrategy();
+ mandatoryTrustMarksLookupStrategy = new MandatoryTrustMarksLookupFunction();
+ localMetadataPolicyLookupStrategy = new LocalMetadataPolicyLookupFunction();
+ }
+
+ /**
+ * Set the strategy used to lookup the trust chain context.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setTrustChainContextLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext, RelyingPartyTrustChainContext> strategy) {
+ checkSetterPreconditions();
+ trustChainContextLookupStrategy =
+ Constraint.isNotNull(strategy, "TrustChainContextLookupStrategy cannot be null");
+ }
+
+ /**
+ * Set the strategy used to lookup the selected metadata.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setSelectedMetadataLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext, OIDCClientMetadata> strategy) {
+ checkSetterPreconditions();
+ selectedMetadataLookupStrategy =
+ Constraint.isNotNull(strategy, "SelectedMetadataLookupStrategy cannot be null");
+ }
+
+ /**
+ * Set the strategy used to lookup mandatory trust marks.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setMandatoryTrustMarksLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext, List<String>> strategy) {
+ checkSetterPreconditions();
+ mandatoryTrustMarksLookupStrategy = Constraint.isNotNull(strategy,
+ "Mandatory trust marks lookup strategy cannot be null");
+ }
+
+ /**
+ * Set the strategy used to lookup local metadata policy to be merged to the client metadata.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setLocalMetadataPolicyLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext, Map<String, MetadataPolicy>> strategy) {
+ checkSetterPreconditions();
+ localMetadataPolicyLookupStrategy = Constraint.isNotNull(strategy,
+ "Local metadata policy lookup strategy cannot be null");
+ }
+
+ /**
+ * Set the strategy used to merge local metadata policy into the client metadata.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setLocalMetadataPolicyMergingStrategy(@Nonnull
+ final BiFunction<OIDCClientInformation,Map<String, MetadataPolicy>,OIDCClientInformation> strategy) {
+ checkSetterPreconditions();
+ localMetadataPolicyMergingStrategy =
+ Constraint.isNotNull(strategy, "Local metadata policy merging strategy cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+ if (!super.doPreExecute(profileRequestContext)) {
+ return false;
+ }
+
+ trustChainContext = trustChainContextLookupStrategy.apply(profileRequestContext);
+ if (trustChainContext == null || trustChainContext.getSelectedTrustChain() == null) {
+ log.error("{} Unable to locate selected trust chain", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MSG_CTX);
+ return false;
+ }
+
+ selectedTrustChain = trustChainContext.getSelectedTrustChain();
+ assert selectedTrustChain != null;
+ if (selectedTrustChain.getFirst() == null || selectedTrustChain.getSecond() == null) {
+ log.error("{} Selected trust chain contents is not populated", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MSG_CTX);
+ return false;
+ }
+
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+ final OIDCClientMetadata metadata = selectedMetadataLookupStrategy.apply(profileRequestContext);
+ if (metadata == null) {
+ log.error("{} Unable to parse the RP metadata for storing", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MSG_CTX);
+ return;
+ }
+ final OIDCClientInformation clientInformation = new OIDCClientInformation(
+ new ClientID(selectedTrustChain.getFirst().get(0).getEntityID().getValue()), metadata);
+
+ final Map<String, MetadataPolicy> localMetadataPolicy =
+ localMetadataPolicyLookupStrategy.apply(profileRequestContext);
+ if (localMetadataPolicy != null && !localMetadataPolicy.isEmpty()) {
+ log.debug("{} Applying local metadata policy into the client metadata", getLogPrefix());
+ final OIDCClientInformation enforcedMetadata =
+ localMetadataPolicyMergingStrategy.apply(clientInformation, localMetadataPolicy);
+ if (enforcedMetadata == null) {
+ log.error("{} Could not apply the local metadata policy into the client metadata", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MSG_CTX);
+ return;
+ }
+ selectedTrustChain.setSecond(Map.of("openid_relying_party", clientInformation.toJSONObject()));
+ }
+ final String clientId = clientInformation.getID().getValue();
+ final List<String> mandatoryTrustMarks = mandatoryTrustMarksLookupStrategy.apply(profileRequestContext);
+ if (mandatoryTrustMarks != null && !mandatoryTrustMarks.isEmpty()) {
+ log.debug("{} Verifying the mandatory trust marks {}", getLogPrefix(), mandatoryTrustMarks);
+ final Map<String,List<String>> verifiedTrustMarks = trustChainContext.getVerifiedTrustMarkIds();
+ if (verifiedTrustMarks == null || verifiedTrustMarks.get(clientId) == null
+ || !verifiedTrustMarks.get(clientId).containsAll(mandatoryTrustMarks)) {
+ log.info("{} Rejecting registration as some of the following mandatory trust marks are missing: {}",
+ getLogPrefix(), mandatoryTrustMarks);
+ final List<List<EntityStatement>> rejectedTrustChains = trustChainContext.getRejectedTrustChains();
+ if (rejectedTrustChains == null) {
+ trustChainContext.setRejectedTrustChains(List.of(selectedTrustChain.getFirst()));
+ } else {
+ final List<List<EntityStatement>> rejectedChains = new ArrayList<>(rejectedTrustChains);
+ rejectedChains.add(selectedTrustChain.getFirst());
+ trustChainContext.setRejectedTrustChains(CollectionSupport.copyToList(rejectedChains));
+ }
+ ActionSupport.buildEvent(profileRequestContext, RESELECT_TRUST_CHAIN);
+ return;
+ }
+ }
+
+ final List<EntityStatement> trustChain = selectedTrustChain.getFirst();
+ assert trustChain != null;
+ trustChainContext.setSelectedMetadataExpiration(resolveTrustChainExpiration(trustChain));
+
+ final OIDCMetadataContext oidcCtx = new OIDCMetadataContext();
+ oidcCtx.setClientInformation(clientInformation);
+ profileRequestContext.ensureInboundMessageContext().addSubcontext(oidcCtx);
+ log.debug("{} Client information attached to the OIDCMetadataContext", getLogPrefix());
+ }
+
+ /**
+ * Resolve expiration time for the given trust chain.
+ *
+ * @param trustChain trust chain
+ * @return expiration time
+ */
+ @Nullable private Instant resolveTrustChainExpiration(@Nonnull final List<EntityStatement> trustChain) {
+ Instant metadataExpiration = null;
+ for (final EntityStatement statement : trustChain) {
+ final Instant statementExpiration = statement.getClaimsSet().getExpirationTime().toInstant();
+ metadataExpiration = metadataExpiration == null ? statementExpiration :
+ statementExpiration.isBefore(metadataExpiration) ? statementExpiration : metadataExpiration;
+ }
+ return metadataExpiration;
+ }
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ValidateProvidedTrustChain.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ValidateProvidedTrustChain.java
new file mode 100644
index 0000000..36384ec
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ValidateProvidedTrustChain.java
@@ -0,0 +1,144 @@
+/*
+ * 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.oidfed.profile.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.function.BiPredicate;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+
+import org.opensaml.profile.action.EventIds;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.slf4j.Logger;
+
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
+import net.shibboleth.shared.collection.CollectionSupport;
+import net.shibboleth.shared.collection.Pair;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+import org.opensaml.profile.action.ActionSupport;
+
+/**
+ * Validates the provided trust chain and enforces metadata policy merging
+ * strategy and enforcer. The data is populated to the {@link RelyingPartyTrustChainContext}.
+ *
+ * @event {@link EventIds#PROCEED_EVENT_ID}
+ * @event {@link EventIds#INVALID_MSG_CTX}
+ *
+ * @since 4.3.0
+ */
+public class ValidateProvidedTrustChain extends AbstractTrustChainResolutionAction {
+
+ /** Class logger. */
+ @Nonnull private Logger log = LoggerFactory.getLogger(ValidateProvidedTrustChain.class);
+
+ /** Strategy used to validate provided trust chain. */
+ @NonnullAfterInit
+ private BiPredicate<ProfileRequestContext, List<EntityStatement>> providedTrustChainValidationStrategy;
+
+ /** Strategy used to locate the provided trust chain. */
+ @NonnullAfterInit private Function<ProfileRequestContext, List<EntityStatement>> providedTrustChainLookupStrategy;
+
+ /** Trust chain to operate on. */
+ @NonnullBeforeExec private List<EntityStatement> trustChain;
+
+ /**
+ * Set the strategy used to locate the provided trust chain.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setProvidedTrustChainLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext, List<EntityStatement>> strategy) {
+ providedTrustChainLookupStrategy =
+ Constraint.isNotNull(strategy, "ProvidedTrustChainLookupStrategy cannot be null");
+ }
+
+ /**
+ * Set the strategy used to validate provided trust chain.
+ *
+ * @param strategy validation strategy
+ */
+ public void setProvidedTrustChainValidationStrategy(
+ @Nonnull final BiPredicate<ProfileRequestContext, List<EntityStatement>> strategy) {
+ checkSetterPreconditions();
+ providedTrustChainValidationStrategy =
+ Constraint.isNotNull(strategy, "ProvidedTrustChainValidationStrategy cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+
+ if (providedTrustChainLookupStrategy == null) {
+ throw new ComponentInitializationException("ProvidedTrustChainLookupStrategy cannot be null");
+ }
+ if (providedTrustChainValidationStrategy == null) {
+ throw new ComponentInitializationException("ProvidedTrustChainValidationStrategy cannot be null");
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+ if (!super.doPreExecute(profileRequestContext)) {
+ return false;
+ }
+ trustChain = providedTrustChainLookupStrategy.apply(profileRequestContext);
+ if (trustChain == null) {
+ log.error("{} Unable to fetch trust chain", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MSG_CTX);
+ return false;
+ }
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+ if (!providedTrustChainValidationStrategy.test(profileRequestContext, trustChain)) {
+ log.error("{} The trust chain validation failed", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MSG_CTX);
+ return;
+ }
+
+ final RelyingPartyTrustChainContext trustChainContext =
+ getTrustChainContextCreationStrategy().apply(profileRequestContext);
+ assert trustChain != null;
+ trustChainContext.setResolvedTrustChains(CollectionSupport.listOf(trustChain));
+ final List<Pair<List<EntityStatement>, Map<String,Map<String,Object>>>> policyCompliantChains =
+ new ArrayList<>();
+
+ final String errorEventId = populatePolicyComplaintChains(trustChain, policyCompliantChains);
+ if (errorEventId != null) {
+ log.error("{} The request metadata is not compliant with the merged policy", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, errorEventId);
+ return;
+ }
+
+ log.debug("{} Setting the policy compliant trust chains into the context: {}", getLogPrefix(),
+ policyCompliantChains);
+ trustChainContext.setPolicyCompliantTrustChains(policyCompliantChains);
+ }
+
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ValidateResolveEntityRequest.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ValidateResolveEntityRequest.java
new file mode 100644
index 0000000..49cc1a1
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ValidateResolveEntityRequest.java
@@ -0,0 +1,187 @@
+/*
+ * 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.oidfed.profile.impl;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.messaging.context.navigate.ChildContextLookup;
+import org.opensaml.profile.action.ActionSupport;
+import org.opensaml.profile.action.EventIds;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.opensaml.profile.context.navigate.InboundMessageContextLookup;
+import org.slf4j.Logger;
+
+import com.nimbusds.oauth2.sdk.Request;
+
+import net.shibboleth.idp.plugin.oidc.op.oidfed.messaging.impl.ResolveEntityRequest;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.LocalKeyContainer;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.SubjectEntityIDCriterion;
+import net.shibboleth.idp.profile.AbstractProfileAction;
+import net.shibboleth.oidc.metadata.cache.MetadataCache;
+import net.shibboleth.oidc.metadata.cache.MetadataCacheException;
+import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.primitive.StringSupport;
+import net.shibboleth.shared.resolver.CriteriaSet;
+
+/**
+ * Validates the resolve entity request against the profile configuration and stores the validated (possibly modified)
+ * request into {@link RelyingPartyCachedMessageContext#setValidatedRequest(Request)}.
+ *
+ * @event {@link EventIds#PROCEED_EVENT_ID}
+ * @event {@link EventIds#INVALID_MSG_CTX}
+ *
+ * @since 4.3.0
+ */
+public class ValidateResolveEntityRequest extends AbstractProfileAction {
+
+ /** Class logger. */
+ @Nonnull private Logger log = LoggerFactory.getLogger(ValidateResolveEntityRequest.class);
+
+ /** Strategy used to create the cached message context. */
+ @Nonnull
+ private Function<ProfileRequestContext, RelyingPartyCachedMessageContext> cachedMessageContextCreationStrategy;
+
+ /** Cache containing local copies of trusted trust anchor keys. */
+ @NonnullAfterInit private MetadataCache<Map<String, LocalKeyContainer>> localTrustAnchorsCache;
+
+ /** Request message to operate on. */
+ @NonnullBeforeExec private ResolveEntityRequest requestMessage;
+
+ /** Cached message context to operate on. */
+ @NonnullBeforeExec private RelyingPartyCachedMessageContext cachedMessageContext;
+
+ /**
+ * Constructor.
+ */
+ public ValidateResolveEntityRequest() {
+ final Function<ProfileRequestContext, RelyingPartyCachedMessageContext> reccs =
+ new ChildContextLookup<>(RelyingPartyCachedMessageContext.class, true).compose(
+ new InboundMessageContextLookup());
+ assert reccs != null;
+ cachedMessageContextCreationStrategy = reccs;
+ }
+
+ /**
+ * Set the strategy used to return or create the resolve entity context.
+ *
+ * @param strategy creation strategy
+ */
+ public void setResolveEntityContextCreationStrategy(
+ @Nonnull final Function<ProfileRequestContext, RelyingPartyCachedMessageContext> strategy) {
+ checkSetterPreconditions();
+ cachedMessageContextCreationStrategy = Constraint.isNotNull(strategy,
+ "RelyingPartyResolveEntityContext creation strategy cannot be null");
+ }
+
+ /**
+ * Set the strategy used to lookup the trust chain context.
+ *
+ * @param cache lookup strategy
+ */
+ public void setLocalTrustAnchorsCache(
+ @Nonnull final MetadataCache<Map<String, LocalKeyContainer>> cache) {
+ checkSetterPreconditions();
+ localTrustAnchorsCache =
+ Constraint.isNotNull(cache, "LocalTrustAnchorsCache cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+ if (localTrustAnchorsCache == null) {
+ throw new ComponentInitializationException("LocalTrustAnchorsCache cannot be null");
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+ if (!super.doPreExecute(profileRequestContext)) {
+ return false;
+ }
+
+ requestMessage = Optional.ofNullable(profileRequestContext.getInboundMessageContext())
+ .map(messageContext -> messageContext.getMessage())
+ .filter(ResolveEntityRequest.class::isInstance)
+ .map(ResolveEntityRequest.class::cast)
+ .orElse(null);
+ if (requestMessage == null) {
+ log.error("{} Unable to fetch the request message to operate on", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
+ return false;
+ }
+
+ cachedMessageContext = cachedMessageContextCreationStrategy.apply(profileRequestContext);
+ if (cachedMessageContext == null) {
+ log.error("{} Unable to create resolve entity context", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
+ return false;
+ }
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+ final List<String> validatedAnchors = requestMessage.getTrustAnchors().stream()
+ .filter(anchor -> isLocallyTrusted(anchor))
+ .toList();
+ if (validatedAnchors.isEmpty()) {
+ log.info("{} No locally trusted anchors left after filtering", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, OidFederationEventIds.INVALID_TRUST_ANCHOR);
+ return;
+ }
+ log.debug("{} The following trust anchors were validated: {}", getLogPrefix(), validatedAnchors);
+ cachedMessageContext.setValidatedRequest(
+ new ResolveEntityRequest(requestMessage.getEndpointURI(), requestMessage.getSubject(),
+ validatedAnchors, requestMessage.getEntityTypes()));
+ }
+
+ /**
+ * Verifies whether the given trust anchor candidate is locally trusted.
+ *
+ * @param candidate the trust anchor candidate
+ * @return true if locally trusted, false otherwise
+ */
+ protected boolean isLocallyTrusted(@Nullable final String candidate) {
+ if (StringSupport.trimOrNull(candidate) == null) {
+ return false;
+ }
+ assert candidate != null;
+ final SubjectEntityIDCriterion criterion = new SubjectEntityIDCriterion(candidate);
+ try {
+ final List<Map<String,LocalKeyContainer>> result = localTrustAnchorsCache.get(new CriteriaSet(criterion));
+ if (result == null || result.isEmpty() || result.get(0).isEmpty()) {
+ log.debug("{} No locally trusted keys found for {}", getLogPrefix(), candidate);
+ return false;
+ }
+ return result.get(0).containsKey(candidate);
+ } catch (final MetadataCacheException e) {
+ log.error("{} Could not fetch value for {} from the metadata cache", getLogPrefix(), candidate, e);
+ }
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ValidateSelectedTrustChain.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ValidateSelectedTrustChain.java
new file mode 100644
index 0000000..bd5038f
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ValidateSelectedTrustChain.java
@@ -0,0 +1,231 @@
+/*
+ * 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.oidfed.profile.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+
+import org.opensaml.profile.action.EventIds;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.opensaml.profile.context.navigate.InboundMessageContextLookup;
+import org.slf4j.Logger;
+
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import net.shibboleth.idp.plugin.oidc.op.oidfed.messaging.impl.ResolveEntityRequest;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.SubjectEntityIDCriterion;
+import net.shibboleth.idp.profile.AbstractProfileAction;
+import net.shibboleth.oidc.metadata.cache.MetadataCache;
+import net.shibboleth.oidc.metadata.cache.MetadataCacheException;
+import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
+import net.shibboleth.shared.collection.CollectionSupport;
+import net.shibboleth.shared.collection.Pair;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.resolver.CriteriaSet;
+
+import org.opensaml.messaging.context.navigate.ChildContextLookup;
+import org.opensaml.profile.action.ActionSupport;
+
+/**
+ * Validates that the currenty selected trust chain meets the trust anchor requirements in the resolve entity request.
+ * If not and if other candidates remains, {@link OidFederationEventIds#RESELECT_TRUST_CHAIN} is published. If no other
+ * candidates are available, {@link OidFederationEventIds#INVALID_TRUST_ANCHOR} or
+ * {@link OidFederationEventIds#INVALID_SUBJECT} is published.
+ *
+ * @event {@link EventIds#PROCEED_EVENT_ID}
+ * @event {@link EventIds#INVALID_MSG_CTX}
+ * @event {@link OidFederationEventIds#RESELECT_TRUST_CHAIN}
+ * @event {@link OidFederationEventIds#INVALID_TRUST_ANCHOR}
+ * @event {@link OidFederationEventIds#INVALID_SUBJECT}
+ *
+ * @since 4.3.0
+ */
+public class ValidateSelectedTrustChain extends AbstractProfileAction {
+
+ /** Class logger. */
+ @Nonnull private Logger log = LoggerFactory.getLogger(ValidateSelectedTrustChain.class);
+
+ /** Metadata cache for entity configurations. */
+ @NonnullAfterInit private MetadataCache<EntityStatement> entityConfigurationCache;
+
+ /** Strategy used to lookup the trust chain context. */
+ @Nonnull private Function<ProfileRequestContext, RelyingPartyTrustChainContext> trustChainContextLookupStrategy;
+
+ /** Strategy used to locate the resolve entity context. */
+ @Nonnull
+ private Function<ProfileRequestContext, RelyingPartyCachedMessageContext> resolveEntityContextLookupStrategy;
+
+ /** The validated request to operate on. */
+ @NonnullBeforeExec private ResolveEntityRequest validatedRequest;
+
+ /**
+ * Constructor.
+ */
+ public ValidateSelectedTrustChain() {
+ final Function<ProfileRequestContext, RelyingPartyTrustChainContext> tcls =
+ new ChildContextLookup<>(RelyingPartyTrustChainContext.class).compose(
+ new InboundMessageContextLookup());
+ assert tcls != null;
+ trustChainContextLookupStrategy = tcls;
+ final Function<ProfileRequestContext, RelyingPartyCachedMessageContext> recls =
+ new ChildContextLookup<>(RelyingPartyCachedMessageContext.class).compose(
+ new InboundMessageContextLookup());
+ assert recls != null;
+ resolveEntityContextLookupStrategy = recls;
+ }
+
+ /**
+ * Set the metadata cache for entity configurations.
+ *
+ * @param cache What to set.
+ */
+ public void setEntityConfigurationCache(@Nonnull final MetadataCache<EntityStatement> cache) {
+ checkSetterPreconditions();
+ entityConfigurationCache = Constraint.isNotNull(cache, "Entity configuration metadata cache cannot be null");
+ }
+
+ /**
+ * Set the strategy used to lookup the trust chain context.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setTrustChainContextLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext, RelyingPartyTrustChainContext> strategy) {
+ checkSetterPreconditions();
+ trustChainContextLookupStrategy =
+ Constraint.isNotNull(strategy, "TrustChainContextLookupStrategy cannot be null");
+ }
+
+ /**
+ * Set the strategy used to locate the resolve entity context
+ *
+ * @param strategy What to set.
+ */
+ public void setResolveEntityContextLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext,RelyingPartyCachedMessageContext> strategy) {
+ checkSetterPreconditions();
+ resolveEntityContextLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null!");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+
+ if (entityConfigurationCache == null) {
+ throw new ComponentInitializationException("Entity configuration metadata cache cannot be null");
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+ if (!super.doPreExecute(profileRequestContext)) {
+ return false;
+ }
+
+ final RelyingPartyCachedMessageContext cachedResponseContext =
+ resolveEntityContextLookupStrategy.apply(profileRequestContext);
+ if (cachedResponseContext == null) {
+ log.error("{} Could not resolve cached message context", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
+ return false;
+ }
+
+ if (cachedResponseContext.getValidatedRequest() instanceof ResolveEntityRequest resolveEntityRequest) {
+ validatedRequest = resolveEntityRequest;
+ } else {
+ log.error("{} Could not resolve request message", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
+ return false;
+ }
+
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+ final RelyingPartyTrustChainContext trustChainContext =
+ trustChainContextLookupStrategy.apply(profileRequestContext);
+ final Pair<List<EntityStatement>, Map<String,Map<String,Object>>> selectedTrustChain =
+ trustChainContext != null ? trustChainContext.getSelectedTrustChain() : null;
+ if (selectedTrustChain == null || selectedTrustChain.getFirst() == null) {
+ final List<Pair<List<EntityStatement>,Map<String,Map<String,Object>>>> allChains =
+ trustChainContext != null ? trustChainContext.getPolicyCompliantTrustChains() : null;
+ if (allChains == null || allChains.isEmpty()) {
+ if (isSubjectValid(validatedRequest.getSubject())) {
+ log.debug("{} No trust chains were resolved, subject is valid", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, OidFederationEventIds.INVALID_TRUST_ANCHOR);
+ return;
+ } else {
+ log.debug("{} No trust chains were resolved, subject is not valid", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, OidFederationEventIds.INVALID_SUBJECT);
+ return;
+ }
+ } else {
+ log.debug("{} No trust chains left to choose from", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, OidFederationEventIds.INVALID_TRUST_ANCHOR);
+ return;
+ }
+ }
+
+ final List<String> trustAnchors = validatedRequest.getTrustAnchors();
+ final List<EntityStatement> candidateChain = selectedTrustChain.getFirst();
+ assert candidateChain != null;
+ final String candidateAnchor = candidateChain.get(candidateChain.size() - 1).getEntityID().getValue();
+ if (!trustAnchors.contains(candidateAnchor)) {
+ log.debug("{} Selected trust chain candidate has unrequested trust anchor {}", getLogPrefix(),
+ candidateAnchor);
+ assert trustChainContext != null;
+ final List<List<EntityStatement>> rejectedTrustChains = trustChainContext.getRejectedTrustChains();
+ if (rejectedTrustChains == null) {
+ trustChainContext.setRejectedTrustChains(List.of(selectedTrustChain.getFirst()));
+ } else {
+ final List<List<EntityStatement>> rejectedChains = new ArrayList<>(rejectedTrustChains);
+ rejectedChains.add(selectedTrustChain.getFirst());
+ trustChainContext.setRejectedTrustChains(CollectionSupport.copyToList(rejectedChains));
+ }
+ ActionSupport.buildEvent(profileRequestContext, OidFederationEventIds.RESELECT_TRUST_CHAIN);
+ return;
+ }
+ }
+
+ /**
+ * Checks if an entity configuration can be resolved for the given subject and it's thus valid for federation.
+ *
+ * @param subject the subject to be verified
+ * @return true if the given subject is valid, false otherwise.
+ */
+ protected boolean isSubjectValid(@Nonnull final String subject) {
+ final SubjectEntityIDCriterion subjectCriterion = new SubjectEntityIDCriterion(subject);
+ try {
+ final List<EntityStatement> result = entityConfigurationCache.get(new CriteriaSet(subjectCriterion));
+ if (result.size() == 1) {
+ return true;
+ }
+ } catch (final MetadataCacheException e) {
+ log.debug("{} Exception catched when resolving entty configuration", e);
+ }
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/logic/DefaultAutomaticRegistrationActivationCondition.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/logic/DefaultAutomaticRegistrationActivationCondition.java
new file mode 100644
index 0000000..8c7b958
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/logic/DefaultAutomaticRegistrationActivationCondition.java
@@ -0,0 +1,87 @@
+/*
+ * 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.oidfed.profile.logic;
+
+import java.util.Map;
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.component.AbstractIdentifiableInitializableComponent;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.logic.Constraint;
+
+/**
+ * Default condition for automatic registration: activation is done via configurable map of predicates per profile.
+ */
+public class DefaultAutomaticRegistrationActivationCondition extends AbstractIdentifiableInitializableComponent
+ implements Predicate<ProfileRequestContext > {
+
+ /** The lookup strategy to obtain profile ID. */
+ @NonnullAfterInit private Function<ProfileRequestContext, String> profileIdLookupStrategy;
+
+ /** The map of conditions per profile. */
+ @NonnullAfterInit private Map<String, Predicate<ProfileRequestContext>> profileConditions;
+
+ /**
+ * Set the lookup strategy to obtain profile ID.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setProfileIdLookupStrategy(@Nonnull final Function<ProfileRequestContext, String> strategy) {
+ checkSetterPreconditions();
+ profileIdLookupStrategy = Constraint.isNotNull(strategy, "ProfileIdLookupStrategy cannot be null");
+ }
+
+ /**
+ * Set the map of conditions per profile.
+ *
+ * @param conditions map of conditions
+ */
+ public void setProfileConditions(@Nonnull final Map<String, Predicate<ProfileRequestContext>> conditions) {
+ checkSetterPreconditions();
+ profileConditions = Constraint.isNotNull(conditions, "ProfileConditions cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+
+ if (profileIdLookupStrategy == null) {
+ throw new ComponentInitializationException("ProfileIdLookupStrategy cannot be null");
+ }
+ if (profileConditions == null) {
+ throw new ComponentInitializationException("ProfileConditions cannot be null");
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean test(@Nullable final ProfileRequestContext profileRequestContext) {
+ return Optional.ofNullable(profileRequestContext)
+ .map(prc -> profileIdLookupStrategy.apply(prc))
+ .map(profileId -> profileConditions.get(profileId))
+ .map(condition -> condition.test(profileRequestContext))
+ .orElse(false);
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/AbstractTrustChainContextLookupFunction.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/AbstractTrustChainContextLookupFunction.java
new file mode 100644
index 0000000..1c6bcb6
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/AbstractTrustChainContextLookupFunction.java
@@ -0,0 +1,83 @@
+/*
+ * 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.oidfed.profile.navigate;
+
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.messaging.context.navigate.ChildContextLookup;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.opensaml.profile.context.navigate.InboundMessageContextLookup;
+import org.slf4j.Logger;
+
+import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.RelyingPartyTrustChainContext;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+/**
+ * An abstract function for lookup functions dealing with {@link RelyingPartyTrustChainContext}.
+ *
+ * @param <T> The return type of the lookup function
+ */
+public abstract class AbstractTrustChainContextLookupFunction<T> implements Function<ProfileRequestContext, T> {
+
+ /** Class logger. */
+ @Nonnull private Logger log = LoggerFactory.getLogger(AbstractTrustChainContextLookupFunction.class);
+
+ /** Strategy used to locate the trust chain context. */
+ @Nonnull private Function<ProfileRequestContext, RelyingPartyTrustChainContext> trustChainContextLookupStrategy;
+
+ /**
+ * Constructor.
+ */
+ public AbstractTrustChainContextLookupFunction() {
+ final Function<ProfileRequestContext, RelyingPartyTrustChainContext> tcls =
+ new ChildContextLookup<>(RelyingPartyTrustChainContext.class).compose(
+ new InboundMessageContextLookup());
+ assert tcls != null;
+ trustChainContextLookupStrategy = tcls;
+ }
+
+ /**
+ * Set the strategy used to locate the trust chain context.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setTrustChainContextLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext, RelyingPartyTrustChainContext> strategy) {
+ trustChainContextLookupStrategy =
+ Constraint.isNotNull(strategy, "TrustChainContextLookupStrategy cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override @Nullable public T apply(@Nullable final ProfileRequestContext input) {
+ final RelyingPartyTrustChainContext trustChainContext = trustChainContextLookupStrategy.apply(input);
+ if (trustChainContext == null) {
+ log.error("Could not resolve trust chain context");
+ return null;
+ }
+ return doApply(trustChainContext);
+ }
+
+ /**
+ * Perform the lookup operation on the {@link RelyingPartyTrustChainContext}.
+ *
+ * @param trustChainContext the context, guaranteed to be non-null
+ * @return result
+ */
+ @Nullable protected abstract T doApply(@Nonnull final RelyingPartyTrustChainContext trustChainContext);
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/AuthorityHintsLookupFunction.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/AuthorityHintsLookupFunction.java
new file mode 100644
index 0000000..8db21f0
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/AuthorityHintsLookupFunction.java
@@ -0,0 +1,48 @@
+/*
+ * 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.oidfed.profile.navigate;
+
+import java.util.List;
+
+import javax.annotation.Nullable;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import net.shibboleth.profile.config.ProfileConfiguration;
+import net.shibboleth.profile.context.RelyingPartyContext;
+import net.shibboleth.profile.context.navigate.AbstractRelyingPartyLookupFunction;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.config.OIDFederationEntityConfigurationProfileConfiguration;
+
+/**
+ * A function that obtains {@link OIDFederationEntityConfigurationProfileConfiguration#getAuthorityHints(ProfileRequestContext)}.
+ *
+ * <p>If a specific setting is unavailable, a null value is returned.</p>
+ */
+public class AuthorityHintsLookupFunction extends AbstractRelyingPartyLookupFunction<List<String>> {
+
+ /** {@inheritDoc} */
+ @Override
+ @Nullable public List<String> apply(@Nullable final ProfileRequestContext input) {
+ final RelyingPartyContext rpc = getRelyingPartyContextLookupStrategy().apply(input);
+ if (rpc != null) {
+ final ProfileConfiguration pc = rpc.getProfileConfig();
+ if (pc instanceof OIDFederationEntityConfigurationProfileConfiguration ofec) {
+ return ofec.getAuthorityHints(input);
+ }
+ }
+ return null;
+ }
+
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultAuthorizePreSelectedTrustChainIDsLookupStrategy.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultAuthorizePreSelectedTrustChainIDsLookupStrategy.java
new file mode 100644
index 0000000..228abe7
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultAuthorizePreSelectedTrustChainIDsLookupStrategy.java
@@ -0,0 +1,49 @@
+/*
+ * 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.oidfed.profile.navigate;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.function.Function;
+
+import javax.annotation.Nullable;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import net.shibboleth.idp.plugin.oidc.op.oauth2.messaging.context.OAuth2PushedAuthorizationRequestContext;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.support.ClaimsSetExtensionSupport;
+
+/**
+ * Default strategy for looking up the entity IDs of the previously selected trust chain to be used in the authorization
+ * endpoint. The selected trust chain is fetched via {@link OAuth2PushedAuthorizationRequestContext#getClaimsSet()}.
+ */
+public class DefaultAuthorizePreSelectedTrustChainIDsLookupStrategy
+ implements Function<ProfileRequestContext,List<String>> {
+
+ /** {@inheritDoc} */
+ @Override @Nullable
+ public List<String> apply(@Nullable final ProfileRequestContext input) {
+ return Optional.ofNullable(input)
+ .filter(prc -> prc.getInboundMessageContext() != null)
+ .map(prc -> prc.ensureInboundMessageContext())
+ .filter(msgCtx -> msgCtx.containsSubcontext(OAuth2PushedAuthorizationRequestContext.class))
+ .map(msgCtx -> msgCtx.ensureSubcontext(OAuth2PushedAuthorizationRequestContext.class))
+ .map(parCtx -> parCtx.getClaimsSet())
+ .filter(Objects::nonNull)
+ .map(ClaimsSetExtensionSupport::parseAutoRegisteredTrustChain)
+ .orElse(null);
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultEntityTypesLookupFunction.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultEntityTypesLookupFunction.java
new file mode 100644
index 0000000..7ba6c81
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultEntityTypesLookupFunction.java
@@ -0,0 +1,46 @@
+/*
+ * 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.oidfed.profile.navigate;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.function.Function;
+
+import javax.annotation.Nullable;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import net.shibboleth.idp.plugin.oidc.op.oidfed.messaging.impl.ResolveEntityRequest;
+import net.shibboleth.shared.collection.CollectionSupport;
+import net.shibboleth.shared.primitive.NonnullSupplier;
+
+/**
+ * Default function to lookup entity types to be included to the response metadata.
+ */
+public class DefaultEntityTypesLookupFunction implements Function<ProfileRequestContext, List<String>> {
+
+ /** {@inheritDoc} */
+ @Override @Nullable
+ public List<String> apply(@Nullable final ProfileRequestContext profileRequestContext) {
+ return Optional.ofNullable(profileRequestContext)
+ .map(prc -> prc.getInboundMessageContext())
+ .map(msgCtx -> msgCtx.getMessage())
+ .filter(ResolveEntityRequest.class::isInstance)
+ .map(ResolveEntityRequest.class::cast)
+ .map(req -> req.getEntityTypes())
+ .orElseGet(NonnullSupplier.of(CollectionSupport.emptyList()));
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultLocalMetadataPolicyMergingStrategy.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultLocalMetadataPolicyMergingStrategy.java
new file mode 100644
index 0000000..684aa0d
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultLocalMetadataPolicyMergingStrategy.java
@@ -0,0 +1,112 @@
+/*
+ * 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.oidfed.profile.navigate;
+
+import java.util.Map;
+import java.util.function.BiFunction;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+
+import com.nimbusds.oauth2.sdk.ParseException;
+import com.nimbusds.openid.connect.sdk.rp.OIDCClientInformation;
+
+import net.minidev.json.JSONObject;
+import net.shibboleth.oidc.metadata.policy.MetadataPolicy;
+import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.collection.Pair;
+import net.shibboleth.shared.component.AbstractIdentifiableInitializableComponent;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+/**
+ * Default strategy to merge the metadata policies for the given entity type from the given trust chain. Finally,
+ * a configurable local metadata policy is merged to the resulting map of metadata policies.
+ */
+public class DefaultLocalMetadataPolicyMergingStrategy extends AbstractIdentifiableInitializableComponent
+ implements BiFunction<OIDCClientInformation,Map<String, MetadataPolicy>,OIDCClientInformation> {
+
+ /** Class logger. */
+ @Nonnull private Logger log = LoggerFactory.getLogger(DefaultLocalMetadataPolicyMergingStrategy.class);
+
+ /** Enforcer function for applying metadata policy for an item. */
+ @NonnullAfterInit private BiFunction<Object, MetadataPolicy, Pair<Object, Boolean>> metadataPolicyEnforcer;
+
+ /**
+ * Set the enforcer function for applying metadata policy for an item.
+ *
+ * @param enforcer policy enforcer
+ */
+ public void setMetadataPolicyEnforcer(
+ @Nonnull final BiFunction<Object, MetadataPolicy, Pair<Object, Boolean>> enforcer) {
+ checkSetterPreconditions();
+ metadataPolicyEnforcer = Constraint.isNotNull(enforcer, "Metadata policy enforcer cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+
+ if (metadataPolicyEnforcer == null) {
+ throw new ComponentInitializationException("MetadataPolicyEnforcer cannot be null");
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override @Nullable
+ public OIDCClientInformation apply(@Nullable final OIDCClientInformation inputMetadata,
+ @Nullable final Map<String, MetadataPolicy> localPolicy) {
+ checkComponentActive();
+ if (inputMetadata == null) {
+ return null;
+ }
+ if (localPolicy == null || localPolicy.isEmpty()) {
+ return inputMetadata;
+ }
+ final JSONObject result = inputMetadata.getOIDCMetadata().toJSONObject();
+ boolean compliant = true;
+ for (final String claim : localPolicy.keySet()) {
+ final MetadataPolicy policy = localPolicy.get(claim);
+ final Object value = inputMetadata.getOIDCMetadata().toJSONObject().get(claim);
+ log.debug("Claim {} set in policy included in the input: {}", claim, value == null);
+ final Pair<Object,Boolean> mergeResult = metadataPolicyEnforcer.apply(value, policy);
+ final Boolean enforcerResult = mergeResult != null ? mergeResult.getSecond() : null;
+ if (enforcerResult == null || !enforcerResult.booleanValue()) {
+ log.warn("Metadata claim {} is not compliant with the policy", claim);
+ compliant = false;
+ } else {
+ log.trace("Validation result is OK for claim {}", claim);
+ final Object enforcedValue = mergeResult != null ? mergeResult.getFirst() : null;
+ result.put(claim, enforcedValue);
+ }
+ }
+
+ if (!compliant) {
+ log.warn("The requested metadata is not compliant with the policy");
+ } else {
+ log.debug("The requested metadata is compliant with the policy");
+ try {
+ return OIDCClientInformation.parse(result);
+ } catch (final ParseException e) {
+ log.error("Could not parse the metadata object", e);
+ }
+ }
+ return null;
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultMetadataValidationCondition.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultMetadataValidationCondition.java
new file mode 100644
index 0000000..3733037
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultMetadataValidationCondition.java
@@ -0,0 +1,81 @@
+/*
+ * 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.oidfed.profile.navigate;
+
+import java.util.Map;
+import java.util.function.BiPredicate;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+
+import com.nimbusds.oauth2.sdk.ParseException;
+import com.nimbusds.oauth2.sdk.as.AuthorizationServerMetadata;
+import com.nimbusds.oauth2.sdk.client.ClientMetadata;
+import com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata;
+import com.nimbusds.openid.connect.sdk.rp.OIDCClientMetadata;
+
+import net.minidev.json.JSONObject;
+import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.primitive.StringSupport;
+
+/**
+ * Default validation condition for metadata entries by entity type. Validation is done by parsing the entity type
+ * into a corresponding Nimbus object.
+ */
+public class DefaultMetadataValidationCondition implements BiPredicate<String, Map<String,Object>> {
+
+ /** Class logger. */
+ @Nonnull private final static Logger log = LoggerFactory.getLogger(DefaultMetadataValidationCondition.class);
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean test(@Nullable final String key, @Nullable final Map<String, Object> metadata) {
+ if (StringSupport.trimOrNull(key) == null || metadata == null) {
+ log.error("Invalid input to the validation condition key={}, metadata={}", key, metadata);
+ return false;
+ }
+ try {
+ switch (key) {
+ case "federation_entity":
+ log.debug("Ignoring validation of {}", key);
+ return true;
+ case "openid_provider":
+ OIDCProviderMetadata.parse(new JSONObject(metadata));
+ return true;
+ case "openid_relying_party":
+ OIDCClientMetadata.parse(new JSONObject(metadata));
+ return true;
+ case "oauth_authorization_server":
+ AuthorizationServerMetadata.parse(new JSONObject(metadata));
+ return true;
+ case "oauth_client":
+ ClientMetadata.parse(new JSONObject(metadata));
+ return true;
+ case "oauth_resource":
+ log.debug("Ignoring validation of {}", key);
+ return true;
+ default:
+ log.debug("Ignoring validation of {}", key);
+ return true;
+ }
+ } catch (final ParseException e) {
+ log.warn("Could not parse entity_type {}", key, e);
+ }
+ return false;
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultPreSelectedTrustChainIDsLookupStrategy.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultPreSelectedTrustChainIDsLookupStrategy.java
new file mode 100644
index 0000000..56ec368
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultPreSelectedTrustChainIDsLookupStrategy.java
@@ -0,0 +1,119 @@
+/*
+ * 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.oidfed.profile.navigate;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import net.shibboleth.idp.plugin.oidc.op.messaging.context.OIDCAuthenticationResponseContext;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.support.ClaimsSetExtensionSupport;
+import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.collection.CollectionSupport;
+import net.shibboleth.shared.component.AbstractIdentifiableInitializableComponent;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.logic.Constraint;
+
+/**
+ * Default strategy for looking up the entity IDs of the previously selected trust chain. The selected trust chain is
+ * fetched by default via {@link OIDCAuthenticationResponseContext#getAuthorizationGrantClaimsSet()}. The default logic
+ * may be overridden via {@link #profileSpecificStrategies}.
+ */
+public class DefaultPreSelectedTrustChainIDsLookupStrategy extends AbstractIdentifiableInitializableComponent
+ implements Function<ProfileRequestContext,List<String>> {
+
+ /** Strategy to locate the profile ID. */
+ @NonnullAfterInit private Function<ProfileRequestContext, String> profileIdLookupStrategy;
+
+ /** Strategies used to locate profile-specific lookup strategies. */
+ @Nonnull private Map<String,Function<ProfileRequestContext,List<String>>> profileSpecificStrategies;
+
+ /**
+ * Constructor.
+ */
+ public DefaultPreSelectedTrustChainIDsLookupStrategy() {
+ profileSpecificStrategies = CollectionSupport.emptyMap();
+ }
+
+ /**
+ * Set strategy to locate the profile ID.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setProfileIdLookupStrategy(@Nonnull final Function<ProfileRequestContext, String> strategy) {
+ checkSetterPreconditions();
+ profileIdLookupStrategy = Constraint.isNotNull(strategy, "ProfileIdLookupStrategy cannot be null");
+ }
+
+ /**
+ * Set strategies used to locate profile-specific lookup strategies.
+ *
+ * @param strategies map of strategies
+ */
+ public void setProfileSpecificStrategies(
+ @Nonnull final Map<String,Function<ProfileRequestContext,List<String>>> strategies) {
+ checkSetterPreconditions();
+ profileSpecificStrategies = Constraint.isNotNull(strategies, "ProfileSpecificStrategies cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+
+ if (profileIdLookupStrategy == null) {
+ throw new ComponentInitializationException("ProfileIdLookupStrategy cannot be null");
+ }
+ if (profileSpecificStrategies == null) {
+ throw new ComponentInitializationException("ProfileSpecificStrategies cannot be null");
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override @Nullable
+ public List<String> apply(@Nullable final ProfileRequestContext input) {
+ checkComponentActive();
+ return Optional.ofNullable(profileIdLookupStrategy.apply(input))
+ .map(profileId -> profileSpecificStrategies.get(profileId))
+ .map(function -> function.apply(input))
+ .orElse(defaultValue(input));
+ }
+
+ /**
+ * The implementation if no profile-specific strategy has been set.
+ *
+ * @param input profile request context
+ * @return trust chain IDs
+ */
+ private List<String> defaultValue(@Nullable final ProfileRequestContext input) {
+ return Optional.ofNullable(input)
+ .filter(prc -> prc.getOutboundMessageContext() != null)
+ .map(prc -> prc.ensureOutboundMessageContext())
+ .filter(msgCtx -> msgCtx.containsSubcontext(OIDCAuthenticationResponseContext.class))
+ .map(msgCtx -> msgCtx.ensureSubcontext(OIDCAuthenticationResponseContext.class))
+ .map(oidcResponseCtx -> oidcResponseCtx.getAuthorizationGrantClaimsSet())
+ .filter(Objects::nonNull)
+ .map(ClaimsSetExtensionSupport::parseAutoRegisteredTrustChain)
+ .orElse(null);
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultSelectedTrustChainIDsLookupStrategy.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultSelectedTrustChainIDsLookupStrategy.java
new file mode 100644
index 0000000..8344b48
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultSelectedTrustChainIDsLookupStrategy.java
@@ -0,0 +1,64 @@
+/*
+ * 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.oidfed.profile.navigate;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.RelyingPartyTrustChainContext;
+import net.shibboleth.shared.logic.Constraint;
+
+/**
+ * Default strategy for looking up the entity IDs of the selected trust chain. The selected trust chain is fetched via
+ * {@link RelyingPartyTrustChainContext#getSelectedTrustChain()}.
+ */
+public class DefaultSelectedTrustChainIDsLookupStrategy extends AbstractTrustChainContextLookupFunction<List<String>> {
+
+ /** Strategy used to get entity IDs from a trust chain. */
+ @Nonnull private Function<List<EntityStatement>, List<String>> trustChainIDsLookupStrategy;
+
+ /**
+ * Constructor.
+ */
+ public DefaultSelectedTrustChainIDsLookupStrategy() {
+ super();
+ trustChainIDsLookupStrategy = new DefaultTrustChainIDsLookupStrategy();
+ }
+
+ /**
+ * Set the strategy used to get entity IDs from a trust chain.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setTrustChainIDsLookupStrategy(
+ @Nonnull final Function<List<EntityStatement>, List<String>> strategy) {
+ trustChainIDsLookupStrategy = Constraint.isNotNull(strategy, "TrustChainIDsLookupStrategy cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override @Nullable
+ public List<String> doApply(@Nonnull final RelyingPartyTrustChainContext trustChainContext) {
+ return Optional.ofNullable(trustChainContext.getSelectedTrustChain())
+ .map(pair -> pair.getFirst())
+ .map(chain -> trustChainIDsLookupStrategy.apply(chain))
+ .orElse(null);
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultSelectedTrustChainImmediateSuperiorLookupStrategy.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultSelectedTrustChainImmediateSuperiorLookupStrategy.java
new file mode 100644
index 0000000..f03a2a7
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultSelectedTrustChainImmediateSuperiorLookupStrategy.java
@@ -0,0 +1,42 @@
+/*
+ * 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.oidfed.profile.navigate;
+
+import java.util.Optional;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.RelyingPartyTrustChainContext;
+
+/**
+ * Default strategy for looking up the entity ID of the immediate superior in the selected trust chain. The selected
+ * trust chain is fetched via {@link RelyingPartyTrustChainContext#getSelectedTrustChain()}.
+ */
+public class DefaultSelectedTrustChainImmediateSuperiorLookupStrategy
+ extends AbstractTrustChainContextLookupFunction<String> {
+
+ /** {@inheritDoc} */
+ @Override @Nullable
+ public String doApply(@Nonnull final RelyingPartyTrustChainContext trustChainContext) {
+ return Optional.ofNullable(trustChainContext.getSelectedTrustChain())
+ .map(pair -> pair.getFirst())
+ .filter(list -> list.size() >= 3)
+ .map(list -> list.get(1))
+ .map(entityStatement -> entityStatement.getClaimsSet().getIssuer())
+ .map(issuer -> issuer.getValue())
+ .orElse(null);
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultSelectedTrustChainMetadataLookupStrategy.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultSelectedTrustChainMetadataLookupStrategy.java
new file mode 100644
index 0000000..bd42f6e
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultSelectedTrustChainMetadataLookupStrategy.java
@@ -0,0 +1,54 @@
+/*
+ * 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.oidfed.profile.navigate;
+
+import java.util.Map;
+import java.util.Optional;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import com.nimbusds.oauth2.sdk.ParseException;
+import com.nimbusds.openid.connect.sdk.rp.OIDCClientMetadata;
+
+import net.minidev.json.JSONObject;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.RelyingPartyTrustChainContext;
+
+/**
+ * Default strategy for looking up the metadata the selected trust chain. The selected trust chain is fetched via
+ * {@link RelyingPartyTrustChainContext#getSelectedTrustChain()}.
+ */
+public class DefaultSelectedTrustChainMetadataLookupStrategy
+ extends AbstractTrustChainContextLookupFunction<OIDCClientMetadata> {
+
+ /** {@inheritDoc} */
+ @Override @Nullable
+ public OIDCClientMetadata doApply(@Nonnull final RelyingPartyTrustChainContext trustChainContext) {
+ return Optional.ofNullable(trustChainContext.getSelectedTrustChain())
+ .map(pair -> pair.getSecond())
+ .map(map -> map.get("openid_relying_party"))
+ .filter(Map.class::isInstance)
+ .map(Map.class::cast)
+ .map(JSONObject::new)
+ .map(json-> {
+ try {
+ return OIDCClientMetadata.parse(json);
+ } catch (ParseException e) {
+ return null;
+ }
+ })
+ .orElse(null);
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultSelectedTrustChainTrustAnchorLookupStrategy.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultSelectedTrustChainTrustAnchorLookupStrategy.java
new file mode 100644
index 0000000..ae644f2
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultSelectedTrustChainTrustAnchorLookupStrategy.java
@@ -0,0 +1,41 @@
+/*
+ * 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.oidfed.profile.navigate;
+
+import java.util.Optional;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.RelyingPartyTrustChainContext;
+
+/**
+ * Default strategy for looking up the entity ID of the trust anchor in the selected trust chain. The selected trust
+ * chain is fetched via {@link RelyingPartyTrustChainContext#getSelectedTrustChain()}.
+ */
+public class DefaultSelectedTrustChainTrustAnchorLookupStrategy
+ extends AbstractTrustChainContextLookupFunction<String> {
+
+ /** {@inheritDoc} */
+ @Override @Nullable
+ public String doApply(@Nonnull final RelyingPartyTrustChainContext trustChainContext) {
+ return Optional.ofNullable(trustChainContext.getSelectedTrustChain())
+ .map(pair -> pair.getFirst())
+ .filter(list -> list.size() >= 3)
+ .map(list -> list.get(list.size() - 1))
+ .map(entityStatement -> entityStatement.getEntityID().getValue())
+ .orElse(null);
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultTrustChainIDsLookupStrategy.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultTrustChainIDsLookupStrategy.java
new file mode 100644
index 0000000..7af8e2b
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultTrustChainIDsLookupStrategy.java
@@ -0,0 +1,43 @@
+/*
+ * 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.oidfed.profile.navigate;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.stream.IntStream;
+
+import javax.annotation.Nullable;
+
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+/**
+ * Default strategy for looking up the entity IDs of a trust chain.
+ */
+public class DefaultTrustChainIDsLookupStrategy implements Function<List<EntityStatement>,List<String>> {
+
+ /** {@inheritDoc} */
+ @Override @Nullable
+ public List<String> apply(@Nullable final List<EntityStatement> input) {
+ return Optional.ofNullable(input)
+ .filter(chain -> chain != null && !chain.isEmpty())
+ .map(chain -> IntStream.range(0, chain.size())
+ .mapToObj(i -> chain.get(i))
+ .map(statement -> statement.getEntityID().getValue())
+ .distinct()
+ .toList())
+ .orElse(null);
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultTrustChainMetadataPolicyMergingStrategy.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultTrustChainMetadataPolicyMergingStrategy.java
new file mode 100644
index 0000000..3477420
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultTrustChainMetadataPolicyMergingStrategy.java
@@ -0,0 +1,200 @@
+/*
+ * 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.oidfed.profile.navigate;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.type.MapType;
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import net.shibboleth.oidc.metadata.policy.MetadataPolicy;
+import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.collection.CollectionSupport;
+import net.shibboleth.shared.collection.Pair;
+import net.shibboleth.shared.component.AbstractIdentifiableInitializableComponent;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.logic.ConstraintViolationException;
+import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.primitive.StringSupport;
+
+/**
+ * Default strategy to merge the metadata policies for the given entity type from the given trust chain. Finally,
+ * a configurable local metadata policy is merged to the resulting map of metadata policies.
+ */
+public class DefaultTrustChainMetadataPolicyMergingStrategy extends AbstractIdentifiableInitializableComponent
+ implements BiFunction<List<EntityStatement>,String, Map<String, MetadataPolicy>> {
+
+ /** Class logger. */
+ @Nonnull private Logger log = LoggerFactory.getLogger(DefaultTrustChainMetadataPolicyMergingStrategy.class);
+
+ /** The strategy used for merging two metadata policies. */
+ @NonnullAfterInit private BiFunction<Map<String, MetadataPolicy>, Map<String, MetadataPolicy>,
+ Pair<Map<String, MetadataPolicy>, Boolean>> metadataPolicyMergingStrategy;
+
+ /** The strategy used for local (additional) metadata policy. */
+ @NonnullAfterInit private Function<List<EntityStatement>, Map<String, MetadataPolicy>>
+ localMetadataPolicyStrategy;
+
+ /** Object mapper used for deserializing metadata policies. */
+ @NonnullAfterInit private ObjectMapper objectMapper;
+
+ /**
+ * Set the strategy used for merging two metadata policies.
+ *
+ * @param strategy What to set.
+ */
+ public void setMetadataPolicyMergingStrategy(@Nonnull final BiFunction<Map<String,MetadataPolicy>,
+ Map<String,MetadataPolicy>, Pair<Map<String, MetadataPolicy>, Boolean>> strategy) {
+ checkSetterPreconditions();
+ metadataPolicyMergingStrategy = Constraint.isNotNull(strategy,
+ "Metadata policy merging strategy cannot be null");
+ }
+
+ /**
+ * Set the strategy used for local (additional) metadata policy.
+ *
+ * @param strategy What to set.
+ */
+ public void setLocalMetadataPolicyStrategy(
+ @Nonnull final Function<List<EntityStatement>, Map<String, MetadataPolicy>> strategy) {
+ checkSetterPreconditions();
+ localMetadataPolicyStrategy = Constraint.isNotNull(strategy,
+ "Local metadata policy strategy cannot be null");
+ }
+
+ /**
+ * Set the object mapper used for deserializing metadata policies
+ *
+ * @param mapper What to set.
+ */
+ public void setObjectMapper(@Nonnull final ObjectMapper mapper) {
+ checkSetterPreconditions();
+ objectMapper = Constraint.isNotNull(mapper, "Object mapper cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+
+ if (metadataPolicyMergingStrategy == null) {
+ throw new ComponentInitializationException("Metadata policy merging strategy cannot be null");
+ }
+ if (localMetadataPolicyStrategy == null) {
+ throw new ComponentInitializationException("Local metadata policy strategy cannot be null");
+ }
+ if (objectMapper == null) {
+ throw new ComponentInitializationException("Object mapper cannot be null");
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override @Nonnull
+ public Map<String, MetadataPolicy> apply(@Nullable final List<EntityStatement> trustChain,
+ @Nullable final String entityType) throws ConstraintViolationException {
+ checkComponentActive();
+ if (trustChain == null || trustChain.isEmpty()) {
+ return CollectionSupport.emptyMap();
+ }
+ final Map<String, MetadataPolicy> result = new HashMap<>();
+ for (int i = trustChain.size(); i > 0; i--) {
+ final EntityStatement entityStatement = trustChain.get(i - 1);
+ final Map<String, Object> policy = entityStatement.getClaimsSet().getMetadataPolicyJSONObject();
+ if (policy == null || policy.isEmpty()) {
+ continue;
+ }
+
+ if (StringSupport.trimOrNull(entityType) != null) {
+ try {
+ assert entityType != null;
+ result.putAll(mergePolicies(result, parseMetadataPolicy(entityStatement, entityType)));
+ } catch (final ConstraintViolationException e) {
+ throw new ConstraintViolationException("Could not merge federation metadata policies");
+ }
+ }
+ }
+ try {
+ result.putAll(mergePolicies(result, localMetadataPolicyStrategy.apply(trustChain)));
+ } catch (final ConstraintViolationException e) {
+ throw new ConstraintViolationException("Could not merge local metadata policy in the federation policy");
+ }
+ return result;
+ }
+
+ /**
+ * Merges the two maps of metadata policies.
+ *
+ * @param first the first map of policies
+ * @param second the second map of policies
+ * @return the map containing merged policies
+ * @throws ConstraintViolationException if the merging fails
+ */
+ @Nonnull
+ protected Map<String, MetadataPolicy> mergePolicies(@Nullable final Map<String, MetadataPolicy> first,
+ @Nullable final Map<String, MetadataPolicy> second) throws ConstraintViolationException {
+ final Pair<Map<String, MetadataPolicy>, Boolean> result = metadataPolicyMergingStrategy.apply(first, second);
+ if (result != null && Boolean.TRUE.equals(result.getSecond())) {
+ final Map<String, MetadataPolicy> mergedMap = result.getFirst();
+ return mergedMap == null ? CollectionSupport.emptyMap() : mergedMap;
+ }
+ throw new ConstraintViolationException("Merge failed");
+ }
+
+ /**
+ * Parse a map of metadata policies from the given entity statement for a specified entity type.
+ *
+ * @param entityStatement the source for the map of metadata policies
+ * @param entityType the entity type to use
+ * @return the map of metadata policies for the entity type or null if not found
+ * @throws ConstraintViolationException if the map of policies could not be parsed from the entity statement
+ */
+ @Nullable
+ protected Map<String, MetadataPolicy> parseMetadataPolicy(
+ @Nonnull final EntityStatement entityStatement,
+ @Nonnull final String entityType) throws ConstraintViolationException {
+ final Object metadataPolicyClaim =
+ entityStatement.getClaimsSet().getClaim("metadata_policy");
+ if (metadataPolicyClaim != null) {
+ final JavaType stringType = objectMapper.constructType(String.class);
+ final JavaType metadataPolicyType = objectMapper.constructType(MetadataPolicy.class);
+ final MapType metadataPolicyMapType =
+ objectMapper.getTypeFactory().constructMapType(Map.class, stringType, metadataPolicyType);
+ final MapType metadataPolicyByEntityTypeMapType =
+ objectMapper.getTypeFactory().constructMapType(Map.class, stringType, metadataPolicyMapType);
+ try {
+ final Map<String, Map<String, MetadataPolicy>> result =
+ objectMapper.readValue(metadataPolicyClaim.toString(), metadataPolicyByEntityTypeMapType);
+ if (result != null) {
+ return result.get(entityType);
+ }
+ } catch (final JsonProcessingException e) {
+ log.warn("Could not parse trust mark issuers from the trust chain", e);
+ }
+ }
+ return null;
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultTrustChainSelectionStrategy.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultTrustChainSelectionStrategy.java
new file mode 100644
index 0000000..a3a8254
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultTrustChainSelectionStrategy.java
@@ -0,0 +1,93 @@
+/*
+ * 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.oidfed.profile.navigate;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.RelyingPartyTrustChainContext;
+import net.shibboleth.shared.collection.Pair;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+/**
+ * Default strategy for choosing a specific trust chain: it simply selects the first one in the list whose size is the
+ * shortest. The selection must not be included in the list of previously rejected trust chains, obtained via
+ * {@link RelyingPartyTrustChainContext#getRejectedTrustChains()}.
+ */
+public class DefaultTrustChainSelectionStrategy
+ extends AbstractTrustChainContextLookupFunction<Pair<List<EntityStatement>, Map<String,Map<String,Object>>>> {
+
+ /** Class logger. */
+ @Nonnull private Logger log = LoggerFactory.getLogger(DefaultTrustChainSelectionStrategy.class);
+
+ /** {@inheritDoc} */
+ @Override @Nullable
+ public Pair<List<EntityStatement>, Map<String,Map<String,Object>>> doApply(
+ @Nonnull final RelyingPartyTrustChainContext trustChainContext) {
+ final List<Pair<List<EntityStatement>, Map<String,Map<String,Object>>>> policyCompliantChains =
+ trustChainContext.getPolicyCompliantTrustChains();
+
+ if (policyCompliantChains == null || policyCompliantChains.isEmpty()) {
+ log.debug("No policy compliant chains located");
+ return null;
+ }
+
+ log.trace("Policy-compatible trust chains: {}", policyCompliantChains.size());
+ if (policyCompliantChains.size() > 1) {
+ int shortestIndex = -1;
+ for (int i = 0; i < policyCompliantChains.size(); i++) {
+ final List<EntityStatement> candidate = policyCompliantChains.get(i).getFirst();
+ if (isTrustChainRejected(trustChainContext, candidate)) {
+ continue;
+ }
+ if (shortestIndex == -1) {
+ shortestIndex = i;
+ } else {
+ final List<EntityStatement> shortest = policyCompliantChains.get(shortestIndex).getFirst();
+ if (candidate != null && shortest != null && candidate.size() < shortest.size()) {
+ shortestIndex = i;
+ }
+ }
+ }
+ log.trace("Shortest non-rejected index {}", shortestIndex);
+ return shortestIndex == -1 ? null : policyCompliantChains.get(shortestIndex);
+ }
+ final List<EntityStatement> candidate = policyCompliantChains.get(0).getFirst();
+ return isTrustChainRejected(trustChainContext, candidate) ? null : policyCompliantChains.get(0);
+ }
+
+ /**
+ * Checks whether the trust chain has been previously rejected in the given context.
+ *
+ * @param trustChainContext context containing the previously rejected trust chain
+ * @param trustChain trust chain to be verified
+ * @return true if trust chain is null or previously rejected, false otherwise
+ */
+ private boolean isTrustChainRejected(@Nonnull final RelyingPartyTrustChainContext trustChainContext,
+ @Nullable final List<EntityStatement> trustChain) {
+ if (trustChain == null) {
+ return true;
+ }
+ final List<List<EntityStatement>> rejectedTrustChains = trustChainContext.getRejectedTrustChains();
+ return rejectedTrustChains != null && rejectedTrustChains.contains(trustChain);
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/EntityStatementClaimsSetManipulationStrategyLookupFunction.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/EntityStatementClaimsSetManipulationStrategyLookupFunction.java
new file mode 100644
index 0000000..eb1cdb6
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/EntityStatementClaimsSetManipulationStrategyLookupFunction.java
@@ -0,0 +1,52 @@
+/*
+ * 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.oidfed.profile.navigate;
+
+import java.util.Map;
+import java.util.function.BiFunction;
+
+import javax.annotation.Nullable;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import net.shibboleth.idp.plugin.oidc.op.oidfed.config.OIDFederationEntityStatementProducingProfileConfiguration;
+import net.shibboleth.profile.config.ProfileConfiguration;
+import net.shibboleth.profile.context.RelyingPartyContext;
+import net.shibboleth.profile.context.navigate.AbstractRelyingPartyLookupFunction;
+
+/**
+ * A function that returns entity statement claims set manipulation strategy from
+ * {@link OIDFederationEntityStatementProducingProfileConfiguration} if such a profile is available from a
+ * {@link RelyingPartyContext} obtained via a lookup function, by default a child of the {@link ProfileRequestContext}.
+ *
+ * <p>If a specific setting is unavailable, a null value is returned.</p>
+ */
+public class EntityStatementClaimsSetManipulationStrategyLookupFunction extends
+ AbstractRelyingPartyLookupFunction<BiFunction<ProfileRequestContext,Map<String,Object>,Map<String,Object>>> {
+
+ /** {@inheritDoc} */
+ @Override
+ @Nullable public BiFunction<ProfileRequestContext,Map<String,Object>,Map<String,Object>> apply(
+ @Nullable final ProfileRequestContext input) {
+ final RelyingPartyContext rpc = getRelyingPartyContextLookupStrategy().apply(input);
+ if (rpc != null) {
+ final ProfileConfiguration pc = rpc.getProfileConfig();
+ if (pc instanceof OIDFederationEntityStatementProducingProfileConfiguration ofesppc) {
+ return ofesppc.getEntityStatementClaimsSetManipulationStrategy(input);
+ }
+ }
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/EntityStatementLifetimeLookupFunction.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/EntityStatementLifetimeLookupFunction.java
new file mode 100644
index 0000000..fe2b3e5
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/EntityStatementLifetimeLookupFunction.java
@@ -0,0 +1,51 @@
+/*
+ * 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.oidfed.profile.navigate;
+
+import java.time.Duration;
+
+import javax.annotation.Nullable;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import net.shibboleth.profile.config.ProfileConfiguration;
+import net.shibboleth.profile.context.RelyingPartyContext;
+import net.shibboleth.profile.context.navigate.AbstractRelyingPartyLookupFunction;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.config.OIDFederationEntityConfigurationProfileConfiguration;
+
+/**
+ * A function that returns {@link OIDFederationEntityConfigurationProfileConfiguration#getEntityStatementLifetime(ProfileRequestContext)}
+ * if such a profile is available from a {@link RelyingPartyContext} obtained via a lookup function, by default a child
+ * of the {@link ProfileRequestContext}.
+ *
+ * <p>If a specific setting is unavailable, a null value is returned.</p>
+ */
+public class EntityStatementLifetimeLookupFunction extends AbstractRelyingPartyLookupFunction<Duration> {
+
+ /** {@inheritDoc} */
+ @Override
+ @Nullable public Duration apply(@Nullable final ProfileRequestContext input) {
+ final RelyingPartyContext rpc = getRelyingPartyContextLookupStrategy().apply(input);
+ if (rpc != null) {
+ final ProfileConfiguration pc = rpc.getProfileConfig();
+ if (pc instanceof OIDFederationEntityConfigurationProfileConfiguration ofec) {
+ return ofec.getEntityStatementLifetime(input);
+ }
+ }
+
+ return null;
+ }
+
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/ExplicitClientRegistrationRequestClientIDLookupFunction.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/ExplicitClientRegistrationRequestClientIDLookupFunction.java
new file mode 100644
index 0000000..ffb2856
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/ExplicitClientRegistrationRequestClientIDLookupFunction.java
@@ -0,0 +1,68 @@
+/*
+ * 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.oidfed.profile.navigate;
+
+import java.util.List;
+import java.util.Optional;
+
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.ThreadSafe;
+
+import org.opensaml.messaging.context.MessageContext;
+import org.opensaml.messaging.context.navigate.ContextDataLookupFunction;
+
+import com.nimbusds.oauth2.sdk.id.ClientID;
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import net.shibboleth.idp.plugin.oidc.op.oidfed.messaging.impl.ExplicitClientRegistrationRequest;
+
+/**
+ * A function that returns client from the entity configuration in the explicit registration request.
+ *
+ * @since 4.3.0
+ */
+ at ThreadSafe
+public class ExplicitClientRegistrationRequestClientIDLookupFunction
+ implements ContextDataLookupFunction<MessageContext, ClientID> {
+
+ /** {@inheritDoc} */
+ @Nullable
+ public ClientID apply(@Nullable final MessageContext input) {
+ return Optional.ofNullable(input)
+ .map(messageContext -> messageContext.getMessage())
+ .filter(ExplicitClientRegistrationRequest.class::isInstance)
+ .map(ExplicitClientRegistrationRequest.class::cast)
+ .map(request -> getClientID(request))
+ .orElse(null);
+ }
+
+ /**
+ * Get the client ID from the explicit registration request.
+ *
+ * @param request the explicit registration request
+ * @return the client ID, or null if it cannot be parsed
+ */
+ @Nullable protected ClientID getClientID(@Nullable final ExplicitClientRegistrationRequest request) {
+ if (request == null) {
+ return null;
+ }
+ final EntityStatement entityConfiguration = request.getEntityConfiguration();
+ if (entityConfiguration != null) {
+ return new ClientID(entityConfiguration.getEntityID());
+ }
+ final List<EntityStatement> trustChain = request.getTrustChain();
+ return trustChain != null && !trustChain.isEmpty() ? new ClientID(trustChain.get(0).getEntityID()) : null;
+ }
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/ExplicitClientRegistrationRequestJWKSetLookupFunction.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/ExplicitClientRegistrationRequestJWKSetLookupFunction.java
new file mode 100644
index 0000000..d574b93
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/ExplicitClientRegistrationRequestJWKSetLookupFunction.java
@@ -0,0 +1,69 @@
+/*
+ * 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.oidfed.profile.navigate;
+
+import java.util.List;
+import java.util.Optional;
+
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.ThreadSafe;
+
+import org.opensaml.messaging.context.navigate.ContextDataLookupFunction;
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import com.nimbusds.jose.jwk.JWKSet;
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import net.shibboleth.idp.plugin.oidc.op.oidfed.messaging.impl.ExplicitClientRegistrationRequest;
+
+/**
+ * A function that returns {@link JWKSet} from the entity configuration in the explicit registration request.
+ *
+ * @since 4.3.0
+ */
+ at ThreadSafe
+public class ExplicitClientRegistrationRequestJWKSetLookupFunction
+ implements ContextDataLookupFunction<ProfileRequestContext, JWKSet> {
+
+ /** {@inheritDoc} */
+ @Nullable
+ public JWKSet apply(@Nullable final ProfileRequestContext input) {
+ return Optional.ofNullable(input)
+ .map(profileRequesContext -> profileRequesContext.getInboundMessageContext())
+ .map(messageContext -> messageContext.getMessage())
+ .filter(ExplicitClientRegistrationRequest.class::isInstance)
+ .map(ExplicitClientRegistrationRequest.class::cast)
+ .map(request -> getJWKSet(request))
+ .orElse(null);
+ }
+
+ /**
+ * Get the JSON Web Key Set from the explicit registration request.
+ *
+ * @param request explicit registration request
+ * @return the JWKSet, or null if it cannot be parsed
+ */
+ @Nullable protected JWKSet getJWKSet(@Nullable final ExplicitClientRegistrationRequest request) {
+ if (request == null) {
+ return null;
+ }
+ final EntityStatement entityConfiguration = request.getEntityConfiguration();
+ if (entityConfiguration != null) {
+ return entityConfiguration.getClaimsSet().getJWKSet();
+ }
+ final List<EntityStatement> trustChain = request.getTrustChain();
+ return trustChain != null && !trustChain.isEmpty() ? trustChain.get(0).getClaimsSet().getJWKSet() : null;
+ }
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/ExplicitClientRegistrationRequestTrustChainLookupFunction.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/ExplicitClientRegistrationRequestTrustChainLookupFunction.java
new file mode 100644
index 0000000..283ab0b
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/ExplicitClientRegistrationRequestTrustChainLookupFunction.java
@@ -0,0 +1,50 @@
+/*
+ * 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.oidfed.profile.navigate;
+
+import java.util.List;
+import java.util.Optional;
+
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.ThreadSafe;
+
+import org.opensaml.messaging.context.navigate.ContextDataLookupFunction;
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import net.shibboleth.idp.plugin.oidc.op.oidfed.messaging.impl.ExplicitClientRegistrationRequest;
+
+/**
+ * A function that returns pushed trust chain set in the explicit registration request.
+ *
+ * @since 4.3.0
+ */
+ at ThreadSafe
+public class ExplicitClientRegistrationRequestTrustChainLookupFunction
+ implements ContextDataLookupFunction<ProfileRequestContext, List<EntityStatement>> {
+
+ /** {@inheritDoc} */
+ @Nullable
+ public List<EntityStatement> apply(@Nullable final ProfileRequestContext input) {
+ return Optional.ofNullable(input)
+ .map(profileRequestContext -> profileRequestContext.getInboundMessageContext())
+ .map(messageContext -> messageContext.getMessage())
+ .filter(ExplicitClientRegistrationRequest.class::isInstance)
+ .map(ExplicitClientRegistrationRequest.class::cast)
+ .map(request -> request.getTrustChain())
+ .orElse(null);
+ }
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/LocalMetadataPolicyLookupFunction.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/LocalMetadataPolicyLookupFunction.java
new file mode 100644
index 0000000..41cc47d
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/LocalMetadataPolicyLookupFunction.java
@@ -0,0 +1,49 @@
+/*
+ * 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.oidfed.profile.navigate;
+
+import java.util.Map;
+
+import javax.annotation.Nullable;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import net.shibboleth.profile.config.ProfileConfiguration;
+import net.shibboleth.profile.context.RelyingPartyContext;
+import net.shibboleth.profile.context.navigate.AbstractRelyingPartyLookupFunction;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.config.OIDFederationRegistrationProfileConfiguration;
+import net.shibboleth.oidc.metadata.policy.MetadataPolicy;
+
+/**
+ * A function that obtains
+ * {@link OIDFederationRegistrationProfileConfiguration#getLocalMetadataPolicy(ProfileRequestContext)}.
+ *
+ * <p>If a specific setting is unavailable, a null value is returned.</p>
+ */
+public class LocalMetadataPolicyLookupFunction extends AbstractRelyingPartyLookupFunction<Map<String, MetadataPolicy>> {
+
+ /** {@inheritDoc} */
+ @Override
+ @Nullable public Map<String, MetadataPolicy> apply(@Nullable final ProfileRequestContext input) {
+ final RelyingPartyContext rpc = getRelyingPartyContextLookupStrategy().apply(input);
+ if (rpc != null) {
+ final ProfileConfiguration pc = rpc.getProfileConfig();
+ if (pc instanceof OIDFederationRegistrationProfileConfiguration ofrpc) {
+ return ofrpc.getLocalMetadataPolicy(input);
+ }
+ }
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/MandatoryTrustMarksLookupFunction.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/MandatoryTrustMarksLookupFunction.java
new file mode 100644
index 0000000..7854267
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/MandatoryTrustMarksLookupFunction.java
@@ -0,0 +1,48 @@
+/*
+ * 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.oidfed.profile.navigate;
+
+import java.util.List;
+
+import javax.annotation.Nullable;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import net.shibboleth.profile.config.ProfileConfiguration;
+import net.shibboleth.profile.context.RelyingPartyContext;
+import net.shibboleth.profile.context.navigate.AbstractRelyingPartyLookupFunction;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.config.OIDFederationRegistrationProfileConfiguration;
+
+/**
+ * A function that obtains
+ * {@link OIDFederationRegistrationProfileConfiguration#getMandatoryTrustMarks(ProfileRequestContext)}.
+ *
+ * <p>If a specific setting is unavailable, a null value is returned.</p>
+ */
+public class MandatoryTrustMarksLookupFunction extends AbstractRelyingPartyLookupFunction<List<String>> {
+
+ /** {@inheritDoc} */
+ @Override
+ @Nullable public List<String> apply(@Nullable final ProfileRequestContext input) {
+ final RelyingPartyContext rpc = getRelyingPartyContextLookupStrategy().apply(input);
+ if (rpc != null) {
+ final ProfileConfiguration pc = rpc.getProfileConfig();
+ if (pc instanceof OIDFederationRegistrationProfileConfiguration ofrpc) {
+ return ofrpc.getMandatoryTrustMarks(input);
+ }
+ }
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/MaximumTrustMarkLifetimeLookupFunction.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/MaximumTrustMarkLifetimeLookupFunction.java
new file mode 100644
index 0000000..9998654
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/MaximumTrustMarkLifetimeLookupFunction.java
@@ -0,0 +1,52 @@
+/*
+ * 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.oidfed.profile.navigate;
+
+import java.time.Duration;
+
+import javax.annotation.Nullable;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import net.shibboleth.profile.config.ProfileConfiguration;
+import net.shibboleth.profile.context.RelyingPartyContext;
+import net.shibboleth.profile.context.navigate.AbstractRelyingPartyLookupFunction;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.config.OIDFederationRegistrationProfileConfiguration;
+
+/**
+ * A function that returns
+ * {@link OIDFederationRegistrationProfileConfiguration#getMaximumTrustMarkLifetime(ProfileRequestContext)} if such a
+ * profile is available from a {@link RelyingPartyContext} obtained via a lookup function, by default a child of the
+ * {@link ProfileRequestContext}.
+ *
+ * <p>If a specific setting is unavailable, a null value is returned.</p>
+ */
+public class MaximumTrustMarkLifetimeLookupFunction extends AbstractRelyingPartyLookupFunction<Duration> {
+
+ /** {@inheritDoc} */
+ @Override
+ @Nullable public Duration apply(@Nullable final ProfileRequestContext input) {
+ final RelyingPartyContext rpc = getRelyingPartyContextLookupStrategy().apply(input);
+ if (rpc != null) {
+ final ProfileConfiguration pc = rpc.getProfileConfig();
+ if (pc instanceof OIDFederationRegistrationProfileConfiguration ofrpc) {
+ return ofrpc.getMaximumTrustMarkLifetime(input);
+ }
+ }
+
+ return null;
+ }
+
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml b/idp-oidfed-op-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
new file mode 100644
index 0000000..250fb93
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
@@ -0,0 +1,514 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:c="http://www.springframework.org/schema/c" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
+ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
+
+ default-init-method="initialize" default-destroy-method="destroy">
+
+ <bean id="shibboleth.oidfed.DefaultOpenIdConfigurationResolver"
+ class="net.shibboleth.idp.plugin.oidc.op.metadata.impl.DynamicFilesystemProviderMetadataResolver"
+ p:minRefreshDelay="%{idp.oidc.config.minRefreshDelay:PT5M}"
+ p:maxRefreshDelay="%{idp.oidc.config.maxRefreshDelay:PT4H}"
+ c:metadata="#{getObject('shibboleth.oidfed.OpenIDConfiguration') ?: getObject('DefaultMetadataSkeleton')}"
+ p:dynamicValueResolvers-ref="#{'%{idp.oidfed.configuration.resolver.values:shibboleth.oidfed.configuration.DefaultDynamicValueResolvers}'.trim()}"/>
+
+ <bean id="shibboleth.oidfed.configuration.DefaultDynamicValueResolvers"
+ parent="shibboleth.oidc.discovery.DefaultDynamicValueResolvers"
+ class="org.springframework.beans.factory.config.MapFactoryBean">
+ <property name="sourceMap">
+ <map merge="true">
+ <entry key="federation_registration_endpoint" value-ref="shibboleth.oidfed.configuration.FederationRegistrationEndpointResolver" />
+ <entry key="client_registration_types_supported" value-ref="shibboleth.oidfed.configuration.RegistrationTypesResolver" />
+ </map>
+ </property>
+ </bean>
+
+ <bean id="shibboleth.oidfed.configuration.FederationRegistrationEndpointResolver"
+ class="net.shibboleth.idp.plugin.oidc.op.metadata.impl.FunctionMetadataValueResolver">
+ <property name="resolverFunction">
+ <bean parent="shibboleth.Functions.Expression"
+ c:expression="#custom.get().getRequestURL().toString().replace('/profile/oidfed/entity-configuration','/profile/oidfed/register').replace('/.well-known/openid-federation','/profile/oidfed/register')"
+ p:customObject-ref="shibboleth.HttpServletRequestSupplier" />
+ </property>
+ </bean>
+
+ <bean id="shibboleth.oidfed.configuration.RegistrationTypesResolver"
+ class="net.shibboleth.idp.plugin.oidc.op.metadata.impl.FunctionMetadataValueResolver">
+ <property name="resolverFunction">
+ <bean parent="shibboleth.Functions.Constant">
+ <constructor-arg>
+ <bean class="java.util.List" factory-method="copyOf">
+ <constructor-arg value="%{idp.oidfed.entityConfiguration.registrationTypesSupported:automatic,explicit}" />
+ </bean>
+ </constructor-arg>
+ </bean>
+ </property>
+ </bean>
+
+ <bean id="shibboleth.oidfed.EntityConfigurationMetadataCache" parent="shibboleth.oidc.CacheBuilder">
+ <constructor-arg>
+ <bean p:cacheId="DefaultEntityConfigurationMetadataCache" parent="shibboleth.oidfed.EntityConfigurationMetadataCacheBuilderSpec"
+ p:cleanupTaskInterval="PT30S"/>
+ </constructor-arg>
+ </bean>
+
+ <bean id="shibboleth.oidfed.SubordinateEntityStatementMetadataCache" parent="shibboleth.oidc.CacheBuilder">
+ <constructor-arg>
+ <bean p:cacheId="DefaultSubordinateEntityStarementMetadataCache" parent="shibboleth.oidfed.SubordinateEntityStatementMetadataCacheBuilderSpec"
+ p:cleanupTaskInterval="PT30S"/>
+ </constructor-arg>
+ </bean>
+
+ <bean id="shibboleth.oidfed.TrustChainMetadataCache" parent="shibboleth.oidc.CacheBuilder">
+ <constructor-arg>
+ <bean p:cacheId="DefaultTrustChainMetadataCache" parent="shibboleth.oidfed.TrustChainMetadataCacheBuilderSpec"
+ p:cleanupTaskInterval="PT30S"/>
+ </constructor-arg>
+ </bean>
+
+ <bean id="shibboleth.oidfed.LocalTrustAnchorsMetadataCache" parent="shibboleth.oidc.CacheBuilder">
+ <constructor-arg>
+ <bean p:cacheId="DefaultLocalTrustAnchorsMetadataCache" parent="shibboleth.oidfed.LocalTrustAnchorsMetadataCacheBuilderSpec"/>
+ </constructor-arg>
+ </bean>
+
+ <bean id="shibboleth.oidfed.EntityConfigurationMetadataCacheBuilderSpec"
+ class="net.shibboleth.oidc.metadata.cache.impl.DynamicMetadataCacheBuilderSpec"
+ p:criteriaToIdentifierStrategy-ref="shibboleth.oidfed.DefaultSubjectEntityIDCriteriaToIdentifierStrategy"
+ p:metadataExpirationTimeStrategy-ref="shibboleth.oidfed.DefaultEntityStatementExpirationTimeStrategy"
+ p:minCacheDuration="%{idp.oidfed.entityConfiguration.maxRefreshDelay:PT1S}"
+ p:maxCacheDuration="%{idp.oidfed.entityConfiguration.maxRefreshDelay:PT30S}">
+ <property name="identifierExtractionStrategy">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultEntityStatementSubjectIdentifierExtractionStrategy"/>
+ </property>
+ <property name="fetchStrategy">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultEntityStatementFetchingStrategy"
+ p:httpClient="#{getObject('shibboleth.oidfed.HttpClient') ?: getObject('shibboleth.InternalHttpClient')}"
+ p:httpClientSecurityParameters="#{getObject('shibboleth.oidfed.NonBrowser.HttpClientSecurityParameters')}">
+ <property name="criteriaToEndpointStrategy">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultEntityConfigurationEndpointExtractionStrategy"
+ p:criteriaToEntityIdStrategy-ref="shibboleth.oidfed.DefaultSubjectEntityIDCriteriaToIdentifierStrategy"/>
+ </property>
+ </bean>
+ </property>
+ <property name="metadataFilterStrategy">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultEntityStatementSignatureValidationFilterStrategy"
+ p:trustEngine-ref="shibboleth.oidfed.DefaultEntityConfigurationTrustEngine"/>
+ </property>
+ </bean>
+
+ <bean id="shibboleth.oidfed.DefaultEntityConfigurationTrustEngine"
+ class="net.shibboleth.oidc.security.impl.ExplicitKeySignedJWTTrustEngine">
+ <constructor-arg index="0">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultEntityConfigurationCredentialResolver" />
+ </constructor-arg>
+ <constructor-arg index="1">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultPayloadJOSEObjectCredentialResolver" />
+ </constructor-arg>
+ </bean>
+
+ <bean id="shibboleth.oidfed.DefaultSubordinateStatementTrustEngine"
+ class="net.shibboleth.oidc.security.impl.ExplicitKeySignedJWTTrustEngine">
+ <constructor-arg index="0">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultSubordinateStatementCredentialResolver" />
+ </constructor-arg>
+ <constructor-arg index="1">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultPayloadJOSEObjectCredentialResolver" />
+ </constructor-arg>
+ </bean>
+
+ <bean id="shibboleth.oidfed.DefaultSubjectEntityIDCriteriaToIdentifierStrategy"
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultSubjectEntityIDCriteriaToIdentifierStrategy" />
+
+ <bean id="shibboleth.oidfed.DefaultEntityStatementExpirationTimeStrategy"
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultEntityStatementExpirationTimeStrategy"/>
+
+ <bean id="shibboleth.oidfed.SubordinateEntityStatementMetadataCacheBuilderSpec"
+ class="net.shibboleth.oidc.metadata.cache.impl.DynamicMetadataCacheBuilderSpec"
+ p:metadataExpirationTimeStrategy-ref="shibboleth.oidfed.DefaultEntityStatementExpirationTimeStrategy"
+ p:minCacheDuration="%{idp.oidfed.entityConfiguration.maxRefreshDelay:PT1S}"
+ p:maxCacheDuration="%{idp.oidfed.entityConfiguration.maxRefreshDelay:PT30S}">
+ <property name="identifierExtractionStrategy">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultSubordinateStatementIdentifierExtractionStrategy"/>
+ </property>
+ <property name="criteriaToIdentifierStrategy">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultSubordinateStatementCriteriaToIdentifierStrategy"
+ p:criteriaToSubjectEntityIdStrategy-ref="shibboleth.oidfed.DefaultSubjectEntityIDCriteriaToIdentifierStrategy">
+ <property name="criteriaToIssuerEntityIdStrategy">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultIssuerEntityIDCriteriaToIdentifierStrategy"/>
+ </property>
+ </bean>
+ </property>
+ <property name="metadataFilterStrategy">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultSubordinateStatementSignatureValidationFilterStrategy"
+ p:entityConfigurationCache-ref="shibboleth.oidfed.EntityConfigurationMetadataCache"
+ p:trustEngine-ref="shibboleth.oidfed.DefaultSubordinateStatementTrustEngine"/>
+ </property>
+ <property name="fetchStrategy">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultEntityStatementFetchingStrategy"
+ p:httpClient="#{getObject('shibboleth.oidfed.HttpClient') ?: getObject('shibboleth.InternalHttpClient')}"
+ p:httpClientSecurityParameters="#{getObject('shibboleth.oidfed.NonBrowser.HttpClientSecurityParameters')}">
+ <property name="criteriaToEndpointStrategy">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultSubordinateStatementEndpointExtractionStrategy"
+ p:criteriaToSubjectEntityIdStrategy-ref="shibboleth.oidfed.DefaultSubjectEntityIDCriteriaToIdentifierStrategy"
+ p:entityConfigurationCache-ref="shibboleth.oidfed.EntityConfigurationMetadataCache">
+ <property name="criteriaToIssuerEntityIdStrategy">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultIssuerEntityIDCriteriaToIdentifierStrategy"/>
+ </property>
+ </bean>
+ </property>
+ </bean>
+ </property>
+ </bean>
+
+ <bean id="shibboleth.oidfed.TrustChainMetadataCacheBuilderSpec"
+ class="net.shibboleth.oidc.metadata.cache.impl.DynamicMetadataCacheBuilderSpec"
+ p:criteriaToIdentifierStrategy-ref="shibboleth.oidfed.DefaultSubjectEntityIDCriteriaToIdentifierStrategy"
+ p:minCacheDuration="%{idp.oidfed.entityConfiguration.maxRefreshDelay:PT1S}"
+ p:maxCacheDuration="%{idp.oidfed.entityConfiguration.maxRefreshDelay:PT30S}">
+ <property name="identifierExtractionStrategy">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultTrustChainSubjectIdentifierExtractionStrategy" />
+ </property>
+ <property name="metadataExpirationTimeStrategy">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultTrustChainExpirationTimeStrategy"/>
+ </property>
+ <property name="metadataFilterStrategy">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultTrustAnchorSignatureValidationFilterStrategy">
+ <property name="entityStatementSignatureValidationFilterStrategy">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultEntityStatementSignatureValidationFilterStrategy">
+ <property name="trustEngine">
+ <bean class="net.shibboleth.oidc.security.impl.ExplicitKeySignedJWTTrustEngine">
+ <constructor-arg index="0">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultLocalTrustAnchorCredentialResolver"
+ c:cache-ref="shibboleth.oidfed.LocalTrustAnchorsMetadataCache" />
+ </constructor-arg>
+ <constructor-arg index="1">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultPayloadJOSEObjectCredentialResolver" />
+ </constructor-arg>
+ </bean>
+ </property>
+ </bean>
+ </property>
+ </bean>
+ </property>
+ <property name="fetchStrategy">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultTrustChainFetchingStrategy"
+ p:criteriaToSubjectEntityIdStrategy-ref="shibboleth.oidfed.DefaultSubjectEntityIDCriteriaToIdentifierStrategy"
+ p:entityConfigurationCache-ref="shibboleth.oidfed.EntityConfigurationMetadataCache"
+ p:subordinateStatementCache-ref="shibboleth.oidfed.SubordinateEntityStatementMetadataCache"
+ p:localTrustAnchorsCache-ref="shibboleth.oidfed.LocalTrustAnchorsMetadataCache"
+ p:federationPolicyConstraints-ref="%{idp.oidfed.FederationPolicyConstraints:shibboleth.oidfed.DefaultFederationPolicyConstraints}"
+ p:objectMapper-ref="shibboleth.oidfed.policy.JSONObjectMapper"/>
+ </property>
+ </bean>
+
+ <util:map id="shibboleth.oidfed.DefaultFederationPolicyConstraints"
+ value-type="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.constraints.FederationPolicyConstraint">
+ <entry key="max_path_length">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.constraints.impl.DefaultMaxPathLengthConstraint" />
+ </entry>
+ <entry key="naming_constraints">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.constraints.impl.DefaultNamingConstraintsConstraint" />
+ </entry>
+ <entry key="allowed_entity_types">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.constraints.impl.DefaultAllowedEntityTypesConstraint"
+ p:objectMapper-ref="shibboleth.oidfed.policy.JSONObjectMapper"/>
+ </entry>
+ </util:map>
+
+ <bean id="shibboleth.oidfed.DefaultLocalTrustAnchorsFilename" class="java.lang.String" factory-method="valueOf">
+ <constructor-arg value="%{idp.oidfed.LocalTrustAnchorsFile:%{idp.home}/conf/oidfed/oidfed-trust-anchors.json}" />
+ </bean>
+
+ <bean id="shibboleth.oidfed.LocalTrustAnchorsMetadataCacheBuilderSpec"
+ class="net.shibboleth.oidc.metadata.cache.impl.BatchMetadataCacheBuilderSpec"
+ p:criteriaToIdentifierStrategy-ref="shibboleth.oidfed.LocalTrustAnchorsDefaultIdentifierStrategy"
+ p:identifierExtractionStrategy-ref="shibboleth.oidfed.LocalTrustAnchorsDefaultIdentifierStrategy"
+ p:metadataValidPredicate="#{getObject('shibboleth.oidfed.LocalTrustAnchorsValidator') ?: getObject('shibboleth.oidfed.DefaultLocalTrustAnchorsValidator')}">
+ <property name="loadingStrategy">
+ <bean class="net.shibboleth.oidc.metadata.cache.impl.DefaultResourceLoadingStrategy">
+ <constructor-arg name="metadata">
+ <bean class="org.springframework.core.io.Resource"
+ factory-bean="PreferFileSystemResourceLoader" factory-method="getResource">
+ <constructor-arg>
+ <ref bean="shibboleth.oidfed.DefaultLocalTrustAnchorsFilename" />
+ </constructor-arg>
+ </bean>
+ </constructor-arg>
+ </bean>
+ </property>
+ <property name="parsingStrategy">
+ <bean class="net.shibboleth.oidc.metadata.cache.impl.DefaultJSONMapParsingStrategy"
+ c:valueClass="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.LocalKeyContainer"/>
+ </property>
+ <property name="sourceMetadataExpiryStrategy">
+ <bean class="net.shibboleth.oidc.metadata.cache.impl.DefaultSourceMetadataExpirationTimeStrategy"
+ c:duration="PT10M"/>
+ </property>
+ </bean>
+
+ <bean id="shibboleth.oidfed.DefaultDelegatedTrustMarkTrustEngine"
+ class="net.shibboleth.oidc.security.impl.ExplicitKeySignedJWTTrustEngine">
+ <constructor-arg index="0">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultTrustMarkOwnerCredentialResolver" />
+ </constructor-arg>
+ <constructor-arg index="1">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultPayloadJOSEObjectCredentialResolver" />
+ </constructor-arg>
+ </bean>
+
+ <bean id="PreferFileSystemResourceLoader"
+ class="net.shibboleth.shared.spring.resource.PreferFileSystemResourceLoader"/>
+
+ <bean id="shibboleth.oidfed.DefaultLocalTrustAnchorsValidator"
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultLocalTrustAnchorsValidator"/>
+
+ <bean id="shibboleth.oidfed.LocalTrustAnchorsDefaultIdentifierStrategy"
+ parent="shibboleth.Functions.Constant" c:target="#{getObject('shibboleth.oidfed.DefaultLocalTrustAnchorsFilename') ?: 'undefined'}" />
+
+
+ <bean id="shibboleth.oidfed.policy.JSONObjectMapper" parent="shibboleth.oidc.JSONObjectMapper" />
+
+ <bean id="shibboleth.oidfed.policy.JSONSimpleModule" class="com.fasterxml.jackson.databind.module.SimpleModule"/>
+
+ <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
+ <property name="targetObject" ref="shibboleth.oidfed.policy.JSONSimpleModule" />
+ <property name="targetMethod" value="addDeserializer" />
+ <property name="arguments">
+ <list>
+ <value>#{ T(net.shibboleth.oidc.metadata.policy.MetadataPolicy)}</value>
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.policy.FederationMetadataPolicyDeserializer"
+ c:_0="%{idp.oidfed.policy.arraysAsSpaceSeparatedList:scope}"/>
+ </list>
+ </property>
+ </bean>
+
+ <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
+ <property name="targetObject" ref="shibboleth.oidfed.policy.JSONObjectMapper" />
+ <property name="targetMethod" value="registerModule" />
+ <property name="arguments">
+ <list>
+ <ref bean="shibboleth.oidfed.policy.JSONSimpleModule" />
+ </list>
+ </property>
+ </bean>
+
+ <util:list id="shibboleth.oidfed.StandardMetadataPolicyOperators">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.policy.impl.DefaultFederationMetadataPolicyValueOperator"/>
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.policy.impl.DefaultFederationMetadataPolicyAddOperator"/>
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.policy.impl.DefaultFederationMetadataPolicyDefaultOperator"/>
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.policy.impl.DefaultFederationMetadataPolicyOneOfOperator"/>
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.policy.impl.DefaultFederationMetadataPolicySubsetOfOperator"/>
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.policy.impl.DefaultFederationMetadataPolicySupersetOfOperator"/>
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.policy.impl.DefaultFederationMetadataPolicyEssentialOperator"/>
+ </util:list>
+
+ <bean p:id="oidc/metadata-lookup-ext/oidfed" parent="shibboleth.oidc.MetadataLookupExtensionFlow" />
+
+ <bean id="shibboleth.oidc.DefaultResolveEntityApiMappedErrors"
+ parent="shibboleth.oidc.DefaultApiMappedErrors"
+ class="org.springframework.beans.factory.config.MapFactoryBean">
+ <property name="sourceMap">
+ <map merge="true" value-type="com.nimbusds.oauth2.sdk.ErrorObject">
+ <entry>
+ <key>
+ <util:constant static-field="org.opensaml.profile.action.EventIds.INVALID_MSG_CTX"/>
+ </key>
+ <bean class="com.nimbusds.oauth2.sdk.ErrorObject" c:_0="server_error" c:_1="Internal server error" c:_2="500" />
+ </entry>
+ <entry>
+ <key>
+ <util:constant static-field="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.OidFederationEventIds.INVALID_TRUST_ANCHOR"/>
+ </key>
+ <bean class="com.nimbusds.oauth2.sdk.ErrorObject" c:_0="invalid_trust_anchor" c:_1="Trust anchor in the request is invalid" c:_2="404" />
+ </entry>
+ <entry>
+ <key>
+ <util:constant static-field="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.OidFederationEventIds.INVALID_SUBJECT"/>
+ </key>
+ <bean class="com.nimbusds.oauth2.sdk.ErrorObject" c:_0="invalid_subject" c:_1="Subject in the request is invalid" c:_2="404" />
+ </entry>
+ <entry>
+ <key>
+ <util:constant static-field="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.OidFederationEventIds.INVALID_METADATA"/>
+ </key>
+ <bean class="com.nimbusds.oauth2.sdk.ErrorObject" c:_0="invalid_metadata" c:_1="Metadata is invalid or not found for the requested entity types" c:_2="400" />
+ </entry>
+ </map>
+ </property>
+ </bean>
+
+ <bean id="DefaultTrustMarkClaimsValidationLookupStrategy" parent="shibboleth.Functions.Constant">
+ <constructor-arg name="target">
+ <bean class="net.shibboleth.oidc.security.jwt.claims.impl.ChainingJWTClaimsValidator">
+ <property name="claimValidators">
+ <util:list value-type="net.shibboleth.oidc.jwt.claims.ClaimsValidator">
+ <bean class="net.shibboleth.oidc.security.jwt.claims.impl.IssuedAtClaimsValidator"
+ p:clockSkew="%{idp.policy.clockSkew:PT1M}"
+ p:messageLifetime="%{idp.oidfed.maxTrustMarkifetime:P365D}"
+ p:requiredRule="true" />
+ <bean class="net.shibboleth.oidc.security.jwt.claims.impl.RequiredClaimsValidator"
+ p:requiredClaims="iss" />
+ <bean class="net.shibboleth.oidc.security.jwt.claims.impl.RequiredClaimsValidator"
+ p:requiredClaims="sub" />
+ <bean class="net.shibboleth.oidc.security.jwt.claims.impl.RequiredClaimsValidator"
+ p:requiredClaims="trust_mark_id" />
+ <bean class="net.shibboleth.oidc.security.jwt.claims.impl.ExpiryClaimsValidator"
+ p:clockSkew="%{idp.policy.clockSkew:PT1M}" />
+ </util:list>
+ </property>
+ </bean>
+ </constructor-arg>
+ </bean>
+
+ <bean id="shibboleth.oidfed.DefaultPreSelectedTrustChainIDsLookupStrategy"
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.navigate.DefaultPreSelectedTrustChainIDsLookupStrategy">
+ <property name="profileIdLookupStrategy">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.profile.logic.DefaultMetadataLookupExtensionContextProfileIDLookupFunction"/>
+ </property>
+ <property name="profileSpecificStrategies">
+ <util:map value-type="java.util.function.Function">
+ <entry key="#{T(net.shibboleth.oidc.profile.config.OIDCSSOProfileConfiguration).PROFILE_ID}">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.navigate.DefaultAuthorizePreSelectedTrustChainIDsLookupStrategy"/>
+ </entry>
+ </util:map>
+ </property>
+ </bean>
+
+ <bean id="AutoRegisteredTrustChainAuthorizationCodeClaimsSetDecorator"
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.AutoRegisteredTrustChainAuthorizationCodeClaimsSetDecorator" />
+
+ <bean id="AutoRegisteredTrustChainRequestUriClaimsSetDecorator"
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.AutoRegisteredTrustChainRequestUriClaimsSetDecorator" />
+
+ <bean id="AutomaticRegistrationCondition"
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.logic.DefaultAutomaticRegistrationActivationCondition">
+ <property name="profileIdLookupStrategy">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.profile.logic.DefaultMetadataLookupExtensionContextProfileIDLookupFunction"/>
+ </property>
+ <property name="profileConditions">
+ <util:map value-type="java.util.function.Predicate">
+ <entry key="#{T(net.shibboleth.oidc.profile.config.OIDCSSOProfileConfiguration).PROFILE_ID}">
+ <ref bean="shibboleth.oidfed.authorize.DefaultAutomaticRegistrationCondition"/>
+ </entry>
+ <entry key="#{T(net.shibboleth.oidc.profile.oauth2.config.OAuth2PushedAuthorizationRequestConfiguration).PROFILE_ID}">
+ <ref bean="shibboleth.oidfed.par.DefaultAutomaticRegistrationCondition"/>
+ </entry>
+ </util:map>
+ </property>
+ </bean>
+
+ <bean id="shibboleth.oidfed.authorize.DefaultAutomaticRegistrationCondition" parent="shibboleth.Conditions.AND">
+ <constructor-arg>
+ <list>
+ <ref bean="%{idp.oidfed.authorize.automaticRegistrationCondition:shibboleth.Conditions.FALSE}"/>
+ <bean parent="shibboleth.Conditions.Expression"
+ c:expression="#input.ensureInboundMessageContext().getMessage() instanceof T(com.nimbusds.oauth2.sdk.AuthorizationRequest) and #input.ensureInboundMessageContext().getMessage().specifiesRequestObject()" />
+ <bean parent="shibboleth.Conditions.Expression"
+ c:expression="!(#input.ensureInboundMessageContext().getMessage().getRequestObject() instanceof T(com.nimbusds.jwt.PlainJWT))" />
+ <bean parent="shibboleth.Conditions.OR">
+ <constructor-arg>
+ <list>
+ <bean parent="shibboleth.Conditions.Expression"
+ c:expression="!(#input.ensureInboundMessageContext().getMessage().getRequestObject() instanceof T(com.nimbusds.jwt.SignedJWT))" />
+ <bean parent="shibboleth.Conditions.Expression"
+ c:expression="#input.ensureInboundMessageContext().getMessage().getClientID().getValue().equals(#input.ensureInboundMessageContext().getMessage().getRequestObject().getJWTClaimsSet().getClaim('client_id'))" />
+ </list>
+ </constructor-arg>
+ </bean>
+ </list>
+ </constructor-arg>
+ </bean>
+
+ <bean id="shibboleth.oidfed.par.DefaultAutomaticRegistrationCondition" parent="shibboleth.Conditions.AND">
+ <constructor-arg>
+ <list>
+ <ref bean="%{idp.oidfed.par.automaticRegistrationCondition:shibboleth.Conditions.FALSE}"/>
+ <bean parent="shibboleth.Conditions.Expression"
+ c:expression="#input.ensureInboundMessageContext().getMessage() instanceof T(com.nimbusds.oauth2.sdk.PushedAuthorizationRequest)" />
+ <bean parent="shibboleth.Conditions.Expression"
+ c:expression="!(#input.ensureInboundMessageContext().getMessage().getAuthorizationRequest().getRequestObject() instanceof T(com.nimbusds.jwt.PlainJWT))" />
+ <bean parent="shibboleth.Conditions.OR">
+ <constructor-arg>
+ <bean parent="shibboleth.Conditions.Expression"
+ c:expression="#input.ensureInboundMessageContext().getMessage().getAuthorizationRequest().specifiesRequestObject()" />
+ </constructor-arg>
+ <constructor-arg>
+ <bean parent="shibboleth.Conditions.Expression"
+ c:expression="#input.ensureInboundMessageContext().getMessage().getClientAuthentication() != null and #input.ensureInboundMessageContext().getMessage().getClientAuthentication().getMethod().equals(T(com.nimbusds.oauth2.sdk.auth.ClientAuthenticationMethod).PRIVATE_KEY_JWT)" />
+ </constructor-arg>
+ </bean>
+ <bean parent="shibboleth.Conditions.OR">
+ <constructor-arg>
+ <list>
+ <bean parent="shibboleth.Conditions.Expression"
+ c:expression="!(#input.ensureInboundMessageContext().getMessage().getAuthorizationRequest().getRequestObject() instanceof T(com.nimbusds.jwt.SignedJWT))" />
+ <bean parent="shibboleth.Conditions.Expression"
+ c:expression="#input.ensureInboundMessageContext().getMessage().getAuthorizationRequest().getClientID().getValue().equals(#input.ensureInboundMessageContext().getMessage().getAuthorizationRequest().getRequestObject().getJWTClaimsSet().getClaim('client_id'))" />
+ </list>
+ </constructor-arg>
+ </bean>
+ </list>
+ </constructor-arg>
+ </bean>
+
+ <bean class="net.shibboleth.idp.plugin.oidc.op.security.jwt.claims.RequestObjectClaimsValidator">
+ <constructor-arg>
+ <bean id="shibboleth.oidfed.DefaultRequestObjectClaimsValidation"
+ class="net.shibboleth.oidc.security.jwt.claims.impl.ChainingJWTClaimsValidator"
+ p:claimValidators-ref="FederationClaimsValidators" />
+ </constructor-arg>
+ </bean>
+
+ <util:list id="FederationClaimsValidators" value-type="net.shibboleth.oidc.jwt.claims.ClaimsValidator">
+ <bean class="net.shibboleth.oidc.security.jwt.claims.impl.AudienceClaimsValidator"
+ p:extraAudienceValidation="true">
+ <property name="audienceLookupStrategy">
+ <bean parent="shibboleth.BiFunctions.Expression"
+ c:expression="#custom.apply(#input1)"
+ p:customObject-ref="shibboleth.ResponderIdLookup.Simple" />
+ </property>
+ </bean>
+ <bean class="net.shibboleth.oidc.security.jwt.claims.impl.JWTIdentifierClaimsValidator"
+ p:clockSkew="%{idp.policy.clockSkew:PT1M}"
+ p:replayCache-ref="shibboleth.ReplayCache" />
+ <bean class="net.shibboleth.oidc.security.jwt.claims.impl.RequiredClaimsValidator"
+ p:requiredClaims="exp" />
+ <bean class="net.shibboleth.oidc.security.jwt.claims.impl.ProhibitedClaimsValidator"
+ p:prohibitedClaims="sub" />
+ <bean class="net.shibboleth.oidc.security.jwt.claims.impl.ExactMatchClaimsValidator"
+ p:claimName="client_id">
+ <property name="valueToMatchLookupStrategy">
+ <bean parent="shibboleth.BiFunctions.Expression"
+ c:expression="#custom.apply(#input1.getInboundMessageContext()) == null ? null : #custom.apply(#input1.getInboundMessageContext()).toString()">
+ <property name="customObject">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.profile.logic.DefaultMetadataLookupExtensionContextClientIDLookupFunction" />
+ </property>
+ </bean>
+ </property>
+ </bean>
+ </util:list>
+
+ <bean parent="shibboleth.oidc.PushedAuthorizationErrorMapping">
+ <property name="eventId">
+ <util:constant static-field="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.OidFederationEventIds.INVALID_METADATA_POLICY"/>
+ </property>
+ <property name="errorObject">
+ <bean class="com.nimbusds.oauth2.sdk.ErrorObject" c:_0="invalid_metadata" c:_1="Merged metadata policy is invalid" c:_2="400" />
+ </property>
+ </bean>
+
+ <bean parent="shibboleth.oidc.PushedAuthorizationErrorMapping">
+ <property name="eventId">
+ <util:constant static-field="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.OidFederationEventIds.INVALID_METADATA_AGAINST_POLICY"/>
+ </property>
+ <property name="errorObject">
+ <bean class="com.nimbusds.oauth2.sdk.ErrorObject" c:_0="invalid_metadata" c:_1="Requested metadata is not compliant with the merged policy" c:_2="400" />
+ </property>
+ </bean>
+
+</beans>
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/metadata-lookup-ext/oidfed/metadata-lookup-ext-oidfed-beans.xml b/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/metadata-lookup-ext/oidfed/metadata-lookup-ext-oidfed-beans.xml
new file mode 100644
index 0000000..e16681a
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/metadata-lookup-ext/oidfed/metadata-lookup-ext-oidfed-beans.xml
@@ -0,0 +1,126 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans" xmlns:c="http://www.springframework.org/schema/c"
+ xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
+ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
+ default-init-method="initialize" default-destroy-method="destroy">
+
+ <bean id="InitializeRelyingPartyContext"
+ class="net.shibboleth.idp.plugin.oidc.op.profile.impl.InitializeRelyingPartyContext" scope="prototype">
+ <property name="clientIDLookupStrategy">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.profile.logic.DefaultMetadataLookupExtensionContextClientIDLookupFunction" />
+ </property>
+ </bean>
+
+ <bean id="ResolveTrustChains" class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.ResolveTrustChains"
+ scope="prototype"
+ p:trustChainCache-ref="#{'%{idp.oidfed.authorize.TrustChainMetadataCache:shibboleth.oidfed.TrustChainMetadataCache}'.trim()}"
+ p:metadataPolicyMergingStrategy-ref="#{'%{idp.oidfed.authorize.TrustChainMetadataPolicyMergingStrategy:DefaultTrustChainMetadataPolicyMergingStrategy}'.trim()}"
+ p:metadataPolicyEnforcer-ref="#{'%{idp.oidfed.authorize.MetadataPolicyEnforcer:DefaultMetadataPolicyEnforcer}'.trim()}"
+ p:preSelectedTrustChainIdsLookupStrategy="#{getObject('shibboleth.oidfed.PreSelectedTrustChainIDsLookupStrategy') ?: getObject('shibboleth.oidfed.DefaultPreSelectedTrustChainIDsLookupStrategy')}"
+ p:arraysAsSpaceSeparatedList="%{idp.oidfed.policy.arraysAsSpaceSeparatedList:scope}"
+ p:metadataValidationCondition-ref="#{'%{idp.oidfed.MetadataValidationCondition:DefaultMetadataValidationCondition}'.trim()}">
+ <property name="metadataLookupStrategy">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultCombinedMetadataFromTrustChainLookupStrategy"
+ p:objectMapper-ref="shibboleth.oidc.JSONObjectMapper" />
+ </property>
+ <property name="clientIDLookupStrategy">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.profile.logic.DefaultMetadataLookupExtensionContextClientIDLookupFunction" />
+ </property>
+ </bean>
+
+ <bean id="DefaultMetadataValidationCondition"
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.navigate.DefaultMetadataValidationCondition" />
+
+ <bean id="DefaultMetadataPolicyEnforcer"
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.policy.impl.DefaultFederationMetadataPolicyEnforcer"
+ p:metadataPolicyOperators-ref="#{'%{idp.oidfed.authorize.MetadataPolicyOperatorsy:shibboleth.oidfed.StandardMetadataPolicyOperators}'.trim()}"/>
+
+ <bean id="DefaultTrustChainMetadataPolicyMergingStrategy"
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.navigate.DefaultTrustChainMetadataPolicyMergingStrategy"
+ p:metadataPolicyMergingStrategy-ref="#{'%{idp.oidfed.authorize.MetadataPolicMergingyStrategy:MetadataPolicMergingyStrategy}'.trim()}"
+ p:localMetadataPolicyStrategy-ref="#{'%{idp.oidfed.authorize.LocalMetadataPolicyStrategy:DefaultLocalMetadataPolicyStrategy}'.trim()}"
+ p:objectMapper-ref="shibboleth.oidfed.policy.JSONObjectMapper"/>
+
+ <bean id="MetadataPolicMergingyStrategy"
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.policy.impl.DefaultFederationMetadataPolicyMergingStrategy"
+ p:metadataPolicyOperators-ref="#{'%{idp.oidfed.authorize.MetadataPolicyOperatorsy:shibboleth.oidfed.StandardMetadataPolicyOperators}'.trim()}"/>
+
+ <bean id="DefaultLocalMetadataPolicyStrategy"
+ parent="shibboleth.Functions.Constant">
+ <constructor-arg name="target">
+ <util:map>
+ <entry key="scope">
+ <bean class="net.shibboleth.oidc.metadata.policy.MetadataPolicy">
+ <property name="defaultValue">
+ <util:list value-type="java.lang.String">
+ <value>openid</value>
+ </util:list>
+ </property>
+ </bean>
+ </entry>
+ <entry key="token_endpoint_auth_method">
+ <bean class="net.shibboleth.oidc.metadata.policy.MetadataPolicy" p:defaultValue="private_key_jwt" />
+ </entry>
+ </util:map>
+ </constructor-arg>
+ </bean>
+
+ <bean id="AutomaticRegistrationRelyingPartyCreationStrategy" parent="shibboleth.Functions.Compose"
+ c:g-ref="shibboleth.ChildLookupOrCreate.RelyingPartyContext"
+ c:f-ref="RelyingPartyTrustChainContextLookupStrategy" />
+
+ <bean id="RelyingPartyTrustChainContextLookupStrategy" parent="shibboleth.Functions.Expression"
+ c:expression="#input.ensureInboundMessageContext().getSubcontext(T(net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.RelyingPartyTrustChainContext))" />
+
+ <bean id="SelectAutomaticRegistrationRelyingPartyConfiguration"
+ class="net.shibboleth.idp.profile.impl.SelectRelyingPartyConfiguration" scope="prototype"
+ p:relyingPartyContextLookupStrategy-ref="AutomaticRegistrationRelyingPartyCreationStrategy"
+ p:relyingPartyConfigurationResolver-ref="shibboleth.RelyingPartyResolverService" />
+
+ <bean id="SelectAutomaticRegistrationProfileConfiguration"
+ class="net.shibboleth.idp.profile.impl.SelectProfileConfiguration" scope="prototype"
+ p:relyingPartyContextLookupStrategy-ref="AutomaticRegistrationRelyingPartyCreationStrategy"
+ p:profileId="#{T(net.shibboleth.idp.plugin.oidc.op.oidfed.config.OIDFederationAutomaticRegistrationProfileConfiguration).PROFILE_ID}" />
+
+ <bean id="SelectTrustChain" class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.SelectTrustChain"
+ scope="prototype">
+ <property name="activationCondition">
+ <bean parent="shibboleth.Conditions.Expression"
+ c:expression="#input.ensureInboundMessageContext().containsSubcontext(T(net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.RelyingPartyTrustChainContext))" />
+ </property>
+ </bean>
+
+ <bean id="ResolveTrustMarks" class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.ResolveTrustMarks"
+ scope="prototype"
+ p:trustChainCache-ref="#{'%{idp.oidfed.authorize.TrustChainMetadataCache:shibboleth.oidfed.TrustChainMetadataCache}'.trim()}"
+ p:trustMarkClaimsValidationLookupStrategy="#{getObject('shibboleth.oidfed.TrustMarkClaimsValidationLookupStrategy') ?: getObject('DefaultTrustMarkClaimsValidationLookupStrategy')}"
+ p:delegatedTrustMarkClaimsValidationLookupStrategy="#{getObject('shibboleth.oidfed.DelegatedTrustMarkClaimsValidationLookupStrategy') ?: getObject('DefaultTrustMarkClaimsValidationLookupStrategy')}"
+ p:trustEngine-ref="shibboleth.oidfed.DefaultEntityConfigurationTrustEngine"
+ p:delegationTrustEngine-ref="shibboleth.oidfed.DefaultDelegatedTrustMarkTrustEngine">
+ <property name="trustedTrustMarkIssuersLookupStrategy">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultTrustChainTrustedTrustMarkIssuersLookupStrategy"
+ p:objectMapper-ref="shibboleth.oidc.JSONObjectMapper" />
+ </property>
+ <property name="trustedTrustMarkOwnersLookupStrategy">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultTrustChainTrustedTrustMarkOwnersLookupStrategy"
+ p:objectMapper-ref="shibboleth.oidc.JSONObjectMapper" />
+ </property>
+ </bean>
+
+ <bean id="ValidateAutomaticRegistrationProfileConfiguration"
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.ValidateAutomaticRegistrationProfileConfiguration"
+ scope="prototype">
+ <property name="localMetadataPolicyMergingStrategy">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.navigate.DefaultLocalMetadataPolicyMergingStrategy"
+ p:metadataPolicyEnforcer-ref="#{'%{idp.oidfed.authorize.MetadataPolicyEnforcer:DefaultMetadataPolicyEnforcer}'.trim()}"/>
+ </property>
+ <property name="mandatoryTrustMarksLookupStrategy">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.navigate.MandatoryTrustMarksLookupFunction"
+ p:relyingPartyContextLookupStrategy-ref="AutomaticRegistrationRelyingPartyCreationStrategy"/>
+ </property>
+ </bean>
+
+</beans>
diff --git a/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/metadata-lookup-ext/oidfed/metadata-lookup-ext-oidfed-flow.xml b/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/metadata-lookup-ext/oidfed/metadata-lookup-ext-oidfed-flow.xml
new file mode 100644
index 0000000..ddbff40
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/metadata-lookup-ext/oidfed/metadata-lookup-ext-oidfed-flow.xml
@@ -0,0 +1,50 @@
+<flow xmlns="http://www.springframework.org/schema/webflow"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/webflow http://www.springframework.org/schema/webflow/spring-webflow.xsd">
+
+ <decision-state id="CheckIfResolveTrustChains">
+ <on-entry>
+ <set name="conversationScope.automaticallyRegistered" value="false" />
+ </on-entry>
+ <if test="AutomaticRegistrationCondition.test(opensamlProfileRequestContext) and !opensamlProfileRequestContext.ensureInboundMessageContext().containsSubcontext(T(net.shibboleth.oidc.metadata.context.OIDCMetadataContext))"
+ then="ResolveTrustChains" else="proceed" />
+ </decision-state>
+
+ <action-state id="ResolveTrustChains">
+ <evaluate expression="ResolveTrustChains" />
+ <evaluate expression="'proceed'" />
+ <transition on="proceed" to="CheckIfDoAutomaticRegistration" />
+ </action-state>
+
+ <decision-state id="CheckIfDoAutomaticRegistration">
+ <if test="opensamlProfileRequestContext.ensureInboundMessageContext().containsSubcontext(T(net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.RelyingPartyTrustChainContext)) and opensamlProfileRequestContext.ensureInboundMessageContext().ensureSubcontext(T(net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.RelyingPartyTrustChainContext)).getPolicyCompliantTrustChains() != null and opensamlProfileRequestContext.ensureInboundMessageContext().ensureSubcontext(T(net.shibboleth. [...]
+ then="DoAutomaticRegistration" else="proceed" />
+ </decision-state>
+
+ <action-state id="DoAutomaticRegistration">
+ <evaluate expression="SelectTrustChain" />
+ <evaluate expression="ResolveTrustMarks" />
+ <evaluate expression="SelectAutomaticRegistrationRelyingPartyConfiguration" />
+ <evaluate expression="SelectAutomaticRegistrationProfileConfiguration" />
+ <evaluate expression="ValidateAutomaticRegistrationProfileConfiguration" />
+ <evaluate expression="InitializeRelyingPartyContext" />
+ <evaluate expression="'proceed'" />
+ <transition on="ReselectTrustChain" to="DoAutomaticRegistration" />
+ <transition on="proceed" to="proceed">
+ <set name="conversationScope.automaticallyRegistered" value="opensamlProfileRequestContext.ensureInboundMessageContext().containsSubcontext(T(net.shibboleth.oidc.metadata.context.OIDCMetadataContext))" />
+ </transition>
+ </action-state>
+
+ <end-state id="proceed"/>
+ <end-state id="InvalidMetadataPolicy"/>
+ <end-state id="InvalidMetadataAgainstPolicy"/>
+
+ <global-transitions>
+ <transition on="InvalidMetadataPolicy" to="InvalidMetadataPolicy" />
+ <transition on="InvalidMetadataAgainstPolicy" to="InvalidMetadataAgainstPolicy" />
+ </global-transitions>
+
+
+ <bean-import resource="classpath:/META-INF/net/shibboleth/idp/flows/oidc/metadata-lookup-ext/oidfed/metadata-lookup-ext-oidfed-beans.xml" />
+
+</flow>
diff --git a/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/entity-configuration/entity-configuration-beans.xml b/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/entity-configuration/entity-configuration-beans.xml
new file mode 100644
index 0000000..585c079
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/entity-configuration/entity-configuration-beans.xml
@@ -0,0 +1,165 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans" xmlns:c="http://www.springframework.org/schema/c"
+ xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
+ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
+ default-init-method="initialize" default-destroy-method="destroy">
+
+ <bean id="shibboleth.oidc.profileId" class="java.lang.String"
+ c:_0="#{T(net.shibboleth.idp.plugin.oidc.op.oidfed.config.OIDFederationEntityConfigurationProfileConfiguration).PROFILE_ID}" />
+
+ <bean id="shibboleth.oidc.loggingId" class="java.lang.String" c:_0="%{idp.service.logging.oidfedconfig:OIDFED.Configuration}" />
+
+ <util:constant id="shibboleth.metrics.ProfileCounter"
+ static-field="net.shibboleth.idp.plugin.oidc.op.oidfed.config.DefaultOIDFederationEntityConfigurationProfileConfiguration.PROFILE_COUNTER" />
+
+ <bean id="shibboleth.oidfed.EntityConfigurationResponseMetadataCache" parent="shibboleth.oidc.CacheBuilder">
+ <constructor-arg>
+ <bean p:cacheId="DefaultEntityConfigurationResponseMetadataCache" parent="shibboleth.oidfed.EntityConfigurationResponseMetadataCacheBuilderSpec"
+ p:cleanupTaskInterval="PT30S"/>
+ </constructor-arg>
+ </bean>
+
+ <bean id="shibboleth.oidfed.EntityConfigurationResponseMetadataCacheBuilderSpec"
+ class="net.shibboleth.oidc.metadata.cache.impl.DynamicMetadataCacheBuilderSpec"
+ p:minCacheDuration="%{idp.oidfed.entity-configuration.maxRefreshDelay:PT1S}"
+ p:maxCacheDuration="%{idp.oidfed.entity-configuration.maxRefreshDelay:PT30S}">
+ <property name="criteriaToIdentifierStrategy">
+ <bean parent="shibboleth.Functions.Constant" c:target-ref="shibboleth.oidc.issuer" />
+ </property>
+ <property name="identifierExtractionStrategy">
+ <bean parent="shibboleth.Functions.Constant" c:target-ref="shibboleth.oidc.issuer" />
+ </property>
+ <property name="metadataExpirationTimeStrategy">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultEntityConfigurationResponseContainerExpirationTimeStrategy"/>
+ </property>
+ <property name="metadataFilterStrategy">
+ <bean parent="shibboleth.BiFunctions.Expression" c:expression="#input1"/>
+ </property>
+ <property name="fetchStrategy">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultEntityConfigurationResponseFetchingStrategy" />
+ </property>
+ </bean>
+
+ <bean id="LookupCachedEntityConfigurationResponse"
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.LookupCachedEntityConfigurationResponse"
+ scope="prototype"
+ p:responseCache-ref="shibboleth.oidfed.EntityConfigurationResponseMetadataCache" />
+
+ <bean id="InitializeEntityStatementContext"
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.InitializeEntityStatementContext"
+ p:metadataResolver-ref="#{'%{idp.oidfed.configuration.resolver:shibboleth.oidfed.DefaultOpenIdConfigurationResolver}'.trim()}"
+ p:metadataSkeletonLookupStrategy-ref="#{'%{idp.oidfed.configuration.EntityConfigurationMetadataSkeletonLookupStrategy:DefaultEntityConfigurationMetadataSkeletonLookupStrategy}'.trim()}"/>
+
+ <bean id="DefaultEntityConfigurationMetadataSkeletonLookupStrategy"
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultEntityConfigurationMetadataSkeletonLookupStrategy"
+ p:metadataSkeletonCache-ref="shibboleth.oidfed.EntityConfigurationMetadataSkeletonMetadataCache"/>
+
+ <bean id="PopulateEntityStatementSignatureSigningParameters"
+ class="net.shibboleth.oidc.profile.impl.PopulateJWTSignatureSigningParameters" scope="prototype"
+ c:strategy-ref="shibboleth.MessageContextLookup.Outbound"
+ p:securityParametersContextLookupStrategy-ref="EntityStatementSecurityParametersContextLookupStrategy">
+ <property name="configurationLookupStrategy">
+ <bean lazy-init="true"
+ class="net.shibboleth.oidc.profile.config.navigate.JWTSignatureSigningConfigurationLookupFunction" />
+ </property>
+ <property name="signatureSigningParametersResolver">
+ <bean class="net.shibboleth.oidc.security.jose.impl.ClientInformationSignatureSigningParametersResolver">
+ <constructor-arg name="signatureAlgorithmLookupStrategy">
+ <bean parent="shibboleth.Functions.Constant" c:target="" />
+ </constructor-arg>
+ <constructor-arg name="defaultAlgorithmValue" value="%{idp.oidfed.entity.sigalg:RS256}" />
+ </bean>
+ </property>
+ </bean>
+
+ <bean id="EntityStatementSecurityParametersContextLookupStrategy" parent="shibboleth.Functions.Compose"
+ c:g-ref="shibboleth.oidc.ChildLookupOrCreate.JWTSecurityParameters"
+ c:f-ref="shibboleth.ChildLookup.RelyingParty" />
+
+ <bean id="EntityStatementSecurityParametersCreationViaMessageContextStrategy" parent="shibboleth.Functions.Compose">
+ <constructor-arg name="g" ref="EntityStatementSecurityParametersContextLookupStrategy" />
+ <constructor-arg name="f">
+ <bean parent="shibboleth.Functions.Expression" c:expression="#input.getParent()" />
+ </constructor-arg>
+ </bean>
+
+ <bean id="SelectOidcConfigurationProfileConfiguration"
+ class="net.shibboleth.idp.profile.impl.SelectProfileConfiguration" scope="prototype"
+ p:profileId="#{T(net.shibboleth.oidc.profile.config.OIDCProviderInformationConfiguration).PROFILE_ID}" />
+
+ <bean id="ConfigurationRelyingPartyCreationStrategy" parent="shibboleth.Functions.Compose"
+ c:g-ref="shibboleth.ChildLookupOrCreate.RelyingPartyContext"
+ c:f-ref="shibboleth.MessageContextLookup.Outbound" />
+
+ <bean id="BuildEntityStatement"
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.BuildEntityConfiguration" scope="prototype"
+ p:identifierGeneratorLookupStrategy-ref="shibboleth.oidc.DefaultIdentifierGenerationStrategy"
+ p:objectMapper-ref="#{'%{idp.oidc.logging.objectMapper:shibboleth.oidc.JSONObjectMapper}'.trim()}" />
+
+ <bean id="SignEntityStatement" class="net.shibboleth.idp.profile.impl.WebFlowMessageHandlerAdaptor"
+ scope="prototype" c:executionDirection="OUTBOUND ">
+ <constructor-arg name="messageHandler">
+ <bean id="SignEntityStatementHandler"
+ class="net.shibboleth.oidc.security.impl.SignJWTHandler" scope="prototype" p:logName="Entity Statement"
+ p:securityParametersLookupStrategy-ref="EntityStatementSecurityParametersCreationViaMessageContextStrategy"
+ p:typeHeader="entity-statement+jwt">
+ <property name="claimsToSignLookupStrategy">
+ <bean
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.JWTClaimsSetFromEntityStatementLookupFunction" />
+ </property>
+ <property name="jwtUpdateConsumer">
+ <bean
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.EntityStatementUpdateStrategy" />
+ </property>
+ </bean>
+ </constructor-arg>
+ </bean>
+
+ <bean id="FormOutboundMessage" class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.FormOutboundFederationConfigurationResponse"
+ scope="prototype" p:responseCache-ref="shibboleth.oidfed.EntityConfigurationResponseMetadataCache">
+ </bean>
+
+ <bean id="shibboleth.oidfed.EntityConfigurationMetadataSkeletonMetadataCache" parent="shibboleth.oidc.CacheBuilder">
+ <constructor-arg>
+ <bean p:cacheId="DefaultEntityConfigurationMetadataSkeletonMetadataCache"
+ parent="shibboleth.oidfed.EntityConfigurationMetadataSkeletonMetadataCacheBuilderSpec"/>
+ </constructor-arg>
+ </bean>
+
+ <bean id="shibboleth.oidfed.EntityConfigurationMetadataSkeletonMetadataCacheBuilderSpec"
+ class="net.shibboleth.oidc.metadata.cache.impl.BatchMetadataCacheBuilderSpec"
+ p:metadataValidPredicate-ref="shibboleth.Conditions.TRUE">
+ <property name="criteriaToIdentifierStrategy">
+ <bean parent="shibboleth.Functions.Constant" c:target-ref="shibboleth.oidc.issuer" />
+ </property>
+ <property name="identifierExtractionStrategy">
+ <bean parent="shibboleth.Functions.Constant" c:target-ref="shibboleth.oidc.issuer" />
+ </property>
+ <property name="loadingStrategy">
+ <bean class="net.shibboleth.oidc.metadata.cache.impl.DefaultResourceLoadingStrategy">
+ <constructor-arg name="metadata">
+ <bean class="org.springframework.core.io.Resource"
+ factory-bean="PreferFileSystemResourceLoader" factory-method="getResource">
+ <constructor-arg>
+ <bean class="java.lang.String" factory-method="valueOf">
+ <constructor-arg value="%{idp.oidfed.configuration.MetadataSkaletonFile:%{idp.home}/conf/oidfed/oidfed-entity-configuration-metadata.json}" />
+ </bean>
+ </constructor-arg>
+ </bean>
+ </constructor-arg>
+ </bean>
+ </property>
+ <property name="parsingStrategy">
+ <bean class="net.shibboleth.oidc.metadata.cache.impl.DefaultJSONMapParsingStrategy"
+ c:valueClass="java.util.Map"/>
+ </property>
+ <property name="sourceMetadataExpiryStrategy">
+ <bean class="net.shibboleth.oidc.metadata.cache.impl.DefaultSourceMetadataExpirationTimeStrategy"
+ c:duration="%{idp.oidfed.configuration.MetadataSkaletonCacheLifetime:PT10M}"/>
+ </property>
+ </bean>
+
+</beans>
diff --git a/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/entity-configuration/entity-configuration-flow.xml b/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/entity-configuration/entity-configuration-flow.xml
new file mode 100644
index 0000000..670f03d
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/entity-configuration/entity-configuration-flow.xml
@@ -0,0 +1,39 @@
+<flow xmlns="http://www.springframework.org/schema/webflow"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/webflow http://www.springframework.org/schema/webflow/spring-webflow.xsd"
+ parent="oidc/abstract-api-info">
+
+ <action-state id="InitializeMandatoryContexts">
+ <on-entry>
+ <set name="flowScope.transitionAfterInboundIntercept" value="'LookupCachedResponse'" />
+ </on-entry>
+ </action-state>
+
+ <action-state id="LookupCachedResponse">
+ <evaluate expression="LookupCachedEntityConfigurationResponse" />
+ <evaluate expression="'proceed'" />
+ <transition on="CachedEntityConfigurationResponseFound" to="BuildResponseMessage" />
+ <transition on="proceed" to="InitializeEntityStatementContext" />
+ </action-state>
+
+ <action-state id="InitializeEntityStatementContext">
+ <evaluate expression="SelectOidcConfigurationProfileConfiguration" />
+ <evaluate expression="InitializeEntityStatementContext"/>
+ <evaluate expression="SelectProfileConfiguration" />
+ <evaluate expression="'proceed'" />
+
+ <transition on="proceed" to="BuildEntityConfiguration" />
+ </action-state>
+
+ <action-state id="BuildEntityConfiguration">
+ <evaluate expression="PopulateEntityStatementSignatureSigningParameters" />
+ <evaluate expression="BuildEntityStatement" />
+ <evaluate expression="SignEntityStatement" />
+ <evaluate expression="'proceed'" />
+
+ <transition on="proceed" to="BuildResponseMessage"/>
+ </action-state>
+
+ <bean-import resource="entity-configuration-beans.xml" />
+
+</flow>
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/register/register-beans.xml b/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/register/register-beans.xml
new file mode 100644
index 0000000..8d6c7ad
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/register/register-beans.xml
@@ -0,0 +1,360 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:c="http://www.springframework.org/schema/c"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:util="http://www.springframework.org/schema/util"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
+ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
+ default-init-method="initialize" default-destroy-method="destroy">
+
+ <bean id="shibboleth.oidc.profileId" class="java.lang.String"
+ c:_0="#{T(net.shibboleth.idp.plugin.oidc.op.oidfed.config.OIDFederationExplicitRegistrationProfileConfiguration).PROFILE_ID}" />
+
+ <bean id="shibboleth.oidc.loggingId" class="java.lang.String"
+ c:_0="%{idp.service.logging.oidfeddynreg:OIDFED.Registration}" />
+
+ <bean id="shibboleth.ClientIDLookupStrategy"
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.navigate.ExplicitClientRegistrationRequestClientIDLookupFunction" />
+
+ <util:constant id="shibboleth.metrics.ProfileCounter"
+ static-field="net.shibboleth.idp.plugin.oidc.op.oidfed.config.DefaultOIDFederationExplicitRegistrationProfileConfiguration.PROFILE_COUNTER" />
+
+ <bean id="DecodeMessage" class="org.opensaml.profile.action.impl.DecodeMessage" scope="prototype">
+ <constructor-arg>
+ <bean
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.decoding.impl.ExplicitClientRegistrationRequestDecoder"
+ scope="prototype"
+ p:httpServletRequestSupplier-ref="shibboleth.HttpServletRequestSupplier"
+ p:removeIpAddressFromEndpointUri="%{idp.oidc.logging.removeIpAddressFromProtocolMessage:false}"
+ p:objectMapper-ref="#{'%{idp.oidc.logging.objectMapper:shibboleth.oidc.JSONObjectMapper}'.trim()}"/>
+ <!-- TODO: support custom parsing? p:customRequestParser="#{getObject('%{idp.oidc.requestParser.FederationRegisterRequest:}'.trim())}"/>-->
+ </constructor-arg>
+ </bean>
+
+ <bean id="ExplicitRegistrationRelyingPartyCreationStrategy" parent="shibboleth.Functions.Expression"
+ c:expression="#input.ensureSubcontext(T(net.shibboleth.profile.context.RelyingPartyContext))" />
+
+ <bean id="ValidateProvidedTrustChain" class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.ValidateProvidedTrustChain"
+ scope="prototype"
+ p:metadataPolicyMergingStrategy-ref="#{'%{idp.oidfed.register.TrustChainMetadataPolicyMergingStrategy:DefaultTrustChainMetadataPolicyMergingStrategy}'.trim()}"
+ p:metadataPolicyEnforcer-ref="#{'%{idp.oidfed.register.MetadataPolicyEnforcer:DefaultMetadataPolicyEnforcer}'.trim()}"
+ p:arraysAsSpaceSeparatedList="%{idp.oidfed.policy.arraysAsSpaceSeparatedList:scope}"
+ p:metadataLookupStrategy-ref="DefaultCombinedMetadataFromTrustChainLookupStrategy"
+ p:metadataValidationCondition-ref="#{'%{idp.oidfed.MetadataValidationCondition:DefaultMetadataValidationCondition}'.trim()}">
+ <property name="providedTrustChainValidationStrategy">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultProvidedTrustChainValidationStrategy"
+ p:federationPolicyConstraints-ref="%{idp.oidfed.FederationPolicyConstraints:shibboleth.oidfed.DefaultFederationPolicyConstraints}"
+ p:objectMapper-ref="shibboleth.oidfed.policy.JSONObjectMapper"
+ p:trustEngine-ref="shibboleth.oidfed.DefaultEntityConfigurationTrustEngine">
+ <property name="trustAnchorSignatureValidationFilterStrategy">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultEntityStatementSignatureValidationFilterStrategy">
+ <property name="trustEngine">
+ <bean class="net.shibboleth.oidc.security.impl.ExplicitKeySignedJWTTrustEngine">
+ <constructor-arg index="0">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultLocalTrustAnchorCredentialResolver"
+ c:cache-ref="shibboleth.oidfed.LocalTrustAnchorsMetadataCache" />
+ </constructor-arg>
+ <constructor-arg index="1">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultPayloadJOSEObjectCredentialResolver" />
+ </constructor-arg>
+ </bean>
+ </property>
+ </bean>
+ </property>
+ </bean>
+ </property>
+ <property name="providedTrustChainLookupStrategy">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.navigate.ExplicitClientRegistrationRequestTrustChainLookupFunction" />
+ </property>
+ </bean>
+
+ <bean id="DefaultMetadataValidationCondition"
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.navigate.DefaultMetadataValidationCondition" />
+
+ <bean id="DefaultCombinedMetadataFromTrustChainLookupStrategy"
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultCombinedMetadataFromTrustChainLookupStrategy"
+ p:objectMapper-ref="shibboleth.oidc.JSONObjectMapper" />
+
+ <bean id="ResolveTrustChains" class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.ResolveTrustChains"
+ scope="prototype"
+ p:trustChainCache-ref="#{'%{idp.oidfed.register.TrustChainMetadataCache:FetchThroughTrustChainMetadataCache}'.trim()}"
+ p:clientIDLookupStrategy-ref="shibboleth.ClientIDLookupStrategy"
+ p:metadataPolicyMergingStrategy-ref="#{'%{idp.oidfed.register.TrustChainMetadataPolicyMergingStrategy:DefaultTrustChainMetadataPolicyMergingStrategy}'.trim()}"
+ p:metadataPolicyEnforcer-ref="#{'%{idp.oidfed.register.MetadataPolicyEnforcer:DefaultMetadataPolicyEnforcer}'.trim()}"
+ p:preSelectedTrustChainIdsLookupStrategy="#{getObject('shibboleth.oidfed.PreSelectedTrustChainIDsLookupStrategy') ?: getObject('shibboleth.oidfed.DefaultPreSelectedTrustChainIDsLookupStrategy')}"
+ p:requireEntityConfigurationCondition-ref="shibboleth.Conditions.TRUE"
+ p:arraysAsSpaceSeparatedList="%{idp.oidfed.policy.arraysAsSpaceSeparatedList:scope}"
+ p:metadataLookupStrategy-ref="DefaultCombinedMetadataFromTrustChainLookupStrategy"
+ p:metadataValidationCondition-ref="#{'%{idp.oidfed.MetadataValidationCondition:DefaultMetadataValidationCondition}'.trim()}">
+ <property name="entityConfigurationLookupStrategy">
+ <bean parent="shibboleth.Functions.Expression"
+ c:expression="#custom.apply(#input.ensureInboundMessageContext().getMessage().getEntityConfiguration(), null)">
+ <property name="customObject">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultEntityStatementSignatureValidationFilterStrategy"
+ p:trustEngine-ref="shibboleth.oidfed.DefaultEntityConfigurationTrustEngine"/>
+ </property>
+ </bean>
+ </property>
+ </bean>
+
+ <bean id="FetchThroughTrustChainMetadataCache" parent="shibboleth.oidc.CacheBuilder">
+ <constructor-arg>
+ <bean p:cacheId="FetchThroughTrustChainMetadataCache" parent="FetchThroughTrustChainMetadataCacheBuilderSpec"/>
+ </constructor-arg>
+ </bean>
+
+ <bean id="FetchThroughTrustChainMetadataCacheBuilderSpec"
+ class="net.shibboleth.oidc.metadata.cache.impl.FetchThroughMetadataCacheBuilderSpec"
+ p:criteriaToIdentifierStrategy-ref="shibboleth.oidfed.DefaultSubjectEntityIDCriteriaToIdentifierStrategy">
+ <property name="identifierExtractionStrategy">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultTrustChainSubjectIdentifierExtractionStrategy" />
+ </property>
+ <property name="fetchStrategy">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultTrustChainFetchingStrategy"
+ p:criteriaToSubjectEntityIdStrategy-ref="shibboleth.oidfed.DefaultSubjectEntityIDCriteriaToIdentifierStrategy"
+ p:entityConfigurationCache-ref="shibboleth.oidfed.EntityConfigurationMetadataCache"
+ p:subordinateStatementCache-ref="shibboleth.oidfed.SubordinateEntityStatementMetadataCache"
+ p:localTrustAnchorsCache-ref="shibboleth.oidfed.LocalTrustAnchorsMetadataCache"
+ p:federationPolicyConstraints-ref="%{idp.oidfed.FederationPolicyConstraints:shibboleth.oidfed.DefaultFederationPolicyConstraints}"
+ p:objectMapper-ref="shibboleth.oidfed.policy.JSONObjectMapper" />
+ </property>
+ </bean>
+
+ <bean id="DefaultMetadataPolicyEnforcer"
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.policy.impl.DefaultFederationMetadataPolicyEnforcer"
+ p:metadataPolicyOperators-ref="#{'%{idp.oidfed.register.MetadataPolicyOperatorsy:shibboleth.oidfed.StandardMetadataPolicyOperators}'.trim()}"/>
+
+ <bean id="DefaultTrustChainMetadataPolicyMergingStrategy"
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.navigate.DefaultTrustChainMetadataPolicyMergingStrategy"
+ p:metadataPolicyMergingStrategy-ref="#{'%{idp.oidfed.register.MetadataPolicMergingyStrategy:MetadataPolicMergingyStrategy}'.trim()}"
+ p:localMetadataPolicyStrategy-ref="#{'%{idp.oidfed.register.LocalMetadataPolicyStrategy:DefaultLocalMetadataPolicyStrategy}'.trim()}"
+ p:objectMapper-ref="shibboleth.oidfed.policy.JSONObjectMapper"/>
+
+ <bean id="MetadataPolicMergingyStrategy"
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.policy.impl.DefaultFederationMetadataPolicyMergingStrategy"
+ p:metadataPolicyOperators-ref="#{'%{idp.oidfed.register.MetadataPolicyOperatorsy:shibboleth.oidfed.StandardMetadataPolicyOperators}'.trim()}"/>
+
+ <bean id="DefaultLocalMetadataPolicyStrategy"
+ parent="shibboleth.Functions.Constant">
+ <constructor-arg name="target">
+ <util:map>
+ <entry key="scope">
+ <bean class="net.shibboleth.oidc.metadata.policy.MetadataPolicy">
+ <property name="defaultValue">
+ <util:list value-type="java.lang.String">
+ <value>openid</value>
+ </util:list>
+ </property>
+ </bean>
+ </entry>
+ <entry key="token_endpoint_auth_method">
+ <bean class="net.shibboleth.oidc.metadata.policy.MetadataPolicy" p:defaultValue="private_key_jwt" />
+ </entry>
+ </util:map>
+ </constructor-arg>
+ </bean>
+
+ <bean id="SelectTrustChain" class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.SelectTrustChain"
+ scope="prototype"
+ p:relyingPartyContextCreationStrategy-ref="ExplicitRegistrationRelyingPartyCreationStrategy">
+ <property name="activationCondition">
+ <bean parent="shibboleth.Conditions.Expression"
+ c:expression="#input.ensureInboundMessageContext().containsSubcontext(T(net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.RelyingPartyTrustChainContext))" />
+ </property>
+ </bean>
+
+ <bean id="ResolveTrustMarks" class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.ResolveTrustMarks"
+ scope="prototype"
+ p:trustChainCache-ref="#{'%{idp.oidfed.register.TrustChainMetadataCache:shibboleth.oidfed.TrustChainMetadataCache}'.trim()}"
+ p:trustMarkClaimsValidationLookupStrategy="#{getObject('shibboleth.oidfed.TrustMarkClaimsValidationLookupStrategy') ?: getObject('DefaultTrustMarkClaimsValidationLookupStrategy')}"
+ p:delegatedTrustMarkClaimsValidationLookupStrategy="#{getObject('shibboleth.oidfed.DelegatedTrustMarkClaimsValidationLookupStrategy') ?: getObject('DefaultTrustMarkClaimsValidationLookupStrategy')}"
+ p:trustEngine-ref="shibboleth.oidfed.DefaultEntityConfigurationTrustEngine"
+ p:delegationTrustEngine-ref="shibboleth.oidfed.DefaultDelegatedTrustMarkTrustEngine">
+ <property name="trustedTrustMarkIssuersLookupStrategy">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultTrustChainTrustedTrustMarkIssuersLookupStrategy"
+ p:objectMapper-ref="shibboleth.oidc.JSONObjectMapper" />
+ </property>
+ <property name="trustedTrustMarkOwnersLookupStrategy">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultTrustChainTrustedTrustMarkOwnersLookupStrategy"
+ p:objectMapper-ref="shibboleth.oidc.JSONObjectMapper" />
+ </property>
+ </bean>
+
+ <bean id="RelyingPartyTrustChainContextLookupStrategy" parent="shibboleth.Functions.Expression"
+ c:expression="#input.ensureInboundMessageContext().getSubcontext(T(net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.RelyingPartyTrustChainContext))" />
+
+ <bean id="SelectExplicitRegistrationRelyingPartyConfiguration"
+ class="net.shibboleth.idp.profile.impl.SelectRelyingPartyConfiguration" scope="prototype"
+ p:relyingPartyContextLookupStrategy-ref="ExplicitRegistrationRelyingPartyCreationStrategy"
+ p:relyingPartyConfigurationResolver-ref="shibboleth.RelyingPartyResolverService" />
+
+ <bean id="SelectExplicitRegistrationProfileConfiguration"
+ class="net.shibboleth.idp.profile.impl.SelectProfileConfiguration" scope="prototype"
+ p:relyingPartyContextLookupStrategy-ref="ExplicitRegistrationRelyingPartyCreationStrategy"
+ p:profileId="#{T(net.shibboleth.idp.plugin.oidc.op.oidfed.config.OIDFederationExplicitRegistrationProfileConfiguration).PROFILE_ID}" />
+
+ <bean id="InitializeRegistrationMetadataPolicyContext"
+ class="net.shibboleth.idp.plugin.oidc.op.profile.impl.InitializeRegistrationMetadataPolicyContext"
+ scope="prototype"
+ p:metadataPolicyValidationStrategy="#{getObject('shibboleth.oidc.dynreg.MetadataPolicyValidator') ?: getObject('shibboleth.oidc.dynreg.DefaultMetadataPolicyValidator')}" />
+
+ <bean id="ValidateExplicitRegistrationProfileConfiguration"
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.ValidateAutomaticRegistrationProfileConfiguration"
+ scope="prototype">
+ <property name="localMetadataPolicyMergingStrategy">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.navigate.DefaultLocalMetadataPolicyMergingStrategy"
+ p:metadataPolicyEnforcer-ref="#{'%{idp.oidfed.register.MetadataPolicyEnforcer:DefaultMetadataPolicyEnforcer}'.trim()}"/>
+ </property>
+ <property name="mandatoryTrustMarksLookupStrategy">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.navigate.MandatoryTrustMarksLookupFunction"
+ p:relyingPartyContextLookupStrategy-ref="ExplicitRegistrationRelyingPartyCreationStrategy"/>
+ </property>
+ </bean>
+
+ <bean id="ValidateRegistrationRequestMetadata"
+ 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"
+ scope="prototype"
+ p:httpClient="#{getObject('shibboleth.oidc.NonBrowser.HttpClient') ?: getObject('shibboleth.InternalHttpClient')}"
+ p:httpClientSecurityParameters="#{getObject('shibboleth.oidc.NonBrowser.HttpClientSecurityParameters')}"
+ p:objectMapper-ref="shibboleth.oidc.JSONObjectMapper">
+ <property name="requestMetadataLookupStrategy">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.navigate.DefaultSelectedTrustChainMetadataLookupStrategy" />
+ </property>
+ </bean>
+
+ <bean id="GenerateClientID"
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.GenerateClientID"
+ scope="prototype"
+ p:clientIDLookupStrategy-ref="shibboleth.ClientIDLookupStrategy" />
+
+ <bean id="GenerateClientSecret"
+ class="net.shibboleth.idp.plugin.oidc.op.profile.impl.GenerateClientSecret" scope="prototype"
+ p:xmlSafeIdentifier="%{idp.oidc.xmlSafeIdentifiers:true}"
+ p:identifierGeneratorLookupStrategy="#{getObject('shibboleth.oidc.dynreg.ClientSecretGenerationStrategy') ?: getObject('shibboleth.oidc.DefaultIdentifierGenerationStrategy')}">
+ <property name="secretExpirationPeriodStrategy">
+ <bean class="net.shibboleth.oidc.profile.config.navigate.SecretExpirationPeriodLookupFunction" />
+ </property>
+ </bean>
+
+ <bean id="shibboleth.oidc.InputMetadataLookupStrategy"
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.navigate.DefaultSelectedTrustChainMetadataLookupStrategy" />
+
+ <bean id="shibboleth.oidc.TokenEndpointAuthMethodsLookupStrategy"
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.config.TokenEndpointAuthMethodLookupFunction" />
+
+ <bean id="shibboleth.oidc.DefaultScope"
+ class="com.nimbusds.oauth2.sdk.Scope" factory-method="parse">
+ <constructor-arg type="java.lang.String"
+ value="#{'%{idp.oidfed.expreg.defaultScope:openid profile email address phone offline_access}'.trim()}" />
+ </bean>
+
+ <bean id="shibboleth.oidc.DefaultSubjectType"
+ class="com.nimbusds.openid.connect.sdk.SubjectType"
+ factory-method="parse">
+ <constructor-arg type="java.lang.String"
+ value="#{'%{idp.oidfed.expreg.defaultSubjectType:public}'.trim()}" />
+ </bean>
+
+ <bean id="AddJwksToClientMetadata"
+ class="net.shibboleth.idp.plugin.oidc.op.profile.impl.AddJwksToClientMetadata"
+ scope="prototype"
+ p:httpClient="#{getObject('shibboleth.oidc.NonBrowser.HttpClient') ?: getObject('shibboleth.InternalHttpClient')}"
+ p:httpClientSecurityParameters="#{getObject('shibboleth.oidc.NonBrowser.HttpClientSecurityParameters')}"
+ p:oidcInputMetadataLookupStrategy-ref="shibboleth.oidc.InputMetadataLookupStrategy"
+ p:validateRemoteJwkSetPredicate-ref="%{idp.oidfed.expreg.validateRemoteJwks:shibboleth.Conditions.TRUE}"/>
+
+ <bean id="StoreClientInformation"
+ class="net.shibboleth.idp.plugin.oidc.op.profile.impl.StoreClientInformation" scope="prototype"
+ p:clientInformationManager-ref="#{'%{idp.oidfed.expreg.clientInformationManager:shibboleth.oidc.ClientInformationManager}'.trim()}"
+ p:replacementCondition-ref="shibboleth.Conditions.TRUE">
+ <property name="registrationValidityPeriodStrategy">
+ <bean parent="shibboleth.Functions.Expression"
+ c:expression="T(java.time.Duration).between(T(java.time.Instant).now(), #input.ensureInboundMessageContext().ensureSubcontext(T(net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.RelyingPartyTrustChainContext)).getSelectedMetadataExpiration())" />
+ </property>
+ </bean>
+
+ <bean id="BuildErrorResponseFromEvent"
+ class="net.shibboleth.idp.plugin.oidc.op.profile.impl.BuildRegistrationErrorResponseFromEvent"
+ scope="prototype"
+ p:httpServletResponseSupplier-ref="shibboleth.HttpServletResponseSupplier"
+ p:mappedErrors="#{getObject('shibboleth.oidc.register.MappedErrors') ?: getObject('shibboleth.oidc.register.DefaultMappedErrors')}">
+ <property name="eventContextLookupStrategy">
+ <bean
+ class="net.shibboleth.idp.profile.context.navigate.WebFlowCurrentEventLookupFunction" />
+ </property>
+ </bean>
+
+ <bean id="PopulateEntityStatementSignatureSigningParameters"
+ class="net.shibboleth.oidc.profile.impl.PopulateJWTSignatureSigningParameters" scope="prototype"
+ c:strategy-ref="shibboleth.MessageContextLookup.Outbound"
+ p:securityParametersContextLookupStrategy-ref="EntityStatementSecurityParametersContextLookupStrategy">
+ <property name="configurationLookupStrategy">
+ <bean lazy-init="true"
+ class="net.shibboleth.oidc.profile.config.navigate.JWTSignatureSigningConfigurationLookupFunction" />
+ </property>
+ <property name="signatureSigningParametersResolver">
+ <bean class="net.shibboleth.oidc.security.jose.impl.ClientInformationSignatureSigningParametersResolver">
+ <constructor-arg name="signatureAlgorithmLookupStrategy">
+ <bean parent="shibboleth.Functions.Constant" c:target="" />
+ </constructor-arg>
+ <constructor-arg name="defaultAlgorithmValue" value="%{idp.oidfed.entity.sigalg:RS256}" />
+ </bean>
+ </property>
+ </bean>
+
+ <bean id="EntityStatementSecurityParametersContextLookupStrategy" parent="shibboleth.Functions.Compose"
+ c:g-ref="shibboleth.oidc.ChildLookupOrCreate.JWTSecurityParameters"
+ c:f-ref="shibboleth.ChildLookup.RelyingParty" />
+
+ <bean id="EntityStatementSecurityParametersCreationViaMessageContextStrategy" parent="shibboleth.Functions.Compose">
+ <constructor-arg name="g" ref="EntityStatementSecurityParametersContextLookupStrategy" />
+ <constructor-arg name="f">
+ <bean parent="shibboleth.Functions.Expression" c:expression="#input.getParent()" />
+ </constructor-arg>
+ </bean>
+
+ <bean id="BuildEntityStatement"
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.BuildExplicitRegistrationResponse" scope="prototype"
+ p:identifierGeneratorLookupStrategy-ref="shibboleth.oidc.DefaultIdentifierGenerationStrategy"
+ p:objectMapper-ref="#{'%{idp.oidc.logging.objectMapper:shibboleth.oidc.JSONObjectMapper}'.trim()}">
+ <property name="subjectLookupStrategy">
+ <bean parent="shibboleth.Functions.Expression" p:customObject-ref="shibboleth.ClientIDLookupStrategy"
+ c:expression="#custom.apply(#input.ensureInboundMessageContext()).getValue()" />
+ </property>
+ </bean>
+
+ <bean id="SignEntityStatement" class="net.shibboleth.idp.profile.impl.WebFlowMessageHandlerAdaptor"
+ scope="prototype" c:executionDirection="OUTBOUND ">
+ <constructor-arg name="messageHandler">
+ <bean id="SignEntityStatementHandler"
+ class="net.shibboleth.oidc.security.impl.SignJWTHandler" scope="prototype" p:logName="Entity Statement"
+ p:securityParametersLookupStrategy-ref="EntityStatementSecurityParametersCreationViaMessageContextStrategy"
+ p:typeHeader="entity-statement+jwt">
+ <property name="claimsToSignLookupStrategy">
+ <bean
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.JWTClaimsSetFromEntityStatementLookupFunction" />
+ </property>
+ <property name="jwtUpdateConsumer">
+ <bean
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.EntityStatementUpdateStrategy" />
+ </property>
+ </bean>
+ </constructor-arg>
+ </bean>
+
+ <bean id="FormOutboundMessage"
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.FormExplicitRegistrationResponse"
+ scope="prototype" />
+
+ <bean id="PostResponsePopulateAuditContext" parent="shibboleth.AbstractPopulateAuditContext"
+ p:fieldExtractors="#{getObject('shibboleth.oidc.RegistrationPostResponseAuditExtractors') ?: getObject('shibboleth.oidc.DefaultRegistrationPostResponseAuditExtractors')}" />
+
+</beans>
diff --git a/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/register/register-flow.xml b/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/register/register-flow.xml
new file mode 100644
index 0000000..99d2135
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/register/register-flow.xml
@@ -0,0 +1,60 @@
+<flow xmlns="http://www.springframework.org/schema/webflow"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/webflow http://www.springframework.org/schema/webflow/spring-webflow.xsd"
+ parent="oidc/abstract-register">
+
+ <action-state id="InitializeMandatoryContexts">
+ <evaluate expression="'proceed'" />
+ <transition on="proceed" to="DecodeMessage">
+ <set name="flowScope.transitionAfterDecode" value="'SelectTrustChainResolution'" />
+ </transition>
+ </action-state>
+
+ <decision-state id="SelectTrustChainResolution">
+ <if test="opensamlProfileRequestContext.ensureInboundMessageContext().getMessage().getTrustChain() != null"
+ then="ValidateProvidedTrustChain" else="ResolveTrustChains" />
+ </decision-state>
+
+ <action-state id="ValidateProvidedTrustChain">
+ <evaluate expression="ValidateProvidedTrustChain"/>
+ <evaluate expression="'proceed'" />
+ <transition on="proceed" to="SelectTrustChain" />
+ </action-state>
+
+ <action-state id="ResolveTrustChains">
+ <evaluate expression="ResolveTrustChains" />
+ <evaluate expression="'proceed'" />
+ <transition on="proceed" to="SelectTrustChain" />
+ </action-state>
+
+ <action-state id="SelectTrustChain">
+ <evaluate expression="SelectTrustChain" />
+ <evaluate expression="ResolveTrustMarks" />
+ <evaluate expression="SelectExplicitRegistrationRelyingPartyConfiguration" />
+ <evaluate expression="SelectExplicitRegistrationProfileConfiguration" />
+ <evaluate expression="ValidateExplicitRegistrationProfileConfiguration" />
+ <evaluate expression="PopulateInboundInterceptContext" />
+ <evaluate expression="'proceed'" />
+ <transition on="ReselectTrustChain" to="SelectTrustChain" />
+ <transition on="proceed" to="CheckInboundInterceptContext" />
+ </action-state>
+
+ <action-state id="OutboundContextsAndSecurityParameters">
+ <evaluate expression="CheckRedirectURIs" />
+ <evaluate expression="'proceed'" />
+ <transition on="proceed" to="BuildResponse">
+ <set name="flowScope.transitionAfterBuildResponse" value="'PostBuildResponse'" />
+ </transition>
+ </action-state>
+
+ <action-state id="PostBuildResponse">
+ <evaluate expression="PopulateEntityStatementSignatureSigningParameters" />
+ <evaluate expression="BuildEntityStatement" />
+ <evaluate expression="SignEntityStatement" />
+ <evaluate expression="'proceed'" />
+ <transition on="proceed" to="BuildResponseMessage"/>
+ </action-state>
+
+ <bean-import resource="register-beans.xml" />
+
+</flow>
diff --git a/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/resolve-entity/resolve-entity-beans.xml b/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/resolve-entity/resolve-entity-beans.xml
new file mode 100644
index 0000000..8b85ea4
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/resolve-entity/resolve-entity-beans.xml
@@ -0,0 +1,216 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans" xmlns:c="http://www.springframework.org/schema/c"
+ xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
+ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
+ default-init-method="initialize" default-destroy-method="destroy">
+
+ <bean id="shibboleth.oidc.profileId" class="java.lang.String"
+ c:_0="#{T(net.shibboleth.idp.plugin.oidc.op.oidfed.config.OIDFederationResolveEntityProfileConfiguration).PROFILE_ID}" />
+
+ <bean id="shibboleth.oidc.loggingId" class="java.lang.String" c:_0="%{idp.service.logging.oidfedresolve:OIDFED.ResolveEntity}" />
+
+ <util:constant id="shibboleth.metrics.ProfileCounter"
+ static-field="net.shibboleth.idp.plugin.oidc.op.oidfed.config.DefaultOIDFederationResolveEntityProfileConfiguration.PROFILE_COUNTER" />
+
+ <bean id="DecodeMessage" class="org.opensaml.profile.action.impl.DecodeMessage" scope="prototype">
+ <constructor-arg>
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.decoding.impl.ResolveEntityRequestDecoder" scope="prototype"
+ p:httpServletRequestSupplier-ref="shibboleth.HttpServletRequestSupplier"
+ p:removeIpAddressFromEndpointUri="%{idp.oidc.logging.removeIpAddressFromProtocolMessage:false}"/>
+ <!-- TODO: support custom parsing? p:customRequestParser="#{getObject('%{idp.oidfed.requestParser.ResolveEntityRequest:}'.trim())}"/>-->
+ </constructor-arg>
+ </bean>
+
+ <bean id="InitializeOutboundMessageContext"
+ class="net.shibboleth.idp.plugin.oidc.op.profile.impl.InitializeOutboundResponseMessageContext"
+ scope="prototype" />
+
+ <bean id="shibboleth.ClientIDLookupStrategy" parent="shibboleth.Functions.Expression"
+ c:expression="new com.nimbusds.oauth2.sdk.id.ClientID(#input.getMessage().getSubject())" />
+
+ <bean id="InitializeRelyingPartyContext"
+ class="net.shibboleth.idp.plugin.oidc.op.profile.impl.InitializeRelyingPartyContext" scope="prototype"
+ p:clientIDLookupStrategy-ref="shibboleth.ClientIDLookupStrategy"
+ p:inbound="true" />
+
+ <bean id="shibboleth.oidfed.ResolveEntityResponseMetadataCache" parent="shibboleth.oidc.CacheBuilder">
+ <constructor-arg>
+ <bean p:cacheId="DefaultResolveEntityResponseMetadataCache" parent="shibboleth.oidfed.ResolveEntityResponseMetadataCacheBuilderSpec"
+ p:cleanupTaskInterval="PT30S"/>
+ </constructor-arg>
+ </bean>
+
+ <bean id="shibboleth.oidfed.ResolveEntityResponseMetadataCacheBuilderSpec"
+ class="net.shibboleth.oidc.metadata.cache.impl.DynamicMetadataCacheBuilderSpec"
+ p:minCacheDuration="%{idp.oidfed.resolve-entity.maxRefreshDelay:PT1S}"
+ p:maxCacheDuration="%{idp.oidfed.resolve-entity.maxRefreshDelay:PT30S}">
+ <property name="criteriaToIdentifierStrategy">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultResolveEntityRequestCriteriaToIdentifierStrategy" />
+ </property>
+ <property name="identifierExtractionStrategy">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultResolveEntityResponseIdentifierExtractionStrategy" />
+ </property>
+ <property name="metadataExpirationTimeStrategy">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultResolveEntityResponseContainerExpirationTimeStrategy"/>
+ </property>
+ <property name="metadataFilterStrategy">
+ <bean parent="shibboleth.BiFunctions.Expression" c:expression="#input1"/>
+ </property>
+ <property name="fetchStrategy">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultResolveEntityResponseFetchingStrategy" />
+ </property>
+ </bean>
+
+ <bean id="ValidateRequest" class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.ValidateResolveEntityRequest"
+ scope="prototype"
+ p:localTrustAnchorsCache-ref="#{'%{idp.oidfed.resove-entity.LocalTrustAnchorsMetadataCache:shibboleth.oidfed.LocalTrustAnchorsMetadataCache}'.trim()}" />
+
+ <bean id="LookupCachedResolveEntityResponse"
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.LookupCachedResolveEntityResponse"
+ scope="prototype"
+ p:responseCache-ref="shibboleth.oidfed.ResolveEntityResponseMetadataCache" />
+
+ <bean id="ResolveTrustChains" class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.ResolveTrustChains"
+ scope="prototype"
+ p:trustChainCache-ref="#{'%{idp.oidfed.resolve-entity.TrustChainMetadataCache:shibboleth.oidfed.TrustChainMetadataCache}'.trim()}"
+ p:clientIDLookupStrategy-ref="shibboleth.ClientIDLookupStrategy"
+ p:metadataPolicyMergingStrategy-ref="#{'%{idp.oidfed.resolve-entity.TrustChainMetadataPolicyMergingStrategy:DefaultTrustChainMetadataPolicyMergingStrategy}'.trim()}"
+ p:metadataPolicyEnforcer-ref="#{'%{idp.oidfed.resolve-entity.MetadataPolicyEnforcer:DefaultMetadataPolicyEnforcer}'.trim()}"
+ p:preSelectedTrustChainIdsLookupStrategy="#{getObject('shibboleth.oidfed.PreSelectedTrustChainIDsLookupStrategy') ?: getObject('shibboleth.oidfed.DefaultPreSelectedTrustChainIDsLookupStrategy')}"
+ p:arraysAsSpaceSeparatedList="%{idp.oidfed.policy.arraysAsSpaceSeparatedList:scope}"
+ p:metadataValidationCondition-ref="#{'%{idp.oidfed.MetadataValidationCondition:DefaultMetadataValidationCondition}'.trim()}">
+ <property name="metadataLookupStrategy">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultCombinedMetadataFromTrustChainLookupStrategy"
+ p:objectMapper-ref="shibboleth.oidc.JSONObjectMapper" />
+ </property>
+ </bean>
+
+ <bean id="DefaultMetadataValidationCondition"
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.navigate.DefaultMetadataValidationCondition" />
+
+ <bean id="DefaultMetadataPolicyEnforcer"
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.policy.impl.DefaultFederationMetadataPolicyEnforcer"
+ p:metadataPolicyOperators-ref="#{'%{idp.oidfed.resolve-entity.MetadataPolicyOperatorsy:shibboleth.oidfed.StandardMetadataPolicyOperators}'.trim()}"/>
+
+ <bean id="DefaultTrustChainMetadataPolicyMergingStrategy"
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.navigate.DefaultTrustChainMetadataPolicyMergingStrategy"
+ p:metadataPolicyMergingStrategy-ref="#{'%{idp.oidfed.resolve-entity.MetadataPolicMergingyStrategy:MetadataPolicMergingyStrategy}'.trim()}"
+ p:localMetadataPolicyStrategy-ref="#{'%{idp.oidfed.resolve-entity.LocalMetadataPolicyStrategy:DefaultLocalMetadataPolicyStrategy}'.trim()}"
+ p:objectMapper-ref="shibboleth.oidfed.policy.JSONObjectMapper"/>
+
+ <bean id="MetadataPolicMergingyStrategy"
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.policy.impl.DefaultFederationMetadataPolicyMergingStrategy"
+ p:metadataPolicyOperators-ref="#{'%{idp.oidfed.resolve-entity.MetadataPolicyOperatorsy:shibboleth.oidfed.StandardMetadataPolicyOperators}'.trim()}"/>
+
+ <bean id="DefaultLocalMetadataPolicyStrategy"
+ parent="shibboleth.Functions.Constant">
+ <constructor-arg name="target">
+ <util:map/>
+ </constructor-arg>
+ </bean>
+
+ <bean id="SelectTrustChain" class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.SelectTrustChain"
+ scope="prototype">
+ <property name="activationCondition">
+ <bean parent="shibboleth.Conditions.Expression"
+ c:expression="#input.ensureInboundMessageContext().containsSubcontext(T(net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.RelyingPartyTrustChainContext))" />
+ </property>
+ </bean>
+
+ <bean id="ValidateSelectedTrustChain" class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.ValidateSelectedTrustChain"
+ scope="prototype"
+ p:entityConfigurationCache-ref="shibboleth.oidfed.EntityConfigurationMetadataCache"/>
+
+ <bean id="ResolveTrustMarks" class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.ResolveTrustMarks"
+ scope="prototype"
+ p:trustChainCache-ref="#{'%{idp.oidfed.resolve-entity.TrustChainMetadataCache:shibboleth.oidfed.TrustChainMetadataCache}'.trim()}"
+ p:trustMarkClaimsValidationLookupStrategy="#{getObject('shibboleth.oidfed.TrustMarkClaimsValidationLookupStrategy') ?: getObject('DefaultTrustMarkClaimsValidationLookupStrategy')}"
+ p:delegatedTrustMarkClaimsValidationLookupStrategy="#{getObject('shibboleth.oidfed.DelegatedTrustMarkClaimsValidationLookupStrategy') ?: getObject('DefaultTrustMarkClaimsValidationLookupStrategy')}"
+ p:trustEngine-ref="shibboleth.oidfed.DefaultEntityConfigurationTrustEngine"
+ p:delegationTrustEngine-ref="shibboleth.oidfed.DefaultDelegatedTrustMarkTrustEngine">
+ <property name="trustedTrustMarkIssuersLookupStrategy">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultTrustChainTrustedTrustMarkIssuersLookupStrategy"
+ p:objectMapper-ref="shibboleth.oidc.JSONObjectMapper" />
+ </property>
+ <property name="trustedTrustMarkOwnersLookupStrategy">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultTrustChainTrustedTrustMarkOwnersLookupStrategy"
+ p:objectMapper-ref="shibboleth.oidc.JSONObjectMapper" />
+ </property>
+ </bean>
+
+ <bean id="PopulateEntityStatementSignatureSigningParameters"
+ class="net.shibboleth.oidc.profile.impl.PopulateJWTSignatureSigningParameters" scope="prototype"
+ c:strategy-ref="shibboleth.MessageContextLookup.Outbound"
+ p:securityParametersContextLookupStrategy-ref="EntityStatementSecurityParametersContextLookupStrategy">
+ <property name="configurationLookupStrategy">
+ <bean lazy-init="true"
+ class="net.shibboleth.oidc.profile.config.navigate.JWTSignatureSigningConfigurationLookupFunction" />
+ </property>
+ <property name="signatureSigningParametersResolver">
+ <bean class="net.shibboleth.oidc.security.jose.impl.ClientInformationSignatureSigningParametersResolver">
+ <constructor-arg name="signatureAlgorithmLookupStrategy">
+ <bean parent="shibboleth.Functions.Constant" c:target="" />
+ </constructor-arg>
+ <constructor-arg name="defaultAlgorithmValue" value="%{idp.oidfed.entity.sigalg:RS256}" />
+ </bean>
+ </property>
+ </bean>
+
+ <bean id="EntityStatementSecurityParametersContextLookupStrategy" parent="shibboleth.Functions.Compose"
+ c:g-ref="shibboleth.oidc.ChildLookupOrCreate.JWTSecurityParameters"
+ c:f-ref="shibboleth.ChildLookup.RelyingParty" />
+
+ <bean id="EntityStatementSecurityParametersCreationViaMessageContextStrategy" parent="shibboleth.Functions.Compose">
+ <constructor-arg name="g" ref="EntityStatementSecurityParametersContextLookupStrategy" />
+ <constructor-arg name="f">
+ <bean parent="shibboleth.Functions.Expression" c:expression="#input.getParent()" />
+ </constructor-arg>
+ </bean>
+
+ <bean id="BuildEntityStatement"
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.BuildResolveEntityResponse" scope="prototype"
+ p:identifierGeneratorLookupStrategy-ref="shibboleth.oidc.DefaultIdentifierGenerationStrategy"
+ p:objectMapper-ref="#{'%{idp.oidc.logging.objectMapper:shibboleth.oidc.JSONObjectMapper}'.trim()}">
+ <property name="subjectLookupStrategy">
+ <bean parent="shibboleth.Functions.Expression"
+ c:expression="#input.ensureInboundMessageContext().getMessage().getSubject()" />
+ </property>
+ </bean>
+
+ <bean id="SignEntityStatement" class="net.shibboleth.idp.profile.impl.WebFlowMessageHandlerAdaptor"
+ scope="prototype" c:executionDirection="OUTBOUND ">
+ <constructor-arg name="messageHandler">
+ <bean id="SignEntityStatementHandler"
+ class="net.shibboleth.oidc.security.impl.SignJWTHandler" scope="prototype" p:logName="Entity Statement"
+ p:securityParametersLookupStrategy-ref="EntityStatementSecurityParametersCreationViaMessageContextStrategy"
+ p:typeHeader="entity-statement+jwt">
+ <property name="claimsToSignLookupStrategy">
+ <bean
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.JWTClaimsSetFromEntityStatementLookupFunction" />
+ </property>
+ <property name="jwtUpdateConsumer">
+ <bean
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.EntityStatementUpdateStrategy" />
+ </property>
+ </bean>
+ </constructor-arg>
+ </bean>
+
+ <bean id="FormOutboundMessage"
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.FormOutboundResolveEntityResponse" scope="prototype"
+ p:responseCache-ref="shibboleth.oidfed.ResolveEntityResponseMetadataCache" />
+
+ <bean id="BuildErrorResponseFromEvent"
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.BuildResolveEntityErrorResponseFromEvent" scope="prototype"
+ p:httpServletResponseSupplier-ref="shibboleth.HttpServletResponseSupplier"
+ p:mappedErrors="#{getObject('shibboleth.oidfed.resolve-entity.MappedErrors') ?: getObject('shibboleth.oidc.DefaultResolveEntityApiMappedErrors')}"
+ p:responseCache-ref="shibboleth.oidfed.ResolveEntityResponseMetadataCache">
+ <property name="eventContextLookupStrategy">
+ <bean class="net.shibboleth.idp.profile.context.navigate.WebFlowCurrentEventLookupFunction" />
+ </property>
+ </bean>
+
+</beans>
diff --git a/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/resolve-entity/resolve-entity-flow.xml b/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/resolve-entity/resolve-entity-flow.xml
new file mode 100644
index 0000000..f80f880
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/resolve-entity/resolve-entity-flow.xml
@@ -0,0 +1,77 @@
+<flow xmlns="http://www.springframework.org/schema/webflow"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/webflow http://www.springframework.org/schema/webflow/spring-webflow.xsd"
+ parent="oidc/abstract-api">
+
+ <action-state id="InitializeMandatoryContexts">
+ <evaluate expression="InitializeProfileRequestContext" />
+ <evaluate expression="PopulateMetricContext" />
+ <evaluate expression="FlowStartPopulateAuditContext" />
+ <evaluate expression="InitializeOutboundMessageContext" />
+ <evaluate expression="'proceed'" />
+
+ <transition on="proceed" to="DecodeMessage">
+ <set name="flowScope.transitionAfterDecode" value="'SelectConfiguration'" />
+ </transition>
+ </action-state>
+
+ <action-state id="SelectConfiguration">
+ <evaluate expression="InitializeRelyingPartyContext" />
+ <evaluate expression="SelectRelyingPartyConfiguration" />
+ <evaluate expression="SelectProfileConfiguration" />
+ <evaluate expression="PostLookupPopulateAuditContext" />
+ <evaluate expression="PopulateInboundInterceptContext" />
+ <evaluate expression="'proceed'" />
+
+ <transition on="proceed" to="CheckInboundInterceptContext" />
+ </action-state>
+
+ <decision-state id="CheckInboundInterceptContext">
+ <on-entry>
+ <set name="flowScope.skipOAuth2ClientAuth" value="true" />
+ </on-entry>
+ <if test="opensamlProfileRequestContext.ensureSubcontext(T(net.shibboleth.idp.profile.context.ProfileInterceptorContext)).getAvailableFlows().isEmpty()"
+ then="LookupCachedResponse" else="DoInboundInterceptSubflow" />
+ </decision-state>
+
+ <subflow-state id="DoInboundInterceptSubflow" subflow="intercept">
+ <input name="calledAsSubflow" value="true" />
+ <transition on="proceed" to="LookupCachedResponse" />
+ </subflow-state>
+
+ <action-state id="LookupCachedResponse">
+ <evaluate expression="ValidateRequest" />
+ <evaluate expression="LookupCachedResolveEntityResponse" />
+ <evaluate expression="'proceed'" />
+ <transition on="CachedResolveEntityResponseFound" to="BuildResponseMessage" />
+ <transition on="proceed" to="ResolveTrustChains" />
+ </action-state>
+
+ <action-state id="ResolveTrustChains">
+ <evaluate expression="ResolveTrustChains" />
+ <evaluate expression="'proceed'" />
+ <transition on="proceed" to="SelectTrustChain" />
+ </action-state>
+
+ <action-state id="SelectTrustChain">
+ <evaluate expression="SelectTrustChain" />
+ <evaluate expression="ValidateSelectedTrustChain" />
+ <evaluate expression="ResolveTrustMarks" />
+ <evaluate expression="'proceed'" />
+ <transition on="ReselectTrustChain" to="SelectTrustChain" />
+ <transition on="proceed" to="BuildResponse" />
+ </action-state>
+
+
+ <action-state id="BuildResponse">
+ <evaluate expression="PopulateEntityStatementSignatureSigningParameters" />
+ <evaluate expression="BuildEntityStatement" />
+ <evaluate expression="SignEntityStatement" />
+ <evaluate expression="'proceed'" />
+
+ <transition on="proceed" to="BuildResponseMessage" />
+ </action-state>
+
+ <bean-import resource="resolve-entity-beans.xml" />
+
+</flow>
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/service/relying-party/postconfig.xml b/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/service/relying-party/postconfig.xml
new file mode 100644
index 0000000..b62fda2
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/service/relying-party/postconfig.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:c="http://www.springframework.org/schema/c" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
+ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
+
+ default-init-method="initialize" default-destroy-method="destroy">
+
+ <bean id="AbstractOIDFederationProfile" abstract="true"
+ p:securityConfiguration-ref="shibboleth.oidfed.DefaultSecurityConfiguration" />
+
+ <bean id="OIDFED.Configuration" parent="AbstractOIDFederationProfile" lazy-init="true"
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.config.DefaultOIDFederationEntityConfigurationProfileConfiguration"
+ p:issuer-ref="shibboleth.oidc.issuer"
+ p:authorityHints="%{idp.oidfed.entity.authorityHints:https://example.org}" />
+
+ <bean id="OIDFED.AutomaticRegistration" parent="AbstractOIDFederationProfile" lazy-init="true"
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.config.DefaultOIDFederationAutomaticRegistrationProfileConfiguration"
+ p:mandatoryTrustMarks="%{idp.oidfed.automaticRegistration.mandatoryTrustMarks:}" />
+
+ <bean id="OIDFED.ExplicitRegistration" parent="AbstractOIDFederationProfile" lazy-init="true"
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.config.DefaultOIDFederationExplicitRegistrationProfileConfiguration"
+ p:issuer-ref="shibboleth.oidc.issuer"
+ p:mandatoryTrustMarks="%{idp.oidfed.explicitRegistration.mandatoryTrustMarks:}" />
+
+ <bean id="OIDFED.ResolveEntity" parent="AbstractOIDFederationProfile" lazy-init="true"
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.config.DefaultOIDFederationResolveEntityProfileConfiguration" />
+
+ <bean id="shibboleth.oidfed.SigningConfiguration"
+ parent="shibboleth.oidc.BasicSignatureSigningConfiguration"
+ p:signingCredentials-ref="shibboleth.oidfed.SigningCredentialsFactory">
+ <property name="signatureAlgorithms">
+ <list>
+ <util:constant
+ static-field="net.shibboleth.oidc.jwa.support.SignatureConstants.ALGO_ID_SIGNATURE_RS_256" />
+ <util:constant
+ static-field="net.shibboleth.oidc.jwa.support.SignatureConstants.ALGO_ID_SIGNATURE_RS_384" />
+ <util:constant
+ static-field="net.shibboleth.oidc.jwa.support.SignatureConstants.ALGO_ID_SIGNATURE_RS_512" />
+ <util:constant
+ static-field="net.shibboleth.oidc.jwa.support.SignatureConstants.ALGO_ID_SIGNATURE_ES_256" />
+ <util:constant
+ static-field="net.shibboleth.oidc.jwa.support.SignatureConstants.ALGO_ID_SIGNATURE_ES_384" />
+ <util:constant
+ static-field="net.shibboleth.oidc.jwa.support.SignatureConstants.ALGO_ID_SIGNATURE_ES_512" />
+ <util:constant
+ static-field="net.shibboleth.oidc.jwa.support.SignatureConstants.ALGO_ID_SIGNATURE_PS_256" />
+ <util:constant
+ static-field="net.shibboleth.oidc.jwa.support.SignatureConstants.ALGO_ID_SIGNATURE_PS_384" />
+ <util:constant
+ static-field="net.shibboleth.oidc.jwa.support.SignatureConstants.ALGO_ID_SIGNATURE_PS_512" />
+ </list>
+ </property>
+ </bean>
+
+ <bean id="shibboleth.oidfed.SigningCredentialsFactory"
+ class="net.shibboleth.oidc.profile.config.CredentialsListFactory"
+ c:_0="#{getObject('shibboleth.oidfed.SigningCredentials') ?: getObject('shibboleth.oidc.SigningCredentials')}" />
+
+ <bean id="shibboleth.oidfed.DefaultSecurityConfiguration"
+ class="net.shibboleth.oidc.profile.config.JSONSecurityConfiguration" c:clockSkew="%{idp.policy.clockSkew:PT1M}">
+ <constructor-arg name="idGenerator">
+ <bean
+ class="net.shibboleth.shared.security.IdentifierGenerationStrategy" factory-method="getInstance">
+ <constructor-arg>
+ <util:constant
+ static-field="net.shibboleth.shared.security.IdentifierGenerationStrategy.ProviderType.SECURE" />
+ </constructor-arg>
+ </bean>
+ </constructor-arg>
+ <property name="jwtSignatureSigningConfiguration">
+ <ref bean="#{'%{idp.oidfed.signing.config:shibboleth.oidfed.SigningConfiguration}'.trim()}" />
+ </property>
+ <property name="jwtSignatureValidationConfiguration">
+ <ref bean="#{'%{idp.oidfed.validation.config:shibboleth.oidc.SignatureValidationConfiguration}'.trim()}" />
+ </property>
+ </bean>
+
+ <bean id="RelyingPartyByTrustAnchor" abstract="true" parent="RelyingParty"
+ class="net.shibboleth.idp.plugin.oidc.op.oidfed.config.RelyingPartyConfigurationSupport" factory-method="byTrustAnchor" />
+
+</beans>
diff --git a/idp-oidfed-op-impl/src/main/resources/META-INF/services/net.shibboleth.idp.module.IdPModule b/idp-oidfed-op-impl/src/main/resources/META-INF/services/net.shibboleth.idp.module.IdPModule
new file mode 100644
index 0000000..1a1ebca
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/resources/META-INF/services/net.shibboleth.idp.module.IdPModule
@@ -0,0 +1 @@
+net.shibboleth.idp.plugin.oidc.op.oidfed.OIDFedOPModule
diff --git a/idp-oidfed-op-impl/src/main/resources/META-INF/services/net.shibboleth.idp.plugin.IdPPlugin b/idp-oidfed-op-impl/src/main/resources/META-INF/services/net.shibboleth.idp.plugin.IdPPlugin
new file mode 100644
index 0000000..da48216
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/resources/META-INF/services/net.shibboleth.idp.plugin.IdPPlugin
@@ -0,0 +1,2 @@
+net.shibboleth.idp.plugin.oidc.op.oidfed.OIDFedOPPlugin
+
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/oidfed/conf/attributes/oidc-claim-rules.xml b/idp-oidfed-op-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/oidfed/conf/attributes/oidc-claim-rules.xml
new file mode 100644
index 0000000..9de853b
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/oidfed/conf/attributes/oidc-claim-rules.xml
@@ -0,0 +1,428 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:util="http://www.springframework.org/schema/util"
+ xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:c="http://www.springframework.org/schema/c"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
+ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
+
+ default-init-method="initialize"
+ default-destroy-method="destroy">
+
+ <!-- https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims -->
+
+ <bean parent="shibboleth.TranscodingRuleLoader">
+ <constructor-arg>
+ <list>
+
+ <!-- Typical inetOrgPerson attributes that map to standard claims. -->
+
+ <bean parent="shibboleth.TranscodingProperties">
+ <property name="properties">
+ <props merge="true">
+ <prop key="id">displayName</prop>
+ <prop key="transcoder">OIDCStringTranscoder</prop>
+ <prop key="oidc.name">name</prop>
+ <prop key="displayName.en">Display name</prop>
+ <prop key="displayName.de">Anzeigename</prop>
+ <prop key="displayName.fr">Nom</prop>
+ <prop key="displayName.it">Nome</prop>
+ <prop key="displayName.ja">表示名</prop>
+ <prop key="description.en">The name that should appear in white-pages-like applications for this person.</prop>
+ <prop key="description.de">Anzeigename</prop>
+ <prop key="description.fr">Nom complet d'affichage</prop>
+ <prop key="description.it">Nome</prop>
+ <prop key="description.ja">アプリケーションでの表示に用いられる英字氏名</prop>
+ </props>
+ </property>
+ </bean>
+
+ <bean parent="shibboleth.TranscodingProperties">
+ <property name="properties">
+ <props merge="true">
+ <prop key="id">givenName</prop>
+ <prop key="transcoder">OIDCStringTranscoder</prop>
+ <prop key="oidc.name">given_name</prop>
+ <prop key="displayName.en">Given name</prop>
+ <prop key="displayName.de">Vorname</prop>
+ <prop key="displayName.fr">Prénom</prop>
+ <prop key="displayName.it">Nome</prop>
+ <prop key="displayName.ja">名</prop>
+ <prop key="description.en">Given name of a person</prop>
+ <prop key="description.de">Vorname</prop>
+ <prop key="description.fr">Prénom de l'utilisateur</prop>
+ <prop key="description.it">Nome</prop>
+ <prop key="description.ja">氏名(名)の英語表記</prop>
+ </props>
+ </property>
+ </bean>
+
+ <bean parent="shibboleth.TranscodingProperties">
+ <property name="properties">
+ <props merge="true">
+ <prop key="id">homePhone</prop>
+ <prop key="transcoder">OIDCStringTranscoder</prop>
+ <prop key="oidc.name">phone_number</prop>
+ <prop key="displayName.en">Private phone number</prop>
+ <prop key="displayName.de">Telefon Privat</prop>
+ <prop key="displayName.fr">Teléphone personnel</prop>
+ <prop key="displayName.it">Numero di telefono privato</prop>
+ <prop key="displayName.ja">自宅電話番号</prop>
+ <prop key="description.en">Private phone number</prop>
+ <prop key="description.de">Private Telefonnummer</prop>
+ <prop key="description.fr">Numéro de téléphone de domicile de la personne</prop>
+ <prop key="description.it">Numero di telefono privato</prop>
+ <prop key="description.ja">自宅の電話番号</prop>
+ </props>
+ </property>
+ </bean>
+
+ <bean parent="shibboleth.TranscodingProperties">
+ <property name="properties">
+ <props merge="true">
+ <prop key="id">mail</prop>
+ <prop key="transcoder">OIDCStringTranscoder</prop>
+ <prop key="oidc.name">email</prop>
+ <prop key="displayName.en">E-mail</prop>
+ <prop key="displayName.de">E-Mail</prop>
+ <prop key="displayName.fr">Email</prop>
+ <prop key="displayName.it">E-mail</prop>
+ <prop key="displayName.ja">メールアドレス</prop>
+ <prop key="description.en">E-Mail: Preferred address for e-mail to be sent to this person</prop>
+ <prop key="description.de">E-Mail-Adresse</prop>
+ <prop key="description.de-ch">E-Mail Adresse</prop>
+ <prop key="description.fr">Adresse de courrier électronique</prop>
+ <prop key="description.it">E-Mail: l'indirizzo e-mail preferito dall'utente</prop>
+ <prop key="description.ja">メールアドレス</prop>
+ </props>
+ </property>
+ </bean>
+
+ <bean parent="shibboleth.TranscodingProperties">
+ <property name="properties">
+ <props merge="true">
+ <prop key="id">preferredLanguage</prop>
+ <prop key="transcoder">OIDCStringTranscoder</prop>
+ <prop key="oidc.name">locale</prop>
+ <prop key="displayName.en">Preferred Language</prop>
+ <prop key="displayName.de">Bevorzugte Sprache</prop>
+ <prop key="displayName.fr">Langue préférée</prop>
+ <prop key="displayName.it">Lingua preferita</prop>
+ <prop key="displayName.ja">希望言語</prop>
+ <prop key="description.en">Preferred language: Users preferred language (see RFC1766)</prop>
+ <prop key="description.de">Bevorzugte Sprache (siehe RFC1766)</prop>
+ <prop key="description.fr">Exemple: fr, de, it, en, ... (voir RFC1766)</prop>
+ <prop key="description.it">Lingua preferita: la lingua preferita dall'utente (cfr. RFC1766)</prop>
+ <prop key="description.ja">利用者が希望する言語(RFC1766 を参照)</prop>
+ </props>
+ </property>
+ </bean>
+
+ <bean parent="shibboleth.TranscodingProperties">
+ <property name="properties">
+ <props merge="true">
+ <prop key="id">sn</prop>
+ <prop key="transcoder">OIDCStringTranscoder</prop>
+ <prop key="oidc.name">family_name</prop>
+ <prop key="displayName.en">Surname</prop>
+ <prop key="displayName.de">Nachname</prop>
+ <prop key="displayName.fr">Nom de famille</prop>
+ <prop key="displayName.it">Cognome</prop>
+ <prop key="displayName.ja">姓</prop>
+ <prop key="description.en">Surname or family name</prop>
+ <prop key="description.de">Familienname</prop>
+ <prop key="description.fr">Nom de famille de l'utilisateur.</prop>
+ <prop key="description.it">Cognome dell'utilizzatore</prop>
+ <prop key="description.ja">氏名(姓)の英語表記</prop>
+ </props>
+ </property>
+ </bean>
+
+ <bean parent="shibboleth.TranscodingProperties">
+ <property name="properties">
+ <props merge="true">
+ <prop key="id">telephoneNumber</prop>
+ <prop key="transcoder">OIDCStringTranscoder</prop>
+ <prop key="oidc.name">phone_number</prop>
+ <prop key="displayName.en">Business phone number</prop>
+ <prop key="displayName.de">Telefon Geschäft</prop>
+ <prop key="displayName.fr">Teléphone professionnel</prop>
+ <prop key="displayName.it">Numero di telefono dell'ufficio</prop>
+ <prop key="displayName.ja">所属機関内電話番号</prop>
+ <prop key="description.en">Business phone number: Office or campus phone number</prop>
+ <prop key="description.de">Telefonnummer am Arbeitsplatz</prop>
+ <prop key="description.fr">Teléphone de l'institut, de l'université</prop>
+ <prop key="description.it">Numero di telefono dell'ufficio</prop>
+ <prop key="description.ja">所属機関での利用者の電話番号</prop>
+ </props>
+ </property>
+ </bean>
+
+ <bean parent="shibboleth.TranscodingProperties">
+ <property name="properties">
+ <props merge="true">
+ <prop key="id">uid</prop>
+ <prop key="transcoder">OIDCStringTranscoder</prop>
+ <prop key="oidc.name">preferred_username</prop>
+ <prop key="displayName.en">User ID</prop>
+ <prop key="displayName.de">Benutzer-ID</prop>
+ <prop key="displayName.fr">ID utilisateur</prop>
+ <prop key="displayName.it">ID dell'utente</prop>
+ <prop key="displayName.ja">ユーザID</prop>
+ <prop key="description.en">A unique identifier for a person, mainly used for user identification within the user's home organization.</prop>
+ <prop key="description.de">Eine eindeutige Nummer für eine Person, welche hauptsächlich zur Identifikation innerhalb der Organisation benutzt wird.</prop>
+ <prop key="description.fr">Identifiant de connexion d'une personnes sur les systèmes informatiques.</prop>
+ <prop key="description.it">Identificativo unico della persona, usato per l'identificazione dell'utente all'interno della organizzazione di appartenenza.</prop>
+ <prop key="description.ja">所属機関内で一意の利用者識別子</prop>
+ </props>
+ </property>
+ </bean>
+
+ <!-- eduPerson attributes that map to standard claims. -->
+
+ <bean parent="shibboleth.TranscodingProperties">
+ <property name="properties">
+ <props merge="true">
+ <prop key="id">eduPersonNickname</prop>
+ <prop key="transcoder">OIDCStringTranscoder</prop>
+ <prop key="oidc.name">nickname</prop>
+ <prop key="displayName.en">Nickname</prop>
+ <prop key="displayName.de">Kurzname</prop>
+ <prop key="displayName.de-ch">Übername</prop>
+ <prop key="displayName.fr">Surnom</prop>
+ <prop key="displayName.it">Diminutivo</prop>
+ <prop key="displayName.ja">ニックネーム</prop>
+ <prop key="description.en">Person's nickname, or the informal name by which they are accustomed to be hailed.</prop>
+ <prop key="description.de">Kurzname einer Person, oder üblicher Rufname zur Begrüßung.</prop>
+ <prop key="description.de-ch">Übername einer Person, oder üblicher Rufname zur Begrüssung.</prop>
+ <prop key="description.fr">Nom personnalisable pour un usage informel.</prop>
+ <prop key="description.it">Diminutivo della persona, o soprannome.</prop>
+ <prop key="description.ja">利用者のニックネームもしくは通称</prop>
+ </props>
+ </property>
+ </bean>
+
+ <!-- A subset of the major eduPerson attributes that have no standard claim mapping. -->
+
+ <bean parent="shibboleth.TranscodingProperties">
+ <property name="properties">
+ <props merge="true">
+ <prop key="id">eduPersonAssurance</prop>
+ <prop key="transcoder">OIDCStringTranscoder</prop>
+ <prop key="oidc.name">eduPersonAssurance</prop>
+ <prop key="displayName.en">Assurance level</prop>
+ <prop key="displayName.de">Vertrauensgrad</prop>
+ <prop key="displayName.fr">Niveau de confiance</prop>
+ <prop key="displayName.it">Livello di sicurezza</prop>
+ <prop key="displayName.ja">保証レベル</prop>
+ <prop key="description.en">Set of URIs that assert compliance with specific standards for identity assurance.</prop>
+ <prop key="description.de">URIs die eine gewisse Zusicherung für spezifische Standards des Vertrauens beinhalten</prop>
+ <prop key="description.fr">Un ensemble d'URI qui attestent la conformité selon un standard pour les niveaux d'assurance d'identités</prop>
+ <prop key="description.it">Un insieme di URI che asseriscono l'osservanza dei livelli di sicurezza richiesti</prop>
+ <prop key="description.ja">IDの保証レベルに関して特定の基準に準拠していることを示すURI</prop>
+ </props>
+ </property>
+ </bean>
+
+ <bean parent="shibboleth.TranscodingProperties">
+ <property name="properties">
+ <props merge="true">
+ <prop key="id">eduPersonEntitlement</prop>
+ <prop key="transcoder">OIDCStringTranscoder</prop>
+ <prop key="oidc.name">eduPersonEntitlement</prop>
+ <prop key="displayName.en">Entitlement</prop>
+ <prop key="displayName.de">Berechtigung</prop>
+ <prop key="displayName.fr">Entitlement</prop>
+ <prop key="displayName.it">Prerogativa</prop>
+ <prop key="displayName.ja">資格情報</prop>
+ <prop key="description.en">Member of: URI (either URL or URN) that indicates a set of rights to specific resources based on an agreement across the releavant community</prop>
+ <prop key="description.de">Zeichenkette, die Rechte für spezifische Ressourcen beschreibt</prop>
+ <prop key="description.fr">Membre de: URI (soit une URL ou une URN) décrivant un droit spécific d'accès.</prop>
+ <prop key="description.it">Membro delle seguenti URI (sia URL o URN) che rappresentano diritti specifici d'accesso validi in tutta la communità</prop>
+ <prop key="description.ja">特定のアプリケーションもしくはコミュニティ内の複数リソースへのアクセス権限を持つことを示すURI(URLもしくはURN)</prop>
+ </props>
+ </property>
+ </bean>
+
+ <bean parent="shibboleth.TranscodingProperties">
+ <property name="properties">
+ <props merge="true">
+ <prop key="id">eduPersonPrincipalName</prop>
+ <prop key="transcoder">OIDCScopedStringTranscoder</prop>
+ <prop key="oidc.name">eduPersonPrincipalName</prop>
+ <prop key="displayName.en">Principal name</prop>
+ <prop key="displayName.de">Persönliche ID</prop>
+ <prop key="displayName.fr">Principal Name</prop>
+ <prop key="displayName.it">Principal Name</prop>
+ <prop key="displayName.ja">プリンシパルID</prop>
+ <prop key="description.en">A unique identifier for a person, mainly for inter-institutional user identification.</prop>
+ <prop key="description.de">Eindeutige Benutzeridentifikation</prop>
+ <prop key="description.de-ch">Eindeutige Benützeridentifikation</prop>
+ <prop key="description.fr">L'identifiant unique de l'utilisateur</prop>
+ <prop key="description.it">Un ID personale che identifica chiaramente l'utente in seno alla sua organizzazione</prop>
+ <prop key="description.ja">フェデレーション内で一意かつ永続的な利用者識別子</prop>
+ </props>
+ </property>
+ </bean>
+
+ <bean parent="shibboleth.TranscodingProperties">
+ <property name="properties">
+ <props merge="true">
+ <prop key="id">eduPersonScopedAffiliation</prop>
+ <prop key="transcoder">OIDCScopedStringTranscoder</prop>
+ <prop key="oidc.name">eduPersonScopedAffiliation</prop>
+ <prop key="displayName.en">Scoped affiliation</prop>
+ <prop key="displayName.de">Zugehörigkeit</prop>
+ <prop key="displayName.fr">Affiliation</prop>
+ <prop key="displayName.it">Tipo di membro</prop>
+ <prop key="displayName.ja">スコープ付き職位</prop>
+ <prop key="description.en">Specifies the person's affiliation within a particular security domain</prop>
+ <prop key="description.de">Art der Zugehörigkeit zur Heimatorganisation</prop>
+ <prop key="description.de-ch">Art der Zugehörigkeit zur Heimorganisation</prop>
+ <prop key="description.fr">Type d'affiliation dans l'organisation</prop>
+ <prop key="description.it">Tipo di membro: Tipo di lavoro svolto per l'organizzazione</prop>
+ <prop key="description.ja">セキュリティドメインのスコープが付いた所属機関における職位</prop>
+ </props>
+ </property>
+ </bean>
+
+ <!-- The remainder are standard OIDC claims, which we map based on the actual claim name. -->
+
+ <bean parent="shibboleth.TranscodingProperties">
+ <property name="properties">
+ <props merge="true">
+ <prop key="id">address</prop>
+ <prop key="transcoder">OIDCStringTranscoder</prop>
+ <prop key="oidc.asObject">true</prop>
+ <prop key="oidc.name">address</prop>
+ <prop key="displayName.en">Postal address</prop>
+ </props>
+ </property>
+ </bean>
+
+ <bean parent="shibboleth.TranscodingProperties">
+ <property name="properties">
+ <props merge="true">
+ <prop key="id">birthdate</prop>
+ <prop key="transcoder">OIDCStringTranscoder</prop>
+ <prop key="oidc.name">birthdate</prop>
+ <prop key="displayName.en">Date of birth</prop>
+ </props>
+ </property>
+ </bean>
+
+ <bean parent="shibboleth.TranscodingProperties">
+ <property name="properties">
+ <props merge="true">
+ <prop key="id">email_verified</prop>
+ <prop key="transcoder">OIDCStringTranscoder</prop>
+ <prop key="oidc.name">email_verified</prop>
+ <prop key="oidc.asBoolean">true</prop>
+ <prop key="displayName.en">E-mail verification status</prop>
+ <prop key="description.en">Indicates whether e-mail address has been verified by the issuer</prop>
+ </props>
+ </property>
+ </bean>
+
+ <bean parent="shibboleth.TranscodingProperties">
+ <property name="properties">
+ <props merge="true">
+ <prop key="id">gender</prop>
+ <prop key="transcoder">OIDCStringTranscoder</prop>
+ <prop key="oidc.name">gender</prop>
+ <prop key="displayName.en">Gender</prop>
+ </props>
+ </property>
+ </bean>
+
+ <bean parent="shibboleth.TranscodingProperties">
+ <property name="properties">
+ <props merge="true">
+ <prop key="id">middle_name</prop>
+ <prop key="transcoder">OIDCStringTranscoder</prop>
+ <prop key="oidc.name">middle_name</prop>
+ <prop key="displayName.en">Middle name</prop>
+ </props>
+ </property>
+ </bean>
+
+ <bean parent="shibboleth.TranscodingProperties">
+ <property name="properties">
+ <props merge="true">
+ <prop key="id">phone_number_verified</prop>
+ <prop key="transcoder">OIDCStringTranscoder</prop>
+ <prop key="oidc.name">phone_number_verified</prop>
+ <prop key="oidc.asBoolean">true</prop>
+ <prop key="displayName.en">Phone number verification status</prop>
+ <prop key="description.en">Indicates whether phone number has been verified by the issuer</prop>
+ </props>
+ </property>
+ </bean>
+
+ <bean parent="shibboleth.TranscodingProperties">
+ <property name="properties">
+ <props merge="true">
+ <prop key="id">picture</prop>
+ <prop key="transcoder">OIDCStringTranscoder</prop>
+ <prop key="oidc.name">picture</prop>
+ <prop key="displayName.en">Picture</prop>
+ <prop key="description.en">URL of personal photo</prop>
+ </props>
+ </property>
+ </bean>
+
+ <bean parent="shibboleth.TranscodingProperties">
+ <property name="properties">
+ <props merge="true">
+ <prop key="id">profile</prop>
+ <prop key="transcoder">OIDCStringTranscoder</prop>
+ <prop key="oidc.name">profile</prop>
+ <prop key="displayName.en">Profile page</prop>
+ <prop key="description.en">URL of personal profile page</prop>
+ </props>
+ </property>
+ </bean>
+
+ <bean parent="shibboleth.TranscodingProperties">
+ <property name="properties">
+ <props merge="true">
+ <prop key="id">website</prop>
+ <prop key="transcoder">OIDCStringTranscoder</prop>
+ <prop key="oidc.name">website</prop>
+ <prop key="displayName.en">Web site</prop>
+ <prop key="description.en">URL to personal web site</prop>
+ </props>
+ </property>
+ </bean>
+
+ <bean parent="shibboleth.TranscodingProperties">
+ <property name="properties">
+ <props merge="true">
+ <prop key="id">updated_at</prop>
+ <prop key="transcoder">OIDCStringTranscoder</prop>
+ <prop key="oidc.name">updated_at</prop>
+ <prop key="oidc.asInteger">true</prop>
+ <prop key="displayName.en">Last update of information</prop>
+ </props>
+ </property>
+ </bean>
+
+ <bean parent="shibboleth.TranscodingProperties">
+ <property name="properties">
+ <props merge="true">
+ <prop key="id">zoneinfo</prop>
+ <prop key="transcoder">OIDCStringTranscoder</prop>
+ <prop key="oidc.name">zoneinfo</prop>
+ <prop key="displayName.en">Time zone</prop>
+ </props>
+ </property>
+ </bean>
+
+ </list>
+ </constructor-arg>
+ </bean>
+
+</beans>
diff --git a/idp-oidfed-op-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/oidfed/conf/authn/oidc-credentials.xml b/idp-oidfed-op-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/oidfed/conf/authn/oidc-credentials.xml
new file mode 100644
index 0000000..a8e186b
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/oidfed/conf/authn/oidc-credentials.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:c="http://www.springframework.org/schema/c" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
+ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
+
+ default-init-method="initialize" default-destroy-method="destroy">
+
+ <!--
+ This file contains default OIDC signing credentials. This file should be imported into credentials.xml.
+ -->
+
+ <bean id="shibboleth.oidc.DefaultRSSigningCredential" parent="shibboleth.oidc.JWKCredential"
+ p:resource="%{idp.signing.oidc.rs.key:#{null}}" p:failIfResourceIsNull="false" />
+
+ <bean id="shibboleth.oidc.DefaultESSigningCredential" parent="shibboleth.oidc.JWKCredential"
+ p:resource="%{idp.signing.oidc.es.key:#{null}}" p:failIfResourceIsNull="false" />
+
+ <bean id="shibboleth.oidc.DefaultRSAEncryptionCredential" parent="shibboleth.oidc.JWKCredential"
+ p:resource="%{idp.signing.oidc.rsa.enc.key:#{null}}" p:failIfResourceIsNull="false" />
+
+ <!--
+ Lists ALL of your OP's response signing credentials for the default security configuration.
+ If you define additional signing credentials make sure to include them within this list.
+ -->
+ <util:list id="shibboleth.oidc.SigningCredentials">
+ <ref bean="shibboleth.oidc.DefaultRSSigningCredential" />
+ <ref bean="shibboleth.oidc.DefaultESSigningCredential" />
+ </util:list>
+
+ <!--
+ Lists ALL of your OP's request decryption credentials for the default security configuration.
+ If you define additional decryption credentials make sure to include them within this list.
+ -->
+ <util:list id="shibboleth.oidc.EncryptionCredentials">
+ <ref bean="shibboleth.oidc.DefaultRSAEncryptionCredential" />
+ </util:list>
+
+ <!--
+ If you need to publish a key set different from shibboleth.oidc.EncryptionCredentials, define
+ a list bean named "shibboleth.oidc.EncryptionCredentialsToPublish".
+ -->
+
+ <!-- Example of two active encryption credentials, but only publishing the second before removing from use. -->
+ <!--
+ <util:list id="shibboleth.oidc.EncryptionCredentialsToPublish">
+ <ref bean="shibboleth.oidc.OnlyNewDefaultRSAEncryptionCredential" />
+ </util:list>
+ -->
+
+ <!--
+ If you need to publish a key set different from shibboleth.oidc.SigningCredentials, define
+ a list bean named "shibboleth.oidc.SigningCredentialsToPublish".
+ -->
+
+ <!-- Example of publishing two signing credentials, before active use. -->
+ <!--
+ <util:list id="shibboleth.oidc.SigningCredentialsToPublish">
+ <ref bean="shibboleth.oidc.DefaultRSSigningCredential" />
+ <ref bean="shibboleth.oidc.DefaultESSigningCredential" />
+ <ref bean="shibboleth.oidc.UpcomingDefaultRSSigningCredential" />
+ </util:list>
+ -->
+
+</beans>
diff --git a/idp-oidfed-op-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/oidfed/conf/authn/oidc-rp-client-secret-credential.xml b/idp-oidfed-op-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/oidfed/conf/authn/oidc-rp-client-secret-credential.xml
new file mode 100644
index 0000000..51558fd
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/oidfed/conf/authn/oidc-rp-client-secret-credential.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:c="http://www.springframework.org/schema/c" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
+ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
+
+ default-init-method="initialize" default-destroy-method="destroy">
+
+ <!--
+ This file contains the default credential based on the client_secret, which will be the only used credential in
+ most cases for the RP-Proxy. This file should be imported into credentials.xml.
+ -->
+
+ <bean id="shibboleth.authn.oidc.rp.DefaultCredential" parent="shibboleth.oidc.ClientSecretCredential"
+ p:secret="%{idp.authn.oidc.rp.client.clientSecret:#{null}}"/>
+
+</beans>
diff --git a/idp-oidfed-op-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/oidfed/conf/authn/oidc-rp-config.xml b/idp-oidfed-op-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/oidfed/conf/authn/oidc-rp-config.xml
new file mode 100644
index 0000000..6608675
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/oidfed/conf/authn/oidc-rp-config.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:c="http://www.springframework.org/schema/c" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
+ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
+
+ default-init-method="initialize" default-destroy-method="destroy" default-lazy-init="true">
+
+
+
+</beans>
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/oidfed/conf/authn/oidc-rp-providermetadata-resolvers.xml b/idp-oidfed-op-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/oidfed/conf/authn/oidc-rp-providermetadata-resolvers.xml
new file mode 100644
index 0000000..7d10e4f
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/oidfed/conf/authn/oidc-rp-providermetadata-resolvers.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:c="http://www.springframework.org/schema/c" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
+ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
+
+ default-init-method="initialize" default-destroy-method="destroy">
+
+ <!--
+ The default metadata provider fetches OpenID Provider configuration metadata from the issuers well-known
+ location.
+ -->
+ <util:list id="shibboleth.authn.oidc.rp.ProviderMetadataResolvers">
+ <ref bean="ProviderHTTPResolver" />
+ </util:list>
+
+ <bean id="ProviderHTTPResolver" parent="shibboleth.authn.oidc.rp.OIDCProviderMetadataResolver">
+ <constructor-arg>
+ <bean parent="shibboleth.authn.oidc.rp.CacheBuilder">
+ <constructor-arg>
+ <bean p:cacheId="ProviderHTTPDynamicResolver"
+ parent="shibboleth.authn.oidc.rp.BaseProviderDynamicCacheBuilderSpec"
+ p:minCacheDuration="PT30M"
+ p:maxCacheDuration="PT8H"
+ p:cleanupTaskInterval="PT30M"/>
+ </constructor-arg>
+ </bean>
+ </constructor-arg>
+ </bean>
+
+</beans>
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/oidfed/conf/authn/oidc-rp.properties b/idp-oidfed-op-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/oidfed/conf/authn/oidc-rp.properties
new file mode 100644
index 0000000..d3dae91
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/oidfed/conf/authn/oidc-rp.properties
@@ -0,0 +1,82 @@
+idp.authn.oidc.rp.provider.proxyIssuer=https://issuer.com
+## If discovery is required, these default properties will not be set, you must manage per OP using overrides
+idp.authn.oidc.rp.client.clientId = client_id
+idp.authn.oidc.rp.client.clientSecret= client_secret
+idp.authn.oidc.rp.client.redirecturl.allowedOrigins = https://localhost:8443
+
+## If true and the token was retrieved using TLS with server validation, JWS signature checking will be skipped.
+#idp.authn.oidc.rp.client.idtoken.tlsServerValidationOnly = false
+
+## Should a further lookup to the UserInfo endpoint be made, to retrieve additional claims about the end-user
+#idp.authn.oidc.rp.client.userinfo.enabled = true
+#idp.authn.oidc.rp.client.userinfo.httpRequestMethod = GET
+
+## The HTTP method use to send the authorization request
+#idp.authn.oidc.rp.httpRequestMethod = GET
+## Override the default response_mode for the given response_type
+#idp.authn.oidc.rp.client.responseMode = query
+## Client authentication method.
+#idp.authn.oidc.rp.client.authenticationMethod = client_secret_basic
+#idp.authn.oidc.rp.client.authenticationMethod.jwt.expiryOffset = PT30S
+## Comma seperated list of additional scopes e.g. profile or email. The openid scope is added by default
+#idp.authn.oidc.rp.client.scopes =
+
+#idp.authn.oidc.rp.addDefaultPrincipals = false
+#idp.authn.oidc.rp.supportedPrincipals = \
+# saml2/urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport, \
+# saml2/urn:oasis:names:tc:SAML:2.0:ac:classes:Password, \
+# saml1/urn:oasis:names:tc:SAML:1.0:am:password
+
+## IDToken JWT verification properties
+#idp.authn.oidc.rp.client.idtoken.jwt.verifier.clockSkew = PT60S
+#idp.authn.oidc.rp.client.idtoken.jwt.verifier.authnLifetime = PT60S
+## General JWT verification properties
+#idp.authn.oidc.rp.client.jwt.verifier.clockSkew = PT1M
+
+## Should validation be skipped if the at_hash is not present in the id_token response. Defaults to 'true' as
+## access token at_hash validation is optional in the Authorization Code Flow.
+#idp.authn.oidc.rp.client.tokenresponse.allowMissingAtHash = true
+
+## External controller path. Should not need changing.
+#idp.authn.oidc.rp.externalAuthnPath = /Authn/OIDC/RP
+
+## Bean ID of list of subject c14n flow beans used
+#idp.authn.oidc.rp.c14n.postLoginFlows = shibboleth.authn.oidc.rp.c14n.PostLoginSubjectCanonicalizationFlows
+
+## Inbuilt C14N options for converting a Subject Identifier into a principal name
+idp.authn.oidc.rp.c14n.subjectidentifier.lowercase = false
+idp.authn.oidc.rp.c14n.subjectidentifier.uppercase = false
+idp.authn.oidc.rp.c14n.subjectidentifier.trim = true
+idp.authn.oidc.rp.c14n.subjectidentifier.disabled = false
+
+## Properties to control discovery. Note, there is currently no default discovery implementation
+#idp.authn.oidc.rp.provider.discoveryRequired=false
+#idp.authn.oidc.rp.discoveryURL=http://opdisco.com
+
+### Properties below are common to both RP and OP (if installed).
+
+## The OP's keyset document fetch interval i.e. how long should keys from the OP be cached.
+#idp.oidc.provider.keyfetch.interval = PT30M
+
+## Enable PKCE for the authorization code flow
+#idp.oidc.forcePKCE = false
+#idp.oidc.allowPKCEPlain = false
+
+## Whether to use a request object to send authentication parameters, and if it should be encrypted and or signed.
+#idp.oidc.requestobject.used= false
+#idp.oidc.requestobject.encrypted = false
+#idp.oidc.requestobject.signed = true
+
+## Signing and encryption/decryption keys for request objects, id tokens, and userinfo response
+#idp.signing.oidc.rs.key = %{idp.home}/credentials/idp-signing-rs.jwk
+#idp.signing.oidc.es.key = %{idp.home}/credentials/idp-signing-es.jwk
+#idp.signing.oidc.rsa.enc.key = %{idp.home}/credentials/idp-encryption-rsa.jwk
+
+## Properties to control the authentication flow
+#idp.authn.oidc.rp.order = 1000
+#idp.authn.oidc.rp.nonBrowserSupported = false
+#idp.authn.oidc.rp.passiveAuthenticationSupported = true
+#idp.authn.oidc.rp.forcedAuthenticationSupported = true
+
+
+
diff --git a/idp-oidfed-op-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/oidfed/conf/authn/providermetadata-resolver-system.xml b/idp-oidfed-op-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/oidfed/conf/authn/providermetadata-resolver-system.xml
new file mode 100644
index 0000000..96e7c81
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/oidfed/conf/authn/providermetadata-resolver-system.xml
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:c="http://www.springframework.org/schema/c" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
+ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
+
+ default-init-method="initialize" default-destroy-method="destroy" default-lazy-init="true">
+
+ <!-- Loaded by the postconfig.xml file as global beans -->
+
+ <bean id="shibboleth.authn.oidc.rp.ProviderMetadataProvider" lazy-init="false"
+ class="net.shibboleth.oidc.metadata.ProviderMetadataProviderContainer"
+ p:embeddedResolver-ref="shibboleth.authn.oidc.rp.ChainingProviderMetadataResolver">
+ </bean>
+
+ <bean id="shibboleth.authn.oidc.rp.ChainingProviderMetadataResolver"
+ class="net.shibboleth.oidc.metadata.impl.ChainingProviderMetadataResolver" p:id="InternalEmbeddedChainResolver"
+ p:resolvers="#{getObject('shibboleth.authn.oidc.rp.ProviderMetadataResolvers')}" />
+
+ <!-- abstract beans for the user space config to extend -->
+ <bean id="shibboleth.authn.oidc.rp.OIDCProviderMetadataResolver" abstract="true"
+ class="net.shibboleth.oidc.metadata.impl.OIDCProviderMetadataResolver" />
+
+ <bean id="shibboleth.authn.oidc.rp.DefaultHTTPProviderConfigurationMetadataFetchingStrategy"
+ class="net.shibboleth.oidc.metadata.impl.HTTPProviderConfigurationFetchingStrategy"
+ c:client-ref="shibboleth.InternalHttpClient"
+ c:handler-ref="shibboleth.authn.oidc.rp.DefaultHTTProviderConfigurationMetadataResponseHandler"
+ p:wellKnownLocationCompositionStrategy="#{getObject('shibboleth.authn.oidc.rp.WellKnownLocationCompositionStrategy')}"/>
+
+
+ <bean id="shibboleth.authn.oidc.rp.DefaultHTTProviderConfigurationMetadataResponseHandler"
+ class="net.shibboleth.oidc.metadata.impl.HTTPProviderConfigurationFetchingStrategy.OIDCProviderMetadataResponseHandler" />
+
+ <!-- Cache builder specifications -->
+ <bean id="cacheFactory" class="net.shibboleth.oidc.metadata.cache.impl.MetadataCacheBuilder$Builder"/>
+
+ <bean id="shibboleth.authn.oidc.rp.CacheBuilder" factory-bean="cacheFactory" factory-method="build"
+ abstract="true"/>
+
+
+ <bean class="net.shibboleth.oidc.metadata.cache.impl.BatchMetadataCacheBuilderSpec"
+ id="shibboleth.authn.oidc.rp.BaseProviderBatchCacheBuilderSpec" abstract="true"
+ p:parsingStrategy-ref="shibboleth.authn.oidc.rp.DefaultOIDCProviderMetadataParsingStrategy"
+ p:criteriaToIdentifierStrategy-ref="shibboleth.authn.oidc.rp.DefaultOIDCProviderMetadataCriteriaToIdentifierStrategy"
+ p:sourceMetadataExpiryStrategy-ref="shibboleth.authn.oidc.rp.DefaultODICProviderSourceMetadataExpirationTimeStrategy"
+ p:identifierExtractionStrategy-ref="shibboleth.authn.oidc.rp.DefaultOIDCProviderMetadataIdentifierExtractionStrategy"/>
+
+ <bean class="net.shibboleth.oidc.metadata.cache.impl.DynamicMetadataCacheBuilderSpec"
+ id="shibboleth.authn.oidc.rp.BaseProviderDynamicCacheBuilderSpec" abstract="true"
+ p:fetchStrategy-ref="shibboleth.authn.oidc.rp.DefaultHTTPProviderConfigurationMetadataFetchingStrategy"
+ p:criteriaToIdentifierStrategy-ref="shibboleth.authn.oidc.rp.DefaultOIDCProviderMetadataCriteriaToIdentifierStrategy"
+ p:metadataExpirationTimeStrategy-ref="shibboleth.authn.oidc.rp.DefaultODICProviderMetadataExpirationTimeStrategy"
+ p:identifierExtractionStrategy-ref="shibboleth.authn.oidc.rp.DefaultOIDCProviderMetadataIdentifierExtractionStrategy"
+ />
+
+
+ <!-- Common parents for cache strategy implementations -->
+
+ <bean id="shibboleth.authn.oidc.rp.ProviderConfigurationMetadataFileLoadingStrategy"
+ class="net.shibboleth.oidc.metadata.cache.impl.DefaultFileLoadingStrategy" abstract="true"/>
+
+ <!-- Common implementation strategies for cache implementations -->
+
+ <bean id="shibboleth.authn.oidc.rp.DefaultOIDCProviderMetadataParsingStrategy" scope="prototype"
+ class="net.shibboleth.oidc.metadata.cache.impl.DefaultOIDCProviderMetadataParsingStrategy" />
+
+ <bean id="shibboleth.authn.oidc.rp.DefaultMapParsingStrategy" scope="prototype"
+ class="net.shibboleth.oidc.metadata.cache.impl.DefaultJSONMapParsingStrategy" />
+
+ <bean id="shibboleth.authn.oidc.rp.DefaultODICProviderMetadataExpirationTimeStrategy" scope="prototype"
+ class="net.shibboleth.oidc.metadata.cache.impl.DefaultOIDCProviderMetadataExpirationTimeStrategy"/>
+
+ <bean id="shibboleth.authn.oidc.rp.DefaultODICProviderSourceMetadataExpirationTimeStrategy" scope="prototype"
+ class="net.shibboleth.oidc.metadata.cache.impl.DefaultSourceMetadataExpirationTimeStrategy"
+ c:duration="PT10M" />
+
+ <bean id="shibboleth.authn.oidc.rp.DefaultOIDCProviderMetadataIdentifierExtractionStrategy" scope="prototype"
+ class="net.shibboleth.oidc.metadata.cache.impl.DefaultOIDCProviderMetadataIdentifierExtractionStrategy" />
+
+ <bean id="shibboleth.authn.oidc.rp.DefaultOIDCProviderMetadataCriteriaToIdentifierStrategy" scope="prototype"
+ class="net.shibboleth.oidc.metadata.cache.impl.DefaultOIDCProviderMetadataCriteriaToIdentifierStrategy" />
+
+
+</beans>
diff --git a/idp-oidfed-op-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/oidfed/module.properties b/idp-oidfed-op-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/oidfed/module.properties
new file mode 100644
index 0000000..bafb5e0
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/oidfed/module.properties
@@ -0,0 +1,13 @@
+# Class to Module ID mappings
+net.shibboleth.idp.plugin.oidc.op.oidfed.OIDFedOPModule = idp.oidc.OP.oidfed
+
+# Module Owner
+idp.oidc.OP.oidfed.plugin = net.shibboleth.idp.plugin.oidc.op.oidfed
+
+idp.oidc.OP.oidfed.name = OpenID Federation plugin for OP
+idp.oidc.OP.oidfed.desc = OpenID Federation support for OP
+idp.oidc.OP.oidfed.url = /OIDFED
+
+idp.oidc.OP.oidfed.1.src = /net/shibboleth/idp/plugin/authn/oidc/rp/conf/authn/oidc-rp.properties
+idp.oidc.OP.oidfed.1.dest = conf/authn/oidc-rp.properties
+idp.oidc.OP.oidfed.1.replace = false
diff --git a/idp-oidfed-op-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/oidfed/plugin.properties b/idp-oidfed-op-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/oidfed/plugin.properties
new file mode 100644
index 0000000..4d9c6a4
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/oidfed/plugin.properties
@@ -0,0 +1,6 @@
+plugin.id = net.shibboleth.idp.plugin.oidc.op.oidfed
+# Only used when package manifest is not available
+plugin.version = 1.0.0
+#plugin.license = licence.txt
+
+plugin.modules.required = idp.oidc.OP.6
diff --git a/idp-oidfed-op-impl/src/main/resources/templates/oidc-request-form-post.vm b/idp-oidfed-op-impl/src/main/resources/templates/oidc-request-form-post.vm
new file mode 100644
index 0000000..1ce5112
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/resources/templates/oidc-request-form-post.vm
@@ -0,0 +1,62 @@
+##
+## Velocity Template for OIDC Form Post response mode.
+## cspDigester - Calculates base64-encoded SHA-2 hashes (call apply). Can be null for backward compatibility.
+## cspNonce - Calculates secure nonces (call generateIdentifier). Can be null for backward compatibility.
+##
+##
+#set ($onLoad = "document.forms[0].submit()")
+#if($cspDigester)
+ $response.addHeader("Content-Security-Policy","object-src 'none'; script-src 'none'; script-src-attr 'unsafe-hashes' 'sha256-$cspDigester.apply($onLoad)'")
+#end
+<!DOCTYPE html>
+<html>
+
+<head>
+ <meta charset="utf-8" />
+</head>
+
+<body onload="$onLoad">
+ <noscript>
+ <p>
+ <strong>Note:</strong> Since your browser does not support JavaScript, you must press the Continue button once to proceed.
+ </p>
+ </noscript>
+
+ <form action="${action}" method="post">
+ <div>
+ #if($client_id)
+ <input type="hidden" name="client_id" value="${client_id}" />#end #if($scope)
+
+ <input type="hidden" name="scope" value="${scope}" />#end #if($response_type)
+
+ <input type="hidden" name="response_type" value="${response_type}" />#end #if($response_mode)
+
+ <input type="hidden" name="response_mode" value="${response_mode}" />#end #if($redirect_uri)
+
+ <input type="hidden" name="redirect_uri" value="${redirect_uri}" />#end #if($state)
+
+ <input type="hidden" name="state" value="${state}" />#end #if($prompt)
+
+ <input type="hidden" name="prompt" value="${prompt}" />#end #if($request)
+
+ <input type="hidden" name="request" value="${request}" />#end #if($acr_values)
+
+ <input type="hidden" name="acr_values" value="${acr_values}" />#end #if($claims)
+
+ <input type="hidden" name="claims" value="${claims}" />#end #if($nonce)
+
+ <input type="hidden" name="nonce" value="${nonce}" />#end #if($code_challenge)
+
+ <input type="hidden" name="code_challenge" value="${code_challenge}" />#end #if($code_challenge_method)
+
+ <input type="hidden" name="code_challenge_method" value="${code_challenge_method}" />#end
+ </div>
+ <noscript>
+ <div>
+ <input type="submit" value="Continue" />
+ </div>
+ </noscript>
+ </form>
+</body>
+
+</html>
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/oidfed/TrustChainTestUtil.java b/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/oidfed/TrustChainTestUtil.java
new file mode 100644
index 0000000..a76a63e
--- /dev/null
+++ b/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/oidfed/TrustChainTestUtil.java
@@ -0,0 +1,124 @@
+/*
+ * 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.oidfed;
+
+import java.time.Instant;
+import java.util.Date;
+import java.util.List;
+
+import org.testng.Assert;
+
+import com.nimbusds.jose.JOSEException;
+import com.nimbusds.jose.JOSEObjectType;
+import com.nimbusds.jose.JWSAlgorithm;
+import com.nimbusds.jose.JWSHeader;
+import com.nimbusds.jose.crypto.ECDSASigner;
+import com.nimbusds.jose.crypto.RSASSASigner;
+import com.nimbusds.jose.jwk.JWK;
+import com.nimbusds.jose.jwk.KeyUse;
+import com.nimbusds.jose.jwk.RSAKey;
+import com.nimbusds.jose.jwk.gen.RSAKeyGenerator;
+import com.nimbusds.jwt.JWTClaimsSet;
+import com.nimbusds.jwt.SignedJWT;
+import com.nimbusds.oauth2.sdk.ParseException;
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+/**
+ * Various utility methods for testing trust chains.
+ */
+public class TrustChainTestUtil {
+
+ public static List<EntityStatement> chainWithIntermediate(final EntityStatement leaf, final String anchorId,
+ final String intermediateId) {
+ try {
+ final RSAKey anchorKey = new RSAKeyGenerator(2048)
+ .keyID("mockTrustAnchorKey")
+ .keyUse(KeyUse.SIGNATURE)
+ .generate();
+ final RSAKey intermediateKey = new RSAKeyGenerator(2048)
+ .keyID("mockIntermediateKey")
+ .keyUse(KeyUse.SIGNATURE)
+ .generate();
+ final EntityStatement trustAnchor = trustAnchor(JWSAlgorithm.RS256, anchorKey, anchorId);
+ final EntityStatement intermediateStatement = entityStatement(JWSAlgorithm.RS256, anchorKey,
+ new JWTClaimsSet.Builder()
+ .subject(intermediateId)
+ .issueTime(new Date())
+ .issuer(anchorId)
+ .build());
+ final EntityStatement leafSubordinateStatement = entityStatement(JWSAlgorithm.RS256, intermediateKey,
+ new JWTClaimsSet.Builder(leaf.getClaimsSet().toJWTClaimsSet())
+ .subject(leaf.getEntityID().getValue())
+ .issueTime(new Date())
+ .issuer(intermediateId)
+ .build());
+ return List.of(leaf, leafSubordinateStatement, intermediateStatement, trustAnchor);
+ } catch (final ParseException | JOSEException e) {
+ Assert.fail("Could not construct trust chain", e);
+ }
+ return null;
+ }
+
+ public static EntityStatement trustAnchor(final JWSAlgorithm algorithm, final JWK jwk, final String entityId) {
+ return entityStatement(algorithm, jwk,
+ new JWTClaimsSet.Builder()
+ .subject(entityId)
+ .issueTime(new Date())
+ .issuer(entityId)
+ .build());
+ }
+
+ public static EntityStatement entityStatement(final JWSAlgorithm algorithm, final JWK jwk,
+ final JWTClaimsSet claimsSet) {
+ try {
+ return EntityStatement.parse(signedJwt(algorithm, jwk, "entity-statement+jwt", claimsSet));
+ } catch (final ParseException e) {
+ Assert.fail("Could not construct entity configuration", e);
+ }
+ return null;
+ }
+
+ public static SignedJWT trustMark(final JWSAlgorithm algorithm, final JWK jwk, final String iss, final String sub,
+ final String id, final Instant exp) {
+ final JWTClaimsSet.Builder builder = new JWTClaimsSet.Builder()
+ .subject(sub)
+ .issuer(iss)
+ .claim("id", id)
+ .issueTime(new Date())
+ .expirationTime(exp == null ? null : Date.from(exp));
+ return signedJwt(algorithm, jwk, "trust-mark+jwt", builder.build());
+ }
+
+ public static SignedJWT signedJwt(final JWSAlgorithm algorithm, final JWK jwk, final String type,
+ final JWTClaimsSet claimsSet) {
+ final SignedJWT signedJwt = new SignedJWT(
+ new JWSHeader.Builder(algorithm)
+ .type(new JOSEObjectType(type))
+ .keyID(jwk.getKeyID())
+ .build(),
+ claimsSet);
+ try {
+ if (JWSAlgorithm.Family.RSA.contains(algorithm)) {
+ signedJwt.sign(new RSASSASigner(jwk.toRSAKey()));
+ } else {
+ signedJwt.sign(new ECDSASigner(jwk.toECKey()));
+ }
+ return signedJwt;
+ } catch (final JOSEException e) {
+ Assert.fail("Could not construct signed JWT", e);
+ }
+ return null;
+ }
+}
diff --git a/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/AbstractFederationFlowTest.java b/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/AbstractFederationFlowTest.java
new file mode 100644
index 0000000..a4924d5
--- /dev/null
+++ b/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/AbstractFederationFlowTest.java
@@ -0,0 +1,574 @@
+/*
+ * 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.oidfed;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.argThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.charset.Charset;
+import java.security.KeyPair;
+import java.security.NoSuchAlgorithmException;
+import java.security.interfaces.RSAPublicKey;
+import java.time.Instant;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import javax.annotation.Nonnull;
+
+import org.apache.hc.client5.http.classic.HttpClient;
+import org.apache.hc.core5.http.ClassicHttpRequest;
+import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.apache.hc.core5.http.HttpEntity;
+import org.mockito.ArgumentMatcher;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
+import org.springframework.webflow.executor.FlowExecutionResult;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.nimbusds.jose.JOSEException;
+import com.nimbusds.jose.JWSAlgorithm;
+import com.nimbusds.jose.JWSHeader;
+import com.nimbusds.jose.crypto.RSASSASigner;
+import com.nimbusds.jose.jwk.JWK;
+import com.nimbusds.jose.jwk.JWKSet;
+import com.nimbusds.jose.jwk.RSAKey;
+import com.nimbusds.jwt.JWT;
+import com.nimbusds.jwt.JWTClaimsSet;
+import com.nimbusds.jwt.PlainJWT;
+import com.nimbusds.jwt.SignedJWT;
+import com.nimbusds.oauth2.sdk.ErrorResponse;
+import com.nimbusds.oauth2.sdk.ParseException;
+import com.nimbusds.oauth2.sdk.Response;
+import com.nimbusds.oauth2.sdk.id.Issuer;
+import com.nimbusds.openid.connect.sdk.SubjectType;
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+import com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata;
+import com.nimbusds.openid.connect.sdk.rp.OIDCClientMetadata;
+
+import net.minidev.json.JSONObject;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.TrustChainTestUtil;
+import net.shibboleth.idp.plugin.oidc.op.profile.flow.AbstractOidcFlowTest;
+import net.shibboleth.oidc.security.credential.BasicJWKCredential;
+import net.shibboleth.shared.logic.Constraint;
+
+/**
+ * Abstract unit test for the flows supporting OpenID federation.
+ */
+public class AbstractFederationFlowTest extends AbstractOidcFlowTest {
+
+ final static AtomicInteger clientIndex = new AtomicInteger();
+ final static AtomicInteger intermediateIndex = new AtomicInteger();
+ final String redirectUri = "https://rp.federation.local/cb";
+ final String clientIdPattern = "https://testrp%s.federation.local";
+ final String intermediateIdPattern = "https://intermediate-authority%s.federation.local";
+ final String anchorId = "https://trust-anchor.federation.local";
+ final String anchorFetchEndpoint = anchorId + "/fetch";
+ String issuer = "https://op.example.org";
+
+ JWK rpKey;
+ JWK leafKey;
+ JWK anchorKey;
+ JWK trustedAnchorKey;
+ JWK intermediateKey;
+
+ @Autowired
+ @Qualifier("shibboleth.oidfed.HttpClient")
+ HttpClient federationHttpClient;
+
+ protected AbstractFederationFlowTest(final String flowId) {
+ super(flowId);
+ }
+
+ @BeforeClass
+ public void initKeys() throws NoSuchAlgorithmException {
+ rpKey = initializeNewJwk("RSA", 2048, "mockRpKey");
+ leafKey = initializeNewJwk("RSA", 2048, "mockLeafKey");
+ anchorKey = initializeNewJwk("RSA", 2048, "mockAnchorKey");
+ final BasicJWKCredential localAnchor = loadCredential("/credentials/fed-local-anchor.jwk");
+ trustedAnchorKey = new RSAKey.Builder((RSAPublicKey) localAnchor.getPublicKey())
+ .privateKey(localAnchor.getPrivateKey())
+ .keyID("locallyTrustedAnchorKey")
+ .build();
+ intermediateKey = initializeNewJwk("RSA", 2048, "mockIntermediateKey");
+ }
+
+ protected JWK initializeNewJwk(final String algorithm, final int size, final String kid)
+ throws NoSuchAlgorithmException {
+ if ("RSA".equals(algorithm)) {
+ final KeyPair keyPair = generateNewKeyPair(algorithm, size);
+ return new RSAKey.Builder((RSAPublicKey) keyPair.getPublic())
+ .privateKey(keyPair.getPrivate())
+ .keyID(kid)
+ .build();
+ }
+ throw new NoSuchAlgorithmException(algorithm);
+ }
+
+ protected JWT plainRequestObject(final Map<String,Object> claims) {
+ final JWTClaimsSet.Builder builder = new JWTClaimsSet.Builder();
+ for (final String claim : claims.keySet()) {
+ builder.claim(claim, claims.get(claim));
+ }
+ return new PlainJWT(builder.build());
+ }
+
+ protected JWT signedRequestObject(final Map<String,Object> claims) {
+ return signedRequestObject(claims, rpKey);
+ }
+
+ protected JWT signedRequestObject(final Map<String,Object> claims, final JWK jwk) {
+ final JWTClaimsSet.Builder builder = new JWTClaimsSet.Builder();
+ for (final String claim : claims.keySet()) {
+ builder.claim(claim, claims.get(claim));
+ }
+ try {
+ final SignedJWT jwt =
+ new SignedJWT(new JWSHeader.Builder(JWSAlgorithm.RS256).keyID(jwk.getKeyID()).build(),
+ builder.build());
+ final RSASSASigner signer = new RSASSASigner(jwk.toRSAKey());
+ jwt.sign(signer);
+ return jwt;
+ } catch (JOSEException e) {
+ Assert.fail(e.getMessage(), e);
+ }
+ return null;
+ }
+
+ protected String entityConfigurationUrl(final String entityId) {
+ return entityId + "/.well-known/openid-federation";
+ }
+
+ protected String subordinateStatementUrl(final String fetchEndpoint, final String subject) {
+ return fetchEndpoint + "?sub=" + subject;
+ }
+
+ protected void mapResponse(final String requestUri, final ClassicHttpResponse classicResponse) throws IOException {
+ when(federationHttpClient.executeOpen(any(), argThat(new RequestUriMatcher(requestUri)), any()))
+ .thenReturn(classicResponse);
+ }
+
+ protected ClassicHttpResponse mockResponse(final String contents)
+ throws UnsupportedOperationException, IOException {
+ return mockResponse(200, "application/entity-statement+jwt", contents);
+ }
+
+ protected ClassicHttpResponse mockResponse(final int code, final String contentType, final String contents)
+ throws UnsupportedOperationException, IOException {
+ final ClassicHttpResponse classicResponse = mock(ClassicHttpResponse.class);
+ when(classicResponse.getCode()).thenReturn(code);
+ final HttpEntity responseEntity = mock(HttpEntity.class);
+ when(responseEntity.getContentType()).thenReturn(contentType);
+ when(responseEntity.getContent()).thenReturn(new ByteArrayInputStream(contents.getBytes()));
+ when(classicResponse.getEntity()).thenReturn(responseEntity);
+ return classicResponse;
+ }
+
+ protected String rpEntityConfiguration(final String clientId, final String... authorityHints)
+ throws URISyntaxException {
+ final OIDCClientMetadata metadata = new OIDCClientMetadata();
+ metadata.setRedirectionURI(new URI(redirectUri));
+ metadata.setJWKSet(new JWKSet(rpKey.toPublicJWK()));
+ return rpEntityConfiguration(clientId, metadata, authorityHints);
+ }
+
+ protected String rpEntityConfiguration(final String clientId, final OIDCClientMetadata metadata,
+ final String... authorityHints) throws URISyntaxException {
+ final JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().issuer(clientId).subject(clientId)
+ .issueTime(Date.from(Instant.now()))
+ .expirationTime(Date.from(Instant.now().plusSeconds(300)))
+ .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
+ .claim("metadata", Map.of("openid_relying_party", metadata.toJSONObject()))
+ .claim("authority_hints", authorityHints == null || authorityHints.length == 0 ?
+ new String[] { anchorId } : authorityHints)
+ .build();
+ final EntityStatement rpConfiguration =
+ TrustChainTestUtil.entityStatement(JWSAlgorithm.RS256, leafKey, claimsSet);
+ return rpConfiguration.getSignedStatement().serialize();
+ }
+
+ protected String rpEntityConfigurationUnmatchingKey(final String clientId,
+ final OIDCClientMetadata metadata, final String... authorityHints) throws URISyntaxException {
+ final JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().issuer(clientId).subject(clientId)
+ .issueTime(Date.from(Instant.now()))
+ .expirationTime(Date.from(Instant.now().plusSeconds(300)))
+ .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
+ .claim("metadata", Map.of("openid_relying_party", metadata.toJSONObject()))
+ .claim("authority_hints", authorityHints == null || authorityHints.length == 0 ?
+ new String[] { anchorId } : authorityHints)
+ .build();
+ final EntityStatement rpConfiguration =
+ TrustChainTestUtil.entityStatement(JWSAlgorithm.RS256, anchorKey, claimsSet);
+ return rpConfiguration.getSignedStatement().serialize();
+ }
+
+ protected String opEntityConfiguration(final String issuer, final String... authorityHints)
+ throws URISyntaxException {
+ return opEntityConfiguration(issuer, emptyOpMetadata(issuer), authorityHints);
+ }
+
+ protected String opEntityConfiguration(final String issuer, final OIDCProviderMetadata metadata,
+ final String... authorityHints) throws URISyntaxException {
+ final JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().issuer(issuer).subject(issuer)
+ .issueTime(Date.from(Instant.now()))
+ .expirationTime(Date.from(Instant.now().plusSeconds(300)))
+ .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
+ .claim("metadata", Map.of("openid_provider", metadata.toJSONObject()))
+ .claim("authority_hints", authorityHints == null || authorityHints.length == 0 ?
+ new String[] { anchorId } : authorityHints)
+ .build();
+ final EntityStatement rpConfiguration =
+ TrustChainTestUtil.entityStatement(JWSAlgorithm.RS256, leafKey, claimsSet);
+ return rpConfiguration.getSignedStatement().serialize();
+ }
+
+ protected String entityConfiguration(final String entityId, final Map<String, Object> metadata,
+ final String... authorityHints) {
+ final JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().issuer(entityId).subject(entityId)
+ .issueTime(Date.from(Instant.now()))
+ .expirationTime(Date.from(Instant.now().plusSeconds(300)))
+ .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
+ .claim("metadata", metadata)
+ .claim("authority_hints", authorityHints == null || authorityHints.length == 0 ?
+ new String[] { anchorId } : authorityHints)
+ .build();
+ final EntityStatement configuration =
+ TrustChainTestUtil.entityStatement(JWSAlgorithm.RS256, leafKey, claimsSet);
+ return configuration.getSignedStatement().serialize();
+ }
+
+ protected String trustedAnchorConfiguration() {
+ final String anchorId = "https://trust-anchor.federation.local";
+ final JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().issuer(anchorId).subject(anchorId)
+ .issueTime(Date.from(Instant.now()))
+ .expirationTime(Date.from(Instant.now().plusSeconds(300)))
+ .claim("jwks", new JWKSet(trustedAnchorKey).toJSONObject(true))
+ .claim("metadata", Map.of("federation_entity", Map.of("federation_fetch_endpoint",
+ anchorFetchEndpoint)))
+ .build();
+ final EntityStatement anchorConfiguration =
+ TrustChainTestUtil.entityStatement(JWSAlgorithm.RS256, trustedAnchorKey, claimsSet);
+ return anchorConfiguration.getSignedStatement().serialize();
+ }
+
+ protected String trustedAnchorConfiguration(final Map<String, Object> constraints) {
+ final String anchorId = "https://trust-anchor.federation.local";
+ final JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().issuer(anchorId).subject(anchorId)
+ .issueTime(Date.from(Instant.now()))
+ .expirationTime(Date.from(Instant.now().plusSeconds(300)))
+ .claim("jwks", new JWKSet(trustedAnchorKey).toJSONObject(true))
+ .claim("metadata", Map.of("federation_entity", Map.of("federation_fetch_endpoint",
+ anchorFetchEndpoint)))
+ .claim("constraints", constraints)
+ .build();
+ final EntityStatement anchorConfiguration =
+ TrustChainTestUtil.entityStatement(JWSAlgorithm.RS256, trustedAnchorKey, claimsSet);
+ return anchorConfiguration.getSignedStatement().serialize();
+ }
+
+ protected String intermediateConfiguration(final String intermediateId) {
+ final JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().issuer(intermediateId).subject(intermediateId)
+ .issueTime(Date.from(Instant.now()))
+ .expirationTime(Date.from(Instant.now().plusSeconds(300)))
+ .claim("jwks", new JWKSet(intermediateKey).toJSONObject(true))
+ .claim("metadata", Map.of("federation_entity", Map.of("federation_fetch_endpoint",
+ intermediateId + "/fetch")))
+ .claim("authority_hints", new String[] { anchorId })
+ .build();
+ final EntityStatement anchorConfiguration =
+ TrustChainTestUtil.entityStatement(JWSAlgorithm.RS256, intermediateKey, claimsSet);
+ return anchorConfiguration.getSignedStatement().serialize();
+ }
+
+ protected String subordinateStatement(final String issuer, final Map<String, Object> metadata) {
+ final JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().issuer(anchorId).subject(issuer)
+ .issueTime(Date.from(Instant.now()))
+ .expirationTime(Date.from(Instant.now().plusSeconds(300)))
+ .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
+ .claim("metadata", metadata)
+ .claim("authority_hints", new String[] { anchorId })
+ .build();
+ final EntityStatement rpConfiguration =
+ TrustChainTestUtil.entityStatement(JWSAlgorithm.RS256, trustedAnchorKey, claimsSet);
+ return rpConfiguration.getSignedStatement().serialize();
+ }
+
+ protected String rpSubordinateStatement(final String issuer, final JWK issuerKey, final JWK subjetKey,
+ final String subjectId, final Map<String, Object> rpPolicy, final String... authorityHints) {
+ final JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().issuer(issuer).subject(subjectId)
+ .issueTime(Date.from(Instant.now()))
+ .expirationTime(Date.from(Instant.now().plusSeconds(300)))
+ .claim("jwks", new JWKSet(subjetKey).toJSONObject(true))
+ .claim("metadata", Map.of("openid_relying_party", new OIDCClientMetadata().toJSONObject()))
+ .claim("metadata_policy", rpPolicy)
+ .claim("authority_hints", authorityHints)
+ .build();
+ final EntityStatement rpConfiguration =
+ TrustChainTestUtil.entityStatement(JWSAlgorithm.RS256, issuerKey, claimsSet);
+ return rpConfiguration.getSignedStatement().serialize();
+ }
+
+ protected String subordinateStatement(final String issuer, final JWK issuerKey, final JWK subjetKey,
+ final String subjectId, final Map<String, Object> rpPolicy, final Map<String, Object> constraints,
+ final String... authorityHints) {
+ final JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().issuer(issuer).subject(subjectId)
+ .issueTime(Date.from(Instant.now()))
+ .expirationTime(Date.from(Instant.now().plusSeconds(300)))
+ .claim("jwks", new JWKSet(subjetKey).toJSONObject(true))
+ .claim("metadata", Map.of("openid_relying_party", new OIDCClientMetadata().toJSONObject()))
+ .claim("metadata_policy", rpPolicy)
+ .claim("authority_hints", authorityHints)
+ .claim("constraints", constraints)
+ .build();
+ final EntityStatement rpConfiguration =
+ TrustChainTestUtil.entityStatement(JWSAlgorithm.RS256, issuerKey, claimsSet);
+ return rpConfiguration.getSignedStatement().serialize();
+ }
+
+ protected String uniqueClientId() {
+ return String.format(clientIdPattern, clientIndex.getAndIncrement());
+ }
+
+ protected String uniqueIntermediateId() {
+ return String.format(intermediateIdPattern, intermediateIndex.getAndIncrement());
+ }
+
+ protected void rpConfigureMockHttpClient(final String clientId) {
+ try {
+ mapResponse(entityConfigurationUrl(clientId), mockResponse(rpEntityConfiguration(clientId)));
+ mapResponse(entityConfigurationUrl(anchorId), mockResponse(trustedAnchorConfiguration()));
+ mapResponse(subordinateStatementUrl(anchorFetchEndpoint, clientId),
+ mockResponse(subordinateStatement(clientId, Map.of("openid_relying_party",
+ new OIDCClientMetadata().toJSONObject()))));
+ } catch (UnsupportedOperationException | IOException | URISyntaxException e) {
+ Assert.fail("Could not initialize mock HTTP client", e);
+ }
+ }
+
+ protected void rpConfigureMockHttpClient(final String clientId, final OIDCClientMetadata metadata) {
+ try {
+ mapResponse(entityConfigurationUrl(clientId), mockResponse(rpEntityConfiguration(clientId, metadata)));
+ mapResponse(entityConfigurationUrl(anchorId), mockResponse(trustedAnchorConfiguration()));
+ mapResponse(subordinateStatementUrl(anchorFetchEndpoint, clientId),
+ mockResponse(subordinateStatement(clientId, Map.of("openid_relying_party",
+ new OIDCClientMetadata().toJSONObject()))));
+ } catch (UnsupportedOperationException | IOException | URISyntaxException e) {
+ Assert.fail("Could not initialize mock HTTP client", e);
+ }
+ }
+
+ protected void rpConfigureMockHttpClient(final String clientId, final JSONObject metadata) {
+ try {
+ mapResponse(entityConfigurationUrl(clientId), mockResponse(rpEntityConfiguration(clientId)));
+ mapResponse(entityConfigurationUrl(anchorId), mockResponse(trustedAnchorConfiguration()));
+ mapResponse(subordinateStatementUrl(anchorFetchEndpoint, clientId),
+ mockResponse(subordinateStatement(clientId, Map.of("openid_relying_party", metadata))));
+ } catch (UnsupportedOperationException | IOException | URISyntaxException e) {
+ Assert.fail("Could not initialize mock HTTP client", e);
+ }
+ }
+
+ protected void rpConfigureMockHttpClient(final String clientId, final String rpEntityConfiguration) {
+ try {
+ mapResponse(entityConfigurationUrl(clientId), mockResponse(rpEntityConfiguration));
+ mapResponse(entityConfigurationUrl(anchorId), mockResponse(trustedAnchorConfiguration()));
+ mapResponse(subordinateStatementUrl(anchorFetchEndpoint, clientId),
+ mockResponse(subordinateStatement(clientId, Map.of("openid_relying_party",
+ new OIDCClientMetadata().toJSONObject()))));
+ } catch (UnsupportedOperationException | IOException e) {
+ Assert.fail("Could not initialize mock HTTP client", e);
+ }
+ }
+
+ protected void rpConfigureMockHttpClientWithAnchorConstraints(final String clientId,
+ final Map<String,Object> constraints) {
+ try {
+ mapResponse(entityConfigurationUrl(clientId), mockResponse(rpEntityConfiguration(clientId)));
+ mapResponse(entityConfigurationUrl(anchorId), mockResponse(trustedAnchorConfiguration()));
+ mapResponse(subordinateStatementUrl(anchorFetchEndpoint, clientId),
+ mockResponse(subordinateStatement(anchorId, trustedAnchorKey, leafKey, clientId,
+ Map.of("openid_relying_party", Collections.emptyMap()), constraints)));
+ } catch (UnsupportedOperationException | IOException | URISyntaxException e) {
+ Assert.fail("Could not initialize mock HTTP client", e);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ protected void rpConfigureMockHttpClient(final String clientId, final Map<String, Object> testVector) {
+ final String intermediateId = uniqueIntermediateId();
+ try {
+ final Map<String, Object> vectorMetadata = (Map<String, Object>) testVector.get("metadata");
+ if (vectorMetadata.isEmpty()) {
+ mapResponse(entityConfigurationUrl(clientId), mockResponse(
+ rpEntityConfiguration(clientId, intermediateId)));
+ } else {
+ final Map<String, Object> metadata = new HashMap<>(vectorMetadata);
+ metadata.put("redirect_uris", List.of(redirectUri));
+ metadata.put("jwks", new JWKSet(rpKey.toPublicJWK()).toJSONObject());
+ mapResponse(entityConfigurationUrl(clientId),
+ mockResponse(rpEntityConfiguration(clientId,
+ OIDCClientMetadata.parse(new JSONObject(metadata)), intermediateId)));
+ }
+ mapResponse(entityConfigurationUrl(intermediateId), mockResponse(intermediateConfiguration(intermediateId)));
+ mapResponse(entityConfigurationUrl(anchorId), mockResponse(trustedAnchorConfiguration()));
+ mapResponse(subordinateStatementUrl(anchorFetchEndpoint, intermediateId),
+ mockResponse(rpSubordinateStatement(anchorId, trustedAnchorKey, intermediateKey, intermediateId,
+ Map.of("openid_relying_party", (Map<String, Object>) testVector.get("TA")), anchorId)));
+ mapResponse(subordinateStatementUrl(intermediateId + "/fetch", clientId),
+ mockResponse(rpSubordinateStatement(intermediateId, intermediateKey, rpKey, clientId,
+ Map.of("openid_relying_party", (Map<String, Object>) testVector.get("INT")),
+ intermediateId)));
+ } catch (UnsupportedOperationException | IOException | URISyntaxException | ParseException e) {
+ Assert.fail("Could not initialize mock HTTP client", e);
+ }
+ }
+
+ protected OIDCProviderMetadata emptyOpMetadata(final String issuer) {
+ return new OIDCProviderMetadata(new Issuer(issuer), List.of(SubjectType.PUBLIC),
+ URI.create("https://mock.example.org/jwks"));
+ }
+
+ protected void opConfigureMockHttpClient(final String issuer) {
+ try {
+ mapResponse(entityConfigurationUrl(issuer), mockResponse(opEntityConfiguration(issuer)));
+ mapResponse(entityConfigurationUrl(anchorId), mockResponse(trustedAnchorConfiguration()));
+ mapResponse(subordinateStatementUrl(anchorFetchEndpoint, issuer),
+ mockResponse(subordinateStatement(issuer, Map.of("openid_provider",
+ emptyOpMetadata(issuer).toJSONObject()))));
+ } catch (UnsupportedOperationException | IOException | URISyntaxException e) {
+ Assert.fail("Could not initialize mock HTTP client", e);
+ }
+ }
+
+ protected void opConfigureMockHttpClient(final String issuer, final OIDCProviderMetadata metadata) {
+ try {
+ mapResponse(entityConfigurationUrl(issuer), mockResponse(opEntityConfiguration(issuer, metadata)));
+ mapResponse(entityConfigurationUrl(anchorId), mockResponse(trustedAnchorConfiguration()));
+ mapResponse(subordinateStatementUrl(anchorFetchEndpoint, issuer),
+ mockResponse(subordinateStatement(issuer, Map.of("openid_provider",
+ metadata.toJSONObject()))));
+ } catch (UnsupportedOperationException | IOException | URISyntaxException e) {
+ Assert.fail("Could not initialize mock HTTP client", e);
+ }
+ }
+
+ protected void opConfigureMockHttpClient(final String issuer, final JSONObject metadata) {
+ try {
+ mapResponse(entityConfigurationUrl(issuer), mockResponse(opEntityConfiguration(issuer)));
+ mapResponse(entityConfigurationUrl(anchorId), mockResponse(trustedAnchorConfiguration()));
+ mapResponse(subordinateStatementUrl(anchorFetchEndpoint, issuer),
+ mockResponse(subordinateStatement(issuer, Map.of("openid_provider", metadata))));
+ } catch (UnsupportedOperationException | IOException | URISyntaxException e) {
+ Assert.fail("Could not initialize mock HTTP client", e);
+ }
+ }
+
+ protected void opConfigureMockHttpClient(final String issuer, final String opEntityConfiguration) {
+ try {
+ mapResponse(entityConfigurationUrl(issuer), mockResponse(opEntityConfiguration));
+ mapResponse(entityConfigurationUrl(anchorId), mockResponse(trustedAnchorConfiguration()));
+ mapResponse(subordinateStatementUrl(anchorFetchEndpoint, issuer),
+ mockResponse(subordinateStatement(issuer, Map.of("openid_provider",
+ emptyOpMetadata(issuer).toJSONObject()))));
+ } catch (UnsupportedOperationException | IOException e) {
+ Assert.fail("Could not initialize mock HTTP client", e);
+ }
+ }
+
+ protected void opConfigureMockHttpClientWithAnchorConstraints(final String issuer,
+ final Map<String,Object> constraints) {
+ try {
+ mapResponse(entityConfigurationUrl(issuer), mockResponse(opEntityConfiguration(issuer)));
+ mapResponse(entityConfigurationUrl(anchorId), mockResponse(trustedAnchorConfiguration()));
+ mapResponse(subordinateStatementUrl(anchorFetchEndpoint, issuer),
+ mockResponse(subordinateStatement(anchorId, trustedAnchorKey, leafKey, issuer,
+ Map.of("openid_provider", Collections.emptyMap()), constraints)));
+ } catch (UnsupportedOperationException | IOException | URISyntaxException e) {
+ Assert.fail("Could not initialize mock HTTP client", e);
+ }
+ }
+
+ protected List<Map<String, Object>> loadPolicyTestVectors() throws IOException {
+ final ObjectMapper objectMapper = new ObjectMapper();
+ final Resource file = new ClassPathResource(
+ "/net/shibboleth/idp/oidc/metadata/impl/metadata-policy-test-vectors-2025-02-13.json");
+
+ final Charset utf8 = Charset.forName("UTF-8");
+ assert utf8 != null;
+ try {
+ final List<Map<String, Object>> policies =
+ objectMapper.readValue(file.getContentAsString(utf8),
+ new TypeReference<List<Map<String, Object>>>(){});
+ Assert.assertNotNull(policies);
+ return policies;
+ } catch (final JsonProcessingException e) {
+ throw new IOException("Could not parse JSON from the input", e);
+ }
+ }
+
+ protected ErrorResponse parseErrorResponse(final FlowExecutionResult result, final String message) {
+ final Response response = parseResponse(result);
+ Assert.assertFalse(response.indicatesSuccess(), message);
+ Assert.assertTrue(response instanceof ErrorResponse, message);
+ return (ErrorResponse) response;
+ }
+
+ protected void assertErrorCode(final FlowExecutionResult result, final String errorCode,
+ final String message) {
+ final ErrorResponse errorResponse = parseErrorResponse(result, message);
+ Assert.assertEquals(errorResponse.getErrorObject().getCode(), errorCode, message);
+ }
+
+ protected void assertErrorDescriptionContains(final FlowExecutionResult result, final String errorDescription,
+ final String message) {
+ final ErrorResponse errorResponse = parseErrorResponse(result, message);
+ Assert.assertNotNull(errorResponse.getErrorObject().getDescription(), message);
+ Assert.assertTrue(errorResponse.getErrorObject().getDescription().contains(errorDescription), message);
+ }
+
+ protected class RequestUriMatcher implements ArgumentMatcher<ClassicHttpRequest> {
+
+ @Nonnull private final String uri;
+
+ public RequestUriMatcher(final String value) {
+ uri = Constraint.isNotEmpty(value, "URI value cannot be null");
+ }
+
+ @Override
+ public boolean matches(final ClassicHttpRequest match) {
+ try {
+ return match != null && uri.equals(match.getUri().toString());
+ } catch (URISyntaxException e) {
+ }
+ return false;
+ }
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/AbstractOidcFlowTest.java b/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/AbstractOidcFlowTest.java
new file mode 100644
index 0000000..0740ac8
--- /dev/null
+++ b/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/AbstractOidcFlowTest.java
@@ -0,0 +1,724 @@
+/*
+ * 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.oidfed;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
+import java.security.interfaces.ECPrivateKey;
+import java.security.interfaces.ECPublicKey;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.text.ParseException;
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.Nonnull;
+
+import org.apache.commons.codec.binary.Base64;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.opensaml.storage.StorageService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.webflow.executor.FlowExecutionResult;
+import org.springframework.webflow.test.MockExternalContext;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+
+import com.nimbusds.jose.EncryptionMethod;
+import com.nimbusds.jose.JOSEException;
+import com.nimbusds.jose.JOSEObjectType;
+import com.nimbusds.jose.JWEAlgorithm;
+import com.nimbusds.jose.JWEHeader;
+import com.nimbusds.jose.JWEObject;
+import com.nimbusds.jose.JWSAlgorithm;
+import com.nimbusds.jose.JWSHeader;
+import com.nimbusds.jose.Payload;
+import com.nimbusds.jose.PlainHeader;
+import com.nimbusds.jose.crypto.AESEncrypter;
+import com.nimbusds.jose.crypto.ECDHEncrypter;
+import com.nimbusds.jose.crypto.ECDSASigner;
+import com.nimbusds.jose.crypto.MACSigner;
+import com.nimbusds.jose.crypto.RSAEncrypter;
+import com.nimbusds.jose.crypto.RSASSASigner;
+import com.nimbusds.jose.jwk.Curve;
+import com.nimbusds.jose.jwk.ECKey;
+import com.nimbusds.jose.jwk.JWK;
+import com.nimbusds.jose.jwk.JWKSet;
+import com.nimbusds.jose.jwk.RSAKey;
+import com.nimbusds.jose.jwk.gen.ECKeyGenerator;
+import com.nimbusds.jwt.EncryptedJWT;
+import com.nimbusds.jwt.JWTClaimsSet;
+import com.nimbusds.jwt.PlainJWT;
+import com.nimbusds.jwt.SignedJWT;
+import com.nimbusds.oauth2.sdk.ErrorResponse;
+import com.nimbusds.oauth2.sdk.GrantType;
+import com.nimbusds.oauth2.sdk.Response;
+import com.nimbusds.oauth2.sdk.ResponseType;
+import com.nimbusds.oauth2.sdk.Scope;
+import com.nimbusds.oauth2.sdk.auth.ClientAuthenticationMethod;
+import com.nimbusds.oauth2.sdk.auth.Secret;
+import com.nimbusds.oauth2.sdk.dpop.DPoPProofFactory;
+import com.nimbusds.oauth2.sdk.dpop.DefaultDPoPProofFactory;
+import com.nimbusds.oauth2.sdk.id.ClientID;
+import com.nimbusds.oauth2.sdk.token.AccessToken;
+import com.nimbusds.oauth2.sdk.token.BearerAccessToken;
+import com.nimbusds.openid.connect.sdk.Nonce;
+import com.nimbusds.openid.connect.sdk.claims.ClaimsSet;
+import com.nimbusds.openid.connect.sdk.rp.OIDCClientInformation;
+import com.nimbusds.openid.connect.sdk.rp.OIDCClientMetadata;
+
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import net.shibboleth.idp.plugin.oidc.op.token.support.AccessTokenClaimsSet;
+import net.shibboleth.idp.plugin.oidc.op.token.support.TokenClaimsSet;
+import net.shibboleth.idp.test.flows.AbstractFlowTest;
+import net.shibboleth.oidc.metadata.impl.BaseStorageServiceClientInformationComponent;
+import net.shibboleth.oidc.security.credential.BasicJWKCredential;
+import net.shibboleth.oidc.security.credential.BasicJWKCredentialFactoryBean;
+import net.shibboleth.oidc.security.credential.JWKCredentialSupport;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.security.DataSealer;
+import net.shibboleth.shared.security.DataSealerException;
+import net.shibboleth.shared.servlet.impl.HttpServletRequestResponseContext;
+
+/**
+ * Abstract unit test for the OIDC flows.
+ */
+ at ContextConfiguration(locations = { "classpath*:/META-INF/net.shibboleth.idp/postconfig.xml",})
+ at SuppressWarnings("null")
+public abstract class AbstractOidcFlowTest extends AbstractFlowTest {
+
+ public static final String END_STATE_ID = "CommitResponse";
+
+ protected String flowId;
+
+ protected String endStateId;
+
+ @Autowired
+ @Qualifier("shibboleth.oidc.TokenSealer")
+ private DataSealer dataSealer;
+
+ @Autowired
+ @Qualifier("shibboleth.StorageService")
+ StorageService storageService;
+
+ RSAPrivateKey rsaPrivateKey;
+ RSAPublicKey rsaPublicKey;
+
+ ECKey ecKey;
+
+ protected AbstractOidcFlowTest(final String id) {
+ this(id, END_STATE_ID);
+ }
+
+ protected AbstractOidcFlowTest(final String id, final String endId) {
+ flowId = id;
+ endStateId = endId == null ? END_STATE_ID : endId;
+ }
+
+ /**
+ * Initialize mock request, response, and external context. Overrides to remove authorization header.
+ */
+ @Override
+ @BeforeMethod public void initializeMocks() {
+ overrideEndStateOutput(flowId, endStateId);
+
+ request = new MockHttpServletRequest();
+ response = new MockHttpServletResponse();
+ externalContext = new MockExternalContext();
+ externalContext.setNativeRequest(request);
+ externalContext.setNativeResponse(response);
+ }
+
+ /**
+ * {@link HttpServletRequestResponseContext#loadCurrent(HttpServletRequest, HttpServletResponse)}
+ */
+ @Override
+ @BeforeMethod public void initializeThreadLocals() {
+ HttpServletRequestResponseContext.loadCurrent(request, response);
+ }
+
+ @BeforeClass
+ public void initKeys() throws NoSuchAlgorithmException, JOSEException {
+ final KeyPair keyPair = generateNewKeyPair();
+ rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
+ rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
+ ecKey = initializeECKey(Curve.P_256, "123");
+ }
+
+ protected ECKey initializeECKey(final Curve curve, final String kid) {
+ try {
+ return new ECKeyGenerator(curve).keyID(kid).generate();
+ } catch (final JOSEException e) {
+ Assert.fail();
+ return null;
+ }
+ }
+
+ protected KeyPair generateNewKeyPair() throws NoSuchAlgorithmException {
+ return generateNewKeyPair("RSA", 2048);
+ }
+
+ protected KeyPair generateNewKeyPair(final String algorithm, final int size) throws NoSuchAlgorithmException {
+ final KeyPairGenerator keyGen = KeyPairGenerator.getInstance(algorithm);
+ keyGen.initialize(size);
+ return keyGen.genKeyPair();
+ }
+
+ @Nonnull protected DataSealer getDataSealer() {
+ assert dataSealer != null;
+ return dataSealer;
+ }
+
+ protected Response parseResponse(final FlowExecutionResult result) {
+ assertFlowExecutionOutcome(result.getOutcome(), END_STATE_ID);
+ final ProfileRequestContext prc = retrieveProfileRequestContext(result);
+ Assert.assertNotNull(prc);
+ assert prc != null;
+ Assert.assertNotNull(prc.ensureOutboundMessageContext());
+ final Object responseMessage = prc.ensureOutboundMessageContext().getMessage();
+ Assert.assertNotNull(responseMessage);
+ Assert.assertTrue(responseMessage instanceof Response);
+ return (Response) responseMessage;
+ }
+
+ protected ErrorResponse parseErrorResponse(final FlowExecutionResult result) {
+ final Response response = parseResponse(result);
+ Assert.assertFalse(response.indicatesSuccess());
+ Assert.assertTrue(response instanceof ErrorResponse);
+ return (ErrorResponse) response;
+ }
+
+ protected ErrorResponse parseErrorResponse(final FlowExecutionResult result, final String message) {
+ final Response response = parseResponse(result);
+ Assert.assertFalse(response.indicatesSuccess(), message);
+ Assert.assertTrue(response instanceof ErrorResponse, message);
+ return (ErrorResponse) response;
+ }
+
+ protected <AResponseType extends Response> AResponseType parseSuccessResponse(final FlowExecutionResult result,
+ final Class<AResponseType> clazz) {
+ final Response response = parseResponse(result);
+ if (response.indicatesSuccess()) {
+ Assert.assertTrue(clazz.isInstance(response));
+ return clazz.cast(response);
+ }
+ return null;
+ }
+
+ protected void assertErrorCode(final FlowExecutionResult result, final String errorCode) {
+ final ErrorResponse errorResponse = parseErrorResponse(result);
+ Assert.assertEquals(errorResponse.getErrorObject().getCode(), errorCode);
+ }
+
+ protected void assertErrorCode(final FlowExecutionResult result, final String errorCode,
+ final String message) {
+ final ErrorResponse errorResponse = parseErrorResponse(result, message);
+ Assert.assertEquals(errorResponse.getErrorObject().getCode(), errorCode, message);
+ }
+
+ protected void assertErrorDescriptionContains(final FlowExecutionResult result, final String errorDescription) {
+ assertErrorDescriptionContains(result, errorDescription, null);
+ }
+
+ protected void assertErrorDescriptionContains(final FlowExecutionResult result, final String errorDescription,
+ final String message) {
+ final ErrorResponse errorResponse = parseErrorResponse(result, message);
+ Assert.assertNotNull(errorResponse.getErrorObject().getDescription(), message);
+ Assert.assertTrue(errorResponse.getErrorObject().getDescription().contains(errorDescription), message);
+ }
+
+ protected void setJsonRequest(final String method, final String body) {
+ setRequest(method, body, "application/json");
+ }
+
+ protected void setHttpFormRequest(final String method, final Map<String, String> parameters) {
+ setHttpFormRequest(request, method, parameters);
+ }
+
+ protected static void setHttpFormRequest(final MockHttpServletRequest request, final String method, final Map<String, String> parameters) {
+ setRequest(request, method, "", "application/x-www-form-urlencoded");
+ request.setParameters(parameters);
+ }
+
+ protected void setBasicAuth(final String username, final String password) {
+ request.removeHeader("Authorization");
+ request.addHeader("Authorization",
+ "Basic " + new String(Base64.encodeBase64(new String(username + ":" + password).getBytes())));
+ }
+
+ protected void setRequest(final String method, final String body, final String contentType) {
+ setRequest(request, method, body, contentType);
+ }
+
+ protected static void setRequest(final MockHttpServletRequest request, final String method, final String body, final String contentType) {
+ request.setMethod(method);
+ request.setContentType(contentType);
+ request.setContent(body.getBytes());
+ }
+
+ protected void storeMetadata(final StorageService storageService, final String clientId, final String secret,
+ final Scope scope, final String... redirectUri) throws IOException {
+ storeMetadata(storageService, clientId, secret, scope, null, ClientAuthenticationMethod.CLIENT_SECRET_BASIC,
+ null, null, redirectUri);
+ }
+
+ protected void storeMetadata(final StorageService storageService, final String clientId, final String secret,
+ final Scope scope, final JWSAlgorithm requestObjectSigAlg, final String... redirectUri) throws IOException {
+ storeMetadata(storageService, clientId, secret, scope, null, null, null,
+ ClientAuthenticationMethod.CLIENT_SECRET_BASIC,
+ null, null, false, requestObjectSigAlg, redirectUri);
+ }
+
+ protected void storeMetadata(final StorageService storageService, final String clientId, final String secret,
+ final Scope scope, final JWSAlgorithm requestObjectSigAlg, final PublicKey publicKey,
+ final String... redirectUri) throws IOException {
+ storeMetadata(storageService, clientId, secret, scope, null, null, null,
+ ClientAuthenticationMethod.CLIENT_SECRET_BASIC,
+ null, publicKey, false, requestObjectSigAlg, redirectUri);
+ }
+
+ protected void storeMetadata(final StorageService storageService, final String clientId, final String secret,
+ final Scope scope, final JWSAlgorithm requestObjectSigAlg, final PublicKey publicKey,
+ final JWEAlgorithm requestObjectEncAlg, final EncryptionMethod requestObjectEncMethod,
+ final String... redirectUri) throws IOException {
+ storeMetadata(storageService, clientId, secret, scope, null, null, null,
+ ClientAuthenticationMethod.CLIENT_SECRET_BASIC,
+ null, publicKey, false, requestObjectSigAlg, requestObjectEncAlg, requestObjectEncMethod, redirectUri);
+ }
+
+ protected void storeMetadata(final StorageService storageService, final String clientId, final String secret,
+ final Scope scope, final boolean addResources, final String... redirectUri) throws IOException {
+ storeMetadata(storageService, clientId, secret, scope, null, null, null,
+ ClientAuthenticationMethod.CLIENT_SECRET_BASIC,
+ null, null, addResources, null, redirectUri);
+ }
+
+// Checkstyle: ParameterNumber OFF
+ protected void storeMetadata(final StorageService storageService, final String clientId, final String secret,
+ final Scope scope, final JWSAlgorithm tokenEndpointSigAlg,
+ final ClientAuthenticationMethod tokenEndpointMethod, final String... redirectUri) throws IOException {
+ storeMetadata(storageService, clientId, secret, scope, tokenEndpointSigAlg, tokenEndpointMethod, null, null,
+ redirectUri);
+ }
+
+ protected void storeMetadata(final StorageService storageService, final String clientId, final String secret,
+ final Scope scope, final JWSAlgorithm tokenEndpointSigAlg,
+ final ClientAuthenticationMethod tokenEndpointMethod, final JWSAlgorithm userInfoSigAlg,
+ final String... redirectUri) throws IOException {
+ storeMetadata(storageService, clientId, secret, scope, tokenEndpointSigAlg, tokenEndpointMethod, userInfoSigAlg,
+ null, redirectUri);
+ }
+
+ protected void storeMetadata(final StorageService storageService, final String clientId, final String secret,
+ final Scope scope, final JWSAlgorithm tokenEndpointSigAlg,
+ final ClientAuthenticationMethod tokenEndpointMethod, final JWSAlgorithm userInfoSigAlg,
+ final PublicKey publicKey, final String... redirectUri) throws IOException {
+ storeMetadata(storageService, clientId, secret, scope, tokenEndpointSigAlg, null, null, tokenEndpointMethod,
+ userInfoSigAlg, publicKey, redirectUri);
+ }
+
+ protected void storeMetadata(final StorageService storageService, final String clientId, final String secret,
+ final Scope scope, final JWSAlgorithm tokenEndpointSigAlg, final JWEAlgorithm tokenEncAlg,
+ final EncryptionMethod encMethod, final ClientAuthenticationMethod tokenEndpointMethod,
+ final JWSAlgorithm userInfoSigAlg, final PublicKey publicKey, final String... redirectUri)
+ throws IOException {
+ storeMetadata(storageService, clientId, secret, scope, tokenEndpointSigAlg, tokenEncAlg, encMethod,
+ tokenEndpointMethod, userInfoSigAlg, publicKey, true, null, redirectUri);
+ }
+ protected void storeMetadata(final StorageService storageService, final String clientId, final String secret,
+ final Scope scope, final JWSAlgorithm tokenEndpointSigAlg, final JWEAlgorithm tokenEncAlg,
+ final EncryptionMethod encMethod, final ClientAuthenticationMethod tokenEndpointMethod,
+ final JWSAlgorithm userInfoSigAlg, final PublicKey publicKey,final boolean addResources,
+ final JWSAlgorithm requestObjectSigAlg, final String... redirectUri)
+ throws IOException {
+ storeMetadata(storageService, clientId, secret, scope, tokenEndpointSigAlg, tokenEncAlg, encMethod,
+ tokenEndpointMethod, userInfoSigAlg, publicKey, addResources, requestObjectSigAlg, null, null,
+ redirectUri);
+ }
+
+ protected void storeMetadata(final StorageService storageService, final String clientId, final String secret,
+ final Scope scope, final JWSAlgorithm tokenEndpointSigAlg, final JWEAlgorithm tokenEncAlg,
+ final EncryptionMethod encMethod, final ClientAuthenticationMethod tokenEndpointMethod,
+ final JWSAlgorithm userInfoSigAlg, final PublicKey publicKey,final boolean addResources,
+ final JWSAlgorithm requestObjectSigAlg, final JWEAlgorithm requestObjectEncAlg,
+ final EncryptionMethod requestObjectEncMethod, final String... redirectUri)
+ throws IOException {
+
+ final OIDCClientMetadata metadata = buildMetadataSkeleton();
+ final HashSet<URI> uris = new HashSet<>();
+ if (redirectUri != null) {
+ for (final String uri : redirectUri) {
+ try {
+ uris.add(new URI(uri));
+ } catch (final URISyntaxException e) {
+ throw new IOException(e);
+ }
+ }
+ }
+ metadata.setRedirectionURIs(uris);
+ metadata.setScope(scope);
+ metadata.setTokenEndpointAuthJWSAlg(tokenEndpointSigAlg);
+ metadata.setIDTokenJWEAlg(tokenEncAlg);
+ metadata.setIDTokenJWEEnc(encMethod);
+ metadata.setTokenEndpointAuthMethod(tokenEndpointMethod);
+ metadata.setUserInfoJWSAlg(userInfoSigAlg);
+ metadata.setRequestObjectJWSAlg(requestObjectSigAlg);
+ metadata.setRequestObjectJWEAlg(requestObjectEncAlg);
+ metadata.setRequestObjectJWEEnc(requestObjectEncMethod);
+ if (addResources) {
+ metadata.setCustomField("audience", List.of("https://rp.example.org", "https://rp2.example.org",
+ "https://resource.example.org", "resource.example.org"));
+ }
+ if (publicKey != null) {
+ metadata.setJWKSet(buildJWKSet(publicKey));
+ }
+ storeMetadataObject(storageService, clientId, secret, metadata);
+ }
+
+// Checkstyle: ParameterNumber ON
+
+ protected static void storeMetadataObject(final StorageService storageService, final String clientId, final String secret,
+ final OIDCClientMetadata metadata) throws IOException {
+
+ metadata.setGrantTypes(new HashSet<>(List.of(GrantType.AUTHORIZATION_CODE,
+ GrantType.REFRESH_TOKEN, GrantType.CLIENT_CREDENTIALS)));
+ final OIDCClientInformation information = new OIDCClientInformation(new ClientID(clientId), new Date(),
+ metadata, secret != null ? new Secret(secret) : null);
+ storageService.create(BaseStorageServiceClientInformationComponent.CONTEXT_NAME, clientId,
+ information.toJSONObject().toJSONString(), System.currentTimeMillis() + (60 * 60 * 1000));
+ }
+
+ protected static OIDCClientMetadata buildMetadataSkeleton() {
+ final OIDCClientMetadata metadata = new OIDCClientMetadata();
+ metadata.setGrantTypes(new HashSet<>(List.of(GrantType.AUTHORIZATION_CODE,
+ GrantType.REFRESH_TOKEN, GrantType.CLIENT_CREDENTIALS)));
+ final HashSet<ResponseType> responseTypes = new HashSet<>();
+ responseTypes.add(new ResponseType("code"));
+ // implicit flows
+ responseTypes.add(new ResponseType("id_token"));
+ responseTypes.add(new ResponseType("id_token", "token"));
+ // hybrid flows
+ responseTypes.add(new ResponseType("code", "id_token"));
+ responseTypes.add(new ResponseType("code", "token"));
+ responseTypes.add(new ResponseType("code", "id_token", "token"));
+ metadata.setResponseTypes(responseTypes);
+ return metadata;
+ }
+
+ protected static JWKSet buildJWKSet(final PublicKey... publicKeys) {
+ final List<JWK> keys = new ArrayList<>();
+ for (final PublicKey publicKey : publicKeys) {
+ if (publicKey instanceof RSAPublicKey) {
+ final RSAKey rsaKey = new RSAKey.Builder((RSAPublicKey) publicKey).build();
+ keys.add(rsaKey);
+ } else if (publicKey instanceof ECPublicKey) {
+ final ECPublicKey ecPublicKey = (ECPublicKey) publicKey;
+ final ECKey ecKey = new ECKey.Builder(Curve.forECParameterSpec(ecPublicKey.getParams()),
+ ecPublicKey).build();
+ keys.add(ecKey);
+ } else {
+ Assert.fail();
+ }
+ }
+ return new JWKSet(keys);
+ }
+ protected void removeMetadata(final StorageService storageService, final String clientId) throws IOException {
+ storageService.delete(BaseStorageServiceClientInformationComponent.CONTEXT_NAME, clientId);
+ }
+
+ protected void storeConsent(final StorageService storageService, final String uid, final String clientId,
+ final String... ids) throws IOException {
+ final StringBuilder consented = new StringBuilder("[{\"id\":\"subjectPublic\"}");
+ for (final String id : ids) {
+ consented.append(",{\"id\":\"" + id + "\"}");
+ }
+ storageService.create("intercept/attribute-release", uid + ":" + clientId,
+ consented.append("]").toString(), System.currentTimeMillis() + (60 * 60 * 1000));
+ }
+
+ protected String buildJsonForLegacyToken(final String subject, final String clientId, final Scope scope,
+ final String type, final String... consentedClaims) {
+ final String consentClaims;
+ if (consentedClaims != null && consentedClaims.length > 0) {
+ final String jsonArray = "[\"" + String.join("\",\"", consentedClaims) + "\"]";
+ consentClaims = "\"cnsntd_claims\":" + jsonArray + ",\"cnsntbl_claims\":" + jsonArray + ",";
+ } else {
+ consentClaims = "";
+ }
+ return "{\"sub\":\"" + subject + "\"," + consentClaims +
+ "\"iss\":\"https:\\/\\/op.example.org\"," +
+ "\"clid\":\"" + clientId + "\"," +
+ "\"prncpl\":\"jdoe\"," +
+ "\"type\":\"" + type + "\"," +
+ "\"nonce\":\"j2hzbXZhqkNh8to0\"," +
+ "\"dl_claims_ui\":{}," +
+ "\"auth_time\":" + Instant.now().getEpochSecond() + "," +
+ "\"scope\":\"" + scope.toString() + "\"," +
+ "\"dl_claims\":{}," +
+ "\"redirect_uri\":\"https:\\/\\/example.org\\/cb\"," +
+ "\"exp\":" + Instant.now().plusSeconds(30).getEpochSecond() + "," +
+ "\"iat\":" + Instant.now().getEpochSecond() + "," +
+ "\"jti\":\"" + idGenerator.generateIdentifier() + "\"}";
+ }
+
+ protected static SignedJWT createSecretJWT(final JWTClaimsSet claimsSet, final String clientSecret)
+ throws JOSEException {
+ return createSecretJWT(claimsSet, clientSecret, JWSAlgorithm.HS256);
+ }
+
+ protected static SignedJWT createSecretJWT(final JWTClaimsSet claimsSet, final String clientSecret,
+ final JWSAlgorithm algorithm) {
+ return createSecretJWT(claimsSet, clientSecret, algorithm, null);
+ }
+
+ protected static SignedJWT createSecretJWT(final JWTClaimsSet claimsSet, final String clientSecret,
+ final JWSAlgorithm algorithm, final String type) {
+ final SignedJWT jwt;
+ if (type != null) {
+ jwt = new SignedJWT(new JWSHeader.Builder(algorithm).type(new JOSEObjectType(type)).build(), claimsSet);
+ } else {
+ jwt = new SignedJWT(new JWSHeader(algorithm), claimsSet);
+ }
+ try {
+ final MACSigner signer = new MACSigner(clientSecret);
+ jwt.sign(signer);
+ } catch (final JOSEException e) {
+ return null;
+ }
+ return jwt;
+ }
+
+ protected static SignedJWT createPrivateKeyJWT(final JWTClaimsSet claimsSet, final RSAPrivateKey rsaPrivateKey)
+ throws JOSEException {
+ return createPrivateKeyJWT(claimsSet, rsaPrivateKey, JWSAlgorithm.RS256);
+ }
+
+ protected static SignedJWT createPrivateKeyJWT(final JWTClaimsSet claimsSet, final RSAPrivateKey rsaPrivateKey,
+ final JWSAlgorithm algorithm) throws JOSEException {
+ final SignedJWT jwt = new SignedJWT(new JWSHeader(algorithm), claimsSet);
+ final RSASSASigner signer = new RSASSASigner(rsaPrivateKey);
+ jwt.sign(signer);
+ return jwt;
+ }
+
+ protected static SignedJWT createPrivateKeyJWT(final JWTClaimsSet claimsSet, final ECPrivateKey ecPrivateKey,
+ final JWSAlgorithm algorithm) throws JOSEException {
+ final SignedJWT jwt = new SignedJWT(new JWSHeader(algorithm), claimsSet);
+ final ECDSASigner signer = new ECDSASigner(ecPrivateKey);
+ jwt.sign(signer);
+ return jwt;
+ }
+
+ protected static EncryptedJWT createEncryptedJWT(final String contents, final JWEAlgorithm algorithm,
+ final EncryptionMethod method) throws JOSEException, ParseException {
+ return createEncryptedJWT(contents, algorithm, method, loadEncryptionCredential(), null);
+ }
+
+ protected static EncryptedJWT createEncryptedJWT(final String contents, final JWEAlgorithm algorithm,
+ final EncryptionMethod method, final BasicJWKCredential credential, final String clientSecret)
+ throws JOSEException, ParseException {
+ return createEncryptedJWT(contents, algorithm, method, credential, clientSecret, true);
+ }
+
+ protected static EncryptedJWT createEncryptedJWT(final String contents, final JWEAlgorithm algorithm,
+ final EncryptionMethod method, final BasicJWKCredential credential, final String clientSecret,
+ final boolean setKid) throws JOSEException, ParseException {
+ final JWEObject jweObject = new JWEObject(new JWEHeader.Builder(algorithm, method)
+ .contentType("JWT").keyID(setKid ? credential.getKid() : null).build(),
+ new Payload(contents));
+ final PublicKey publicKey = credential == null ? null : credential.getPublicKey();
+ if (publicKey instanceof RSAPublicKey && JWEAlgorithm.Family.RSA.contains(algorithm)) {
+ jweObject.encrypt(new RSAEncrypter((RSAPublicKey) publicKey));
+ } else if (publicKey instanceof ECPublicKey && JWEAlgorithm.Family.ECDH_ES.contains(algorithm)) {
+ jweObject.encrypt(new ECDHEncrypter((ECPublicKey) publicKey));
+ } else if (clientSecret != null) {
+ try {
+ jweObject.encrypt(new AESEncrypter(JWKCredentialSupport.generateSymmetricKey(
+ clientSecret.getBytes("UTF-8"), algorithm, method)));
+ } catch (UnsupportedEncodingException | JOSEException e) {
+ Assert.fail("Could not encrypt with client secret", e);
+ return null;
+ }
+ } else {
+ Assert.fail("Could not find encrypter for " + algorithm);
+ return null;
+ }
+ return EncryptedJWT.parse(jweObject.serialize());
+ }
+
+ protected static BasicJWKCredential loadEncryptionCredential() {
+ return loadCredential("/credentials/idp-encryption-rsa.jwk");
+ }
+
+ protected static BasicJWKCredential loadRSSigningCredential() {
+ return loadCredential("/credentials/idp-signing-rs.jwk");
+ }
+
+ protected static BasicJWKCredential loadESSigningCredential() {
+ return loadCredential("/credentials/idp-signing-es.jwk");
+ }
+
+ protected static BasicJWKCredential loadES384SigningCredential() {
+ return loadCredential("/credentials/idp-signing-es384.jwk");
+ }
+
+ protected static BasicJWKCredential loadES512SigningCredential() {
+ return loadCredential("/credentials/idp-signing-es521.jwk");
+ }
+
+ protected static BasicJWKCredential loadCredential(final String classPathLocation) {
+ final BasicJWKCredentialFactoryBean factory = new BasicJWKCredentialFactoryBean();
+ factory.setResource(new ClassPathResource(classPathLocation));
+ try {
+ factory.afterPropertiesSet();
+ return factory.getObject();
+ } catch (final Exception e) {
+ Assert.fail();
+ return null;
+ }
+ }
+
+ protected BearerAccessToken buildToken(final String clientId, final String subject, final Scope scope)
+ throws URISyntaxException, NoSuchAlgorithmException, DataSealerException, ComponentInitializationException {
+ return buildToken(clientId, subject, scope, null);
+ }
+
+ protected BearerAccessToken buildToken(final String clientId, final String subject, final Scope scope,
+ final ClaimsSet userInfoDeliverySet)
+ throws URISyntaxException, NoSuchAlgorithmException, DataSealerException, ComponentInitializationException {
+ return buildToken(clientId, subject, scope, userInfoDeliverySet, null, null);
+ }
+
+ protected BearerAccessToken buildToken(final String clientId, final String subject, final Scope scope,
+ final ClaimsSet userInfoDeliverySet, final String id, final String rootId)
+ throws URISyntaxException, NoSuchAlgorithmException, DataSealerException, ComponentInitializationException {
+ final String jti = id == null ? idGenerator.generateIdentifier() : id;
+ final TokenClaimsSet claims = new AccessTokenClaimsSet.Builder()
+ .setJWTID(jti)
+ .setClientID(new ClientID(clientId))
+ .setIssuer("https://op.example.org")
+ .setPrincipal("jdoe")
+ .setSubject(subject)
+ .setIssuedAt(Instant.now())
+ .setExpiresAt(Instant.now().plusSeconds(30))
+ .setAuthenticationTime(Instant.now())
+ .setRedirectURI(new URI("https://example.org/cb"))
+ .setScope(scope)
+ .setDlClaimsUI(userInfoDeliverySet)
+ .setRootTokenIdentifier(rootId)
+ .build();
+ return new BearerAccessToken(claims.serialize(getDataSealer()));
+ }
+
+ protected static SignedJWT buildDPoPProof(final String method, final String uri) {
+ return buildDPoPProof(method, uri, (AccessToken) null);
+ }
+
+ protected static SignedJWT buildDPoPProof(final String method, final String uri, final String nonce) {
+ return buildDPoPProof(method, uri, null, nonce);
+ }
+
+ protected static SignedJWT buildDPoPProof(final String method, final String uri, final AccessToken accessToken) {
+ return buildDPoPProof(defaultDPoPProofKey(), JWSAlgorithm.ES256, method, uri, accessToken, null);
+ }
+
+ protected static SignedJWT buildDPoPProof(final String method, final String uri, final AccessToken accessToken,
+ final String nonce) {
+ return buildDPoPProof(defaultDPoPProofKey(), JWSAlgorithm.ES256, method, uri, accessToken, nonce);
+ }
+
+ protected static SignedJWT buildDPoPProof(final JWK jwk, final JWSAlgorithm alg, final String method,
+ final String uri, final AccessToken accessToken, final String nonceValue) {
+ final Nonce nonce = nonceValue == null ? null : new Nonce(nonceValue);
+ try {
+ DPoPProofFactory proofFactory = new DefaultDPoPProofFactory(jwk, alg);
+ if (accessToken == null) {
+ return proofFactory.createDPoPJWT(method, new URI(uri), null, nonce);
+ } else {
+ return proofFactory.createDPoPJWT(method, new URI(uri), accessToken, nonce);
+ }
+ } catch (JOSEException | URISyntaxException e) {
+ Assert.fail("Could not create DPoP proof", e);
+ }
+ return null;
+ }
+
+ protected static SignedJWT buildDPoPProof(final JWSHeader header, final JWTClaimsSet claimsSet,
+ final ECPrivateKey privateKey) {
+ final SignedJWT signedJWT = new SignedJWT(header, claimsSet);
+ try {
+ final ECDSASigner signer = new ECDSASigner(privateKey);
+ signedJWT.sign(signer);
+ } catch (JOSEException e) {
+ Assert.fail("Could not sign DPoP proof", e);
+ }
+ return signedJWT;
+ }
+
+ protected static PlainJWT buildUnsignedDPoPProof(final JWK jwk, final String method,
+ final String uri, final AccessToken accessToken, final String nonceValue) {
+ final PlainHeader header = new PlainHeader.Builder()
+ .type(new JOSEObjectType("dpop+jwt"))
+ .customParam("jwk", jwk.toJSONString())
+ .build();
+ final JWTClaimsSet claimsSet = new JWTClaimsSet.Builder()
+ .claim("htu", uri.toString())
+ .claim("htm", method)
+ .claim("nonce", nonceValue)
+ .issueTime(new Date())
+ .build();
+ final PlainJWT jwt = new PlainJWT(header, claimsSet);
+ return jwt;
+ }
+
+ protected static ECKey defaultDPoPProofKey() {
+ try {
+ return new ECKeyGenerator(Curve.P_256)
+ .keyID("1")
+ .generate();
+ } catch (JOSEException e) {
+ Assert.fail("Could not initialize DPoP proof key", e);
+ }
+ return null;
+ }
+
+ protected static ECKey excludedDPoPProofKey() {
+ try {
+ return new ECKeyGenerator(Curve.P_384)
+ .keyID("1")
+ .generate();
+ } catch (JOSEException e) {
+ Assert.fail("Could not initialize DPoP proof key", e);
+ }
+ return null;
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/AuthorizeFlowAutomaticRegistrationTest.java b/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/AuthorizeFlowAutomaticRegistrationTest.java
new file mode 100644
index 0000000..7f6ddc7
--- /dev/null
+++ b/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/AuthorizeFlowAutomaticRegistrationTest.java
@@ -0,0 +1,480 @@
+/*
+ * 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.oidfed;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URLEncoder;
+import java.text.ParseException;
+import java.time.Duration;
+import java.time.Instant;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.webflow.executor.FlowExecutionResult;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.nimbusds.jose.jwk.JWKSet;
+import com.nimbusds.jwt.JWT;
+import com.nimbusds.openid.connect.sdk.AuthenticationResponse;
+import com.nimbusds.openid.connect.sdk.AuthenticationSuccessResponse;
+import com.nimbusds.openid.connect.sdk.rp.OIDCClientMetadata;
+
+import net.shibboleth.idp.plugin.oidc.op.profile.flow.AuthorizeFlowTest;
+import net.shibboleth.idp.plugin.oidc.op.profile.logic.DefaultPushedAuthorizationRequestUriSerializationFunction;
+import net.shibboleth.idp.plugin.oidc.op.token.support.AuthorizeCodeClaimsSet;
+import net.shibboleth.shared.collection.Pair;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.security.DataSealerException;
+
+public class AuthorizeFlowAutomaticRegistrationTest extends AbstractFederationFlowTest {
+
+ public AuthorizeFlowAutomaticRegistrationTest() {
+ super(AuthorizeFlowTest.FLOW_ID);
+ }
+
+ @Test
+ public void testWithValidTrustChain_noRequestObject()
+ throws IOException, UnsupportedOperationException, URISyntaxException {
+ final String clientId = uniqueClientId();
+ rpConfigureMockHttpClient(clientId);
+ final FlowExecutionResult result = launchAuthenticationRequest(clientId, "openid profile");
+ Assert.assertEquals(result.getOutcome().getId(), "ErrorView");
+ }
+
+ @Test
+ public void testWithValidTrustChain_plainRequestObject()
+ throws IOException, UnsupportedOperationException, URISyntaxException {
+ final String clientId = uniqueClientId();
+ rpConfigureMockHttpClient(clientId);
+ final FlowExecutionResult result =
+ launchAuthenticationRequest(clientId, "openid profile", plainRequestObject(Map.of(
+ "iss", clientId,
+ "aud", issuer,
+ "exp", Instant.now().plus(Duration.ofMinutes(5)).toEpochMilli(),
+ "jti", UUID.randomUUID(),
+ "response_type", "code",
+ "scope", "openid profile",
+ "redirect_uri", redirectUri)));
+ Assert.assertEquals(result.getOutcome().getId(), "ErrorView");
+ }
+
+ @Test
+ public void testWithValidTrustChain_signedRequestObject()
+ throws IOException, UnsupportedOperationException, URISyntaxException {
+ final String clientId = uniqueClientId();
+ rpConfigureMockHttpClient(clientId);
+ final FlowExecutionResult result =
+ launchAuthenticationRequest(clientId, "openid profile", signedRequestObject(Map.of(
+ "iss", clientId,
+ "client_id", clientId,
+ "aud", issuer,
+ "exp", Instant.now().plus(Duration.ofMinutes(5)).toEpochMilli(),
+ "jti", UUID.randomUUID(),
+ "response_type", "code",
+ "scope", "openid profile",
+ "redirect_uri", redirectUri)));
+ final AuthenticationResponse responseMessage = parseSuccessResponse(result, AuthenticationResponse.class);
+ final AuthenticationSuccessResponse successResponse = responseMessage.toSuccessResponse();
+ Assert.assertEquals(successResponse.getRedirectionURI().toString(), redirectUri);
+ Assert.assertNull(successResponse.getIDToken());
+ Assert.assertNull(successResponse.getAccessToken());
+ Assert.assertNotNull(successResponse.getAuthorizationCode());
+ Assert.assertEquals(unwrapTrustChainFromAuthorizeCode(successResponse), List.of(clientId, anchorId));
+ }
+
+ @Test
+ public void testWithInvalidTrustChain_signedRequestObject_unmatchingRpEntityConfigurationSignature()
+ throws IOException, UnsupportedOperationException, URISyntaxException {
+ final String clientId = uniqueClientId();
+ final OIDCClientMetadata metadata = new OIDCClientMetadata();
+ metadata.setRedirectionURI(new URI(redirectUri));
+ metadata.setJWKSet(new JWKSet(rpKey.toPublicJWK()));
+ rpConfigureMockHttpClient(clientId, rpEntityConfigurationUnmatchingKey(clientId, metadata));
+ final FlowExecutionResult result =
+ launchAuthenticationRequest(clientId, "openid profile", signedRequestObject(Map.of(
+ "iss", clientId,
+ "client_id", clientId,
+ "aud", issuer,
+ "exp", Instant.now().plus(Duration.ofMinutes(5)).toEpochMilli(),
+ "jti", UUID.randomUUID(),
+ "response_type", "code",
+ "scope", "openid profile",
+ "redirect_uri", redirectUri)));
+ Assert.assertEquals(result.getOutcome().getId(), "ErrorView");
+ }
+
+ @Test
+ public void testWithValidTrustChain_signedRequestObject_nonMatchingClientId()
+ throws IOException, UnsupportedOperationException, URISyntaxException {
+ final String clientId = uniqueClientId();
+ rpConfigureMockHttpClient(clientId);
+ final FlowExecutionResult result =
+ launchAuthenticationRequest(clientId + "2", "openid profile", signedRequestObject(Map.of(
+ "iss", clientId,
+ "client_id", clientId,
+ "aud", issuer,
+ "exp", Instant.now().plus(Duration.ofMinutes(5)).toEpochMilli(),
+ "jti", UUID.randomUUID(),
+ "response_type", "code",
+ "scope", "openid profile",
+ "redirect_uri", redirectUri)));
+ Assert.assertEquals(result.getOutcome().getId(), "ErrorView");
+ }
+
+ @Test
+ public void testWithValidTrustChain_signedRequestObject_missingJti()
+ throws IOException, UnsupportedOperationException, URISyntaxException {
+ final String clientId = uniqueClientId();
+ rpConfigureMockHttpClient(clientId);
+ final FlowExecutionResult result =
+ launchAuthenticationRequest(clientId, "openid profile", signedRequestObject(Map.of(
+ "iss", clientId,
+ "client_id", clientId,
+ "aud", issuer,
+ "exp", Instant.now().plus(Duration.ofMinutes(5)).toEpochMilli(),
+ "response_type", "code",
+ "scope", "openid profile",
+ "redirect_uri", redirectUri)));
+ assertErrorCode(result, "invalid_request_object");
+ }
+
+ @Test
+ public void testWithValidTrustChain_signedRequestObject_missingExp()
+ throws IOException, UnsupportedOperationException, URISyntaxException {
+ final String clientId = uniqueClientId();
+ rpConfigureMockHttpClient(clientId);
+ final FlowExecutionResult result =
+ launchAuthenticationRequest(clientId, "openid profile", signedRequestObject(Map.of(
+ "iss", clientId,
+ "client_id", clientId,
+ "aud", issuer,
+ "jti", UUID.randomUUID(),
+ "response_type", "code",
+ "scope", "openid profile",
+ "redirect_uri", redirectUri)));
+ assertErrorCode(result, "invalid_request_object");
+ }
+
+ @Test
+ public void testWithValidTrustChain_signedRequestObject_invalidIss()
+ throws IOException, UnsupportedOperationException, URISyntaxException {
+ final String clientId = uniqueClientId();
+ rpConfigureMockHttpClient(clientId);
+ final FlowExecutionResult result =
+ launchAuthenticationRequest(clientId, "openid profile", signedRequestObject(Map.of(
+ "iss", clientId + "2",
+ "client_id", clientId,
+ "aud", issuer,
+ "exp", Instant.now().plus(Duration.ofMinutes(5)).toEpochMilli(),
+ "jti", UUID.randomUUID(),
+ "response_type", "code",
+ "scope", "openid profile",
+ "redirect_uri", redirectUri)));
+ assertErrorCode(result, "invalid_request_object");
+ }
+
+ @Test
+ public void testWithValidTrustChain_signedRequestObject_missingIss()
+ throws IOException, UnsupportedOperationException, URISyntaxException {
+ final String clientId = uniqueClientId();
+ rpConfigureMockHttpClient(clientId);
+ final FlowExecutionResult result =
+ launchAuthenticationRequest(clientId, "openid profile", signedRequestObject(Map.of(
+ "client_id", clientId,
+ "aud", issuer,
+ "exp", Instant.now().plus(Duration.ofMinutes(5)).toEpochMilli(),
+ "jti", UUID.randomUUID(),
+ "response_type", "code",
+ "scope", "openid profile",
+ "redirect_uri", redirectUri)));
+ assertErrorCode(result, "invalid_request_object");
+ }
+
+ @Test
+ public void testWithValidTrustChain_signedRequestObject_invalidClientId()
+ throws IOException, UnsupportedOperationException, URISyntaxException {
+ final String clientId = uniqueClientId();
+ rpConfigureMockHttpClient(clientId);
+ final FlowExecutionResult result =
+ launchAuthenticationRequest(clientId, "openid profile", signedRequestObject(Map.of(
+ "iss", clientId,
+ "client_id", clientId + "2",
+ "aud", issuer,
+ "exp", Instant.now().plus(Duration.ofMinutes(5)).toEpochMilli(),
+ "jti", UUID.randomUUID(),
+ "response_type", "code",
+ "scope", "openid profile",
+ "redirect_uri", redirectUri)));
+ Assert.assertEquals(result.getOutcome().getId(), "ErrorView");
+ }
+
+ @Test
+ public void testWithValidTrustChain_signedRequestObject_missingClientId()
+ throws IOException, UnsupportedOperationException, URISyntaxException {
+ final String clientId = uniqueClientId();
+ rpConfigureMockHttpClient(clientId);
+ final FlowExecutionResult result =
+ launchAuthenticationRequest(clientId, "openid profile", signedRequestObject(Map.of(
+ "iss", clientId,
+ "aud", issuer,
+ "exp", Instant.now().plus(Duration.ofMinutes(5)).toEpochMilli(),
+ "jti", UUID.randomUUID(),
+ "response_type", "code",
+ "scope", "openid profile",
+ "redirect_uri", redirectUri)));
+ Assert.assertEquals(result.getOutcome().getId(), "ErrorView");
+ }
+
+ @Test
+ public void testWithValidTrustChain_signedRequestObject_containsForbiddenSub()
+ throws IOException, UnsupportedOperationException, URISyntaxException {
+ final String clientId = uniqueClientId();
+ rpConfigureMockHttpClient(clientId);
+ final FlowExecutionResult result =
+ launchAuthenticationRequest(clientId, "openid profile", signedRequestObject(Map.of(
+ "iss", clientId,
+ "client_id", clientId,
+ "sub", "mockValue",
+ "aud", issuer,
+ "exp", Instant.now().plus(Duration.ofMinutes(5)).toEpochMilli(),
+ "jti", UUID.randomUUID(),
+ "response_type", "code",
+ "scope", "openid profile",
+ "redirect_uri", redirectUri)));
+ assertErrorCode(result, "invalid_request_object");
+ }
+
+ @Test
+ public void testWithValidTrustChain_signedRequestObject_containsAdditionalAudience()
+ throws IOException, UnsupportedOperationException, URISyntaxException {
+ final String clientId = uniqueClientId();
+ rpConfigureMockHttpClient(clientId);
+ final FlowExecutionResult result =
+ launchAuthenticationRequest(clientId, "openid profile", signedRequestObject(Map.of(
+ "iss", clientId,
+ "client_id", clientId,
+ "aud", List.of(issuer, "https://another.example.org"),
+ "exp", Instant.now().plus(Duration.ofMinutes(5)).toEpochMilli(),
+ "jti", UUID.randomUUID(),
+ "response_type", "code",
+ "scope", "openid profile",
+ "redirect_uri", redirectUri)));
+ assertErrorCode(result, "invalid_request_object");
+ }
+
+ @Test
+ public void testWithValidTrustChain_leafKeySignedRequestObject()
+ throws IOException, UnsupportedOperationException, URISyntaxException {
+ final String clientId = uniqueClientId();
+ rpConfigureMockHttpClient(clientId);
+ final FlowExecutionResult result =
+ launchAuthenticationRequest(clientId, "openid profile", signedRequestObject(Map.of(
+ "iss", clientId,
+ "aud", issuer,
+ "response_type", "code",
+ "scope", "openid profile",
+ "redirect_uri", redirectUri), leafKey));
+ Assert.assertEquals(result.getOutcome().getId(), "ErrorView");
+ }
+
+ @Test
+ public void testWithPar_unresolvableTrustChain()
+ throws Exception {
+ final String clientId = uniqueClientId();
+ rpConfigureMockHttpClient(clientId);
+ final URI uri = createParGeneratedRequestUri(Map.of(
+ "client_id", clientId,
+ "response_type", "code",
+ "scope", "openid profile",
+ "redirect_uri", redirectUri), List.of(clientId, anchorId + "/notExisting"));
+ final FlowExecutionResult result = launchAuthenticationRequest(clientId, "openid profile", uri);
+ Assert.assertEquals(result.getOutcome().getId(), "ErrorView");
+ }
+
+ @Test
+ public void testWithInvalidTrustChain_entityTypeConstraint_signedRequestObject()
+ throws IOException, UnsupportedOperationException, URISyntaxException {
+ final String clientId = uniqueClientId();
+ rpConfigureMockHttpClientWithAnchorConstraints(clientId, Map.of("allowed_entity_types", Collections.emptyList()));
+ final FlowExecutionResult result =
+ launchAuthenticationRequest(clientId, "openid profile", signedRequestObject(Map.of(
+ "iss", clientId,
+ "client_id", clientId,
+ "aud", issuer,
+ "exp", Instant.now().plus(Duration.ofMinutes(5)).toEpochMilli(),
+ "jti", UUID.randomUUID(),
+ "response_type", "code",
+ "scope", "openid profile",
+ "redirect_uri", redirectUri)));
+ Assert.assertEquals(result.getOutcome().getId(), "ErrorView");
+ }
+
+ @Test
+ public void testWithInvalidTrustChain_namingConstraint_signedRequestObject()
+ throws IOException, UnsupportedOperationException, URISyntaxException {
+ final String clientId = uniqueClientId();
+ rpConfigureMockHttpClientWithAnchorConstraints(clientId, Map.of("naming_constraints",
+ Map.of("permitted", List.of(".wrongfederation.local"))));
+ final FlowExecutionResult result =
+ launchAuthenticationRequest(clientId, "openid profile", signedRequestObject(Map.of(
+ "iss", clientId,
+ "client_id", clientId,
+ "aud", issuer,
+ "exp", Instant.now().plus(Duration.ofMinutes(5)).toEpochMilli(),
+ "jti", UUID.randomUUID(),
+ "response_type", "code",
+ "scope", "openid profile",
+ "redirect_uri", redirectUri)));
+ Assert.assertEquals(result.getOutcome().getId(), "ErrorView");
+ }
+
+ @Test
+ public void testWithValidTrustChain_withConstraints_signedRequestObject()
+ throws IOException, UnsupportedOperationException, URISyntaxException {
+ final String clientId = uniqueClientId();
+ rpConfigureMockHttpClientWithAnchorConstraints(clientId,
+ Map.of("naming_constraints", Map.of("permitted", List.of(".federation.local")),
+ "allowed_entity_types", List.of("openid_relying_party")));
+ final FlowExecutionResult result =
+ launchAuthenticationRequest(clientId, "openid profile", signedRequestObject(Map.of(
+ "iss", clientId,
+ "client_id", clientId,
+ "aud", issuer,
+ "exp", Instant.now().plus(Duration.ofMinutes(5)).toEpochMilli(),
+ "jti", UUID.randomUUID(),
+ "response_type", "code",
+ "scope", "openid profile",
+ "redirect_uri", redirectUri)));
+ final AuthenticationResponse responseMessage = parseSuccessResponse(result, AuthenticationResponse.class);
+ final AuthenticationSuccessResponse successResponse = responseMessage.toSuccessResponse();
+ Assert.assertEquals(successResponse.getRedirectionURI().toString(), redirectUri);
+ Assert.assertNull(successResponse.getIDToken());
+ Assert.assertNull(successResponse.getAccessToken());
+ Assert.assertNotNull(successResponse.getAuthorizationCode());
+ Assert.assertEquals(unwrapTrustChainFromAuthorizeCode(successResponse), List.of(clientId, anchorId));
+ }
+
+ @Test
+ public void testWithPar_matchingAutoRegisteredTrustChain()
+ throws IOException, UnsupportedOperationException, URISyntaxException {
+ final String clientId = uniqueClientId();
+ rpConfigureMockHttpClient(clientId);
+ final FlowExecutionResult result =
+ launchAuthenticationRequest(clientId, "openid profile", createParGeneratedRequestUri(Map.of(
+ "client_id", clientId,
+ "response_type", "code",
+ "scope", "openid profile",
+ "redirect_uri", redirectUri), List.of(clientId, anchorId)));
+ final AuthenticationResponse responseMessage = parseSuccessResponse(result, AuthenticationResponse.class);
+ final AuthenticationSuccessResponse successResponse = responseMessage.toSuccessResponse();
+ Assert.assertEquals(successResponse.getRedirectionURI().toString(), redirectUri);
+ Assert.assertNull(successResponse.getIDToken());
+ Assert.assertNull(successResponse.getAccessToken());
+ Assert.assertNotNull(successResponse.getAuthorizationCode());
+ Assert.assertEquals(unwrapTrustChainFromAuthorizeCode(successResponse), List.of(clientId, anchorId));
+ }
+
+ protected URI createParGeneratedRequestUri(final Map<String, Object> parameters,
+ final List<String> trustChain) {
+ final DefaultPushedAuthorizationRequestUriSerializationFunction parGenerator =
+ new DefaultPushedAuthorizationRequestUriSerializationFunction();
+ parGenerator.setObjectMapper(new ObjectMapper());
+ parGenerator.setDataSealer(getDataSealer());
+ parGenerator.setIdentifierGeneratorLookupStrategy(prc -> idGenerator);
+ parGenerator.setId("mockPar");
+ try {
+ parGenerator.initialize();
+ } catch (ComponentInitializationException e) {
+ Assert.fail("Could not initialize PAR generator", e);
+ }
+ final Map<String, Object> map = new HashMap<>(parameters);
+ map.put("oidfed_artc", trustChain);
+ return parGenerator.apply(null, map);
+ }
+
+ protected FlowExecutionResult launchAuthenticationRequest(final String clientId, final String scope) {
+ return launchAuthenticationRequest(clientId, scope, (JWT) null);
+ }
+
+ protected FlowExecutionResult launchAuthenticationRequest(final String clientId, final String scope,
+ final JWT requestObject) {
+ setQueryParameters(request, List.of(new Pair<>("client_id", clientId),
+ new Pair<>("response_type", "code"),
+ new Pair<>("scope", scope),
+ new Pair<>("redirect_uri", redirectUri),
+ new Pair<>("request", requestObject == null ? "" : requestObject.serialize())));
+ request.setMethod("GET");
+
+ setBasicAuth("jdoe", "changeit");
+ initializeThreadLocals();
+
+ return flowExecutor.launchExecution(AuthorizeFlowTest.FLOW_ID, null, externalContext);
+ }
+
+ protected FlowExecutionResult launchAuthenticationRequest(final String clientId, final String scope,
+ final URI requestUri) {
+ setQueryParameters(request, List.of(new Pair<>("client_id", clientId),
+ new Pair<>("response_type", "code"),
+ new Pair<>("scope", scope),
+ new Pair<>("request_uri", "" + requestUri)));
+ request.setMethod("GET");
+
+ setBasicAuth("jdoe", "changeit");
+ initializeThreadLocals();
+
+ return flowExecutor.launchExecution(AuthorizeFlowTest.FLOW_ID, null, externalContext);
+ }
+
+ protected List<String> unwrapTrustChainFromAuthorizeCode(final AuthenticationSuccessResponse successResponse) {
+ Assert.assertNotNull(successResponse.getAuthorizationCode());
+ final String code = successResponse.getAuthorizationCode().getValue();
+ assert code != null;
+ final AuthorizeCodeClaimsSet claims;
+ try {
+ claims = AuthorizeCodeClaimsSet.parse(code, getDataSealer());
+ Assert.assertNotNull(claims.getClaimsSet().getStringListClaim("oidfed_artc"));
+ return claims.getClaimsSet().getStringListClaim("oidfed_artc");
+ } catch (ParseException | DataSealerException e) {
+ return null;
+ }
+ }
+
+ protected static void setQueryParameters(final MockHttpServletRequest request,
+ final List<Pair<String, String>> pairs) {
+ final StringBuffer query = new StringBuffer();
+ request.removeAllParameters();
+ for (final Pair<String, String> pair : pairs) {
+ final String first = pair.getFirst();
+ assert first != null;
+ request.addParameter(first, pair.getSecond());
+ try {
+ query.append(pair.getFirst() + "=" + URLEncoder.encode(pair.getSecond(), "UTF-8") + "&");
+ } catch (UnsupportedEncodingException e) {
+ Assert.fail(e.getMessage());
+ }
+ }
+ request.setQueryString(query.toString());
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/EntityConfigurationFlowTest.java b/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/EntityConfigurationFlowTest.java
new file mode 100644
index 0000000..f079c81
--- /dev/null
+++ b/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/EntityConfigurationFlowTest.java
@@ -0,0 +1,116 @@
+/*
+ * 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.oidfed;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+import org.springframework.webflow.executor.FlowExecutionResult;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.nimbusds.jose.Algorithm;
+import com.nimbusds.oauth2.sdk.ParseException;
+import com.nimbusds.oauth2.sdk.Response;
+import com.nimbusds.oauth2.sdk.id.Issuer;
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+import com.nimbusds.openid.connect.sdk.federation.entities.FederationEntityMetadata;
+import com.nimbusds.openid.connect.sdk.federation.registration.ClientRegistrationType;
+import com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata;
+
+/**
+ * Unit test for the entity configuration flow.
+ */
+public class EntityConfigurationFlowTest extends AbstractFederationFlowTest {
+
+ public static final String FLOW_ID = "oidfed/entity-configuration";
+
+ protected EntityConfigurationFlowTest() {
+ super(FLOW_ID);
+ }
+
+ @Test
+ public void testOutputAndCaching() throws ParseException, IOException, InterruptedException {
+ request.setRequestURI("/idp/profile/oidfed/entity-configuration");
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ final Response response = parseResponse(result);
+ Assert.assertTrue(response.indicatesSuccess());
+ assertEntityStatement(response);
+
+ final FlowExecutionResult result2 = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ final Response response2 = parseResponse(result2);
+ Assert.assertEquals(response2.toHTTPResponse().getContent(), response.toHTTPResponse().getContent());
+
+ Thread.sleep(2000);
+ final FlowExecutionResult result3 = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ final Response response3 = parseResponse(result3);
+ assertEntityStatement(response3);
+ Assert.assertNotEquals(response3.toHTTPResponse().getContent(), response.toHTTPResponse().getContent());
+ }
+
+ protected void assertEntityStatement(final Response response) throws ParseException {
+ final EntityStatement entityStatement = EntityStatement.parse(response.toHTTPResponse().getContent());
+ final OIDCProviderMetadata metadata = entityStatement.getClaimsSet().getOPMetadata();
+ Assert.assertEquals(metadata.getIssuer(), new Issuer("https://op.example.org"));;
+ // all but RSA-OAEP-384 as it's excluded in test relying-party.xml
+ final List<String> jweAlgs = Arrays.asList("RSA1_5", "RSA-OAEP", "RSA-OAEP-256", "RSA-OAEP-512",
+ "A128KW", "A192KW", "A256KW", "A128GCMKW", "A192GCMKW", "A256GCMKW", "ECDH-ES", "ECDH-ES+A128KW",
+ "ECDH-ES+A192KW", "ECDH-ES+A256KW");
+ // all but A192CBC-HS384 as it's excluded in test relying-party.xml
+ final List<String> jweEncs = Arrays.asList("A128CBC-HS256", "A256CBC-HS512", "A128GCM", "A192GCM", "A256GCM");
+ // all but ES384 as it's excluded in test relying-party.xml
+ final List<String> jwsAlgs = Arrays.asList("RS256", "RS384", "RS512", "ES256", "ES512", "HS256", "HS384",
+ "HS512", "PS256", "PS384", "PS512");
+ Assert.assertNotNull(metadata.getIDTokenJWEAlgs());
+ Assert.assertTrue(containsAll(metadata.getIDTokenJWEAlgs(), jweAlgs));
+ Assert.assertNotNull(metadata.getIDTokenJWEAlgs());
+ Assert.assertTrue(containsAll(metadata.getIDTokenJWEEncs(), jweEncs));
+ Assert.assertNotNull(metadata.getIDTokenJWEEncs());
+ Assert.assertTrue(containsAll(metadata.getIDTokenJWSAlgs(), jwsAlgs));
+ Assert.assertNotNull(metadata.getUserInfoJWEAlgs());
+ Assert.assertTrue(containsAll(metadata.getUserInfoJWEAlgs(), jweAlgs));
+ Assert.assertNotNull(metadata.getUserInfoJWEAlgs());
+ Assert.assertTrue(containsAll(metadata.getUserInfoJWEEncs(), jweEncs));
+ Assert.assertNotNull(metadata.getUserInfoJWEEncs());
+ Assert.assertTrue(containsAll(metadata.getUserInfoJWSAlgs(), jwsAlgs));
+ Assert.assertNotNull(metadata.getCustomParameter("STATIC_CONF_ATTRIBUTE"));
+ Assert.assertEquals(metadata.getCustomParameter("STATIC_CONF_ATTRIBUTE"), "TestAttributeValue");
+ Assert.assertTrue(metadata.getClientRegistrationTypes().containsAll(
+ List.of(ClientRegistrationType.AUTOMATIC, ClientRegistrationType.EXPLICIT)));
+ try {
+ Assert.assertEquals(metadata.getFederationRegistrationEndpointURI(),
+ new URI("http://localhost/idp/profile/oidfed/register"));
+ } catch (URISyntaxException e) {
+ Assert.fail("Could not build URI", e);
+ }
+ final FederationEntityMetadata entityMetadata = entityStatement.getClaimsSet().getFederationEntityMetadata();
+ Assert.assertEquals(entityMetadata.getOrganizationName(), "Example organization");
+ Assert.assertEquals(entityMetadata.getContacts(), List.of("contact at example.org"));
+ }
+
+ protected boolean containsAll(Collection<? extends Algorithm> algs, Collection<String> strings) {
+ final List<String> algStrings = new ArrayList<>();
+ for (final Algorithm alg : algs) {
+ algStrings.add(alg.toString());
+ }
+ return strings.size() == algStrings.size() ? strings.containsAll(strings) : false;
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/PushedAuthorizeFlowAutomaticRegistrationTest.java b/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/PushedAuthorizeFlowAutomaticRegistrationTest.java
new file mode 100644
index 0000000..94b6016
--- /dev/null
+++ b/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/PushedAuthorizeFlowAutomaticRegistrationTest.java
@@ -0,0 +1,489 @@
+/*
+ * 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.oidfed;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URLEncoder;
+import java.security.PublicKey;
+import java.text.ParseException;
+import java.time.Duration;
+import java.time.Instant;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
+import org.opensaml.storage.impl.MemoryStorageService;
+import org.opensaml.storage.impl.StorageServiceReplayCache;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.webflow.executor.FlowExecutionResult;
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.nimbusds.jose.JWSAlgorithm;
+import com.nimbusds.jose.jwk.JWKSet;
+import com.nimbusds.jwt.JWT;
+import com.nimbusds.jwt.JWTClaimsSet;
+import com.nimbusds.jwt.SignedJWT;
+import com.nimbusds.oauth2.sdk.OAuth2Error;
+import com.nimbusds.oauth2.sdk.PushedAuthorizationSuccessResponse;
+import com.nimbusds.oauth2.sdk.ResponseType;
+import com.nimbusds.oauth2.sdk.auth.ClientAuthenticationMethod;
+import com.nimbusds.openid.connect.sdk.rp.OIDCClientMetadata;
+
+import net.shibboleth.idp.plugin.oidc.op.oidfed.support.ClaimsSetExtensionSupport;
+import net.shibboleth.idp.plugin.oidc.op.profile.flow.PushedAuthorizeFlowTest;
+import net.shibboleth.idp.plugin.oidc.op.profile.logic.DefaultPushedAuthorizationRequestUriDeserializationFunction;
+import net.shibboleth.idp.plugin.oidc.op.token.support.AuthorizeCodeClaimsSet;
+import net.shibboleth.shared.collection.Pair;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.security.DataSealerException;
+
+public class PushedAuthorizeFlowAutomaticRegistrationTest extends AbstractFederationFlowTest {
+
+ private DefaultPushedAuthorizationRequestUriDeserializationFunction statelessDeserializer;
+
+ public PushedAuthorizeFlowAutomaticRegistrationTest() {
+ super(PushedAuthorizeFlowTest.FLOW_ID);
+ }
+
+ @BeforeMethod
+ public void initDeserializer() throws ComponentInitializationException {
+ final StorageServiceReplayCache replayCache = new StorageServiceReplayCache();
+ final MemoryStorageService storageService = new MemoryStorageService();
+ storageService.setId("mockId");
+ storageService.initialize();
+ replayCache.setStorage(storageService);
+ statelessDeserializer = new DefaultPushedAuthorizationRequestUriDeserializationFunction();
+ statelessDeserializer.setDataSealer(getDataSealer());
+ statelessDeserializer.setObjectMapper(new ObjectMapper());
+ statelessDeserializer.setReplayCache(replayCache);
+ }
+
+ @Test
+ public void testSuccess() throws Exception {
+ final String clientId = uniqueClientId();
+ rpConfigureMockHttpClient(clientId);
+ final SignedJWT jwt = createPrivateKeyJWT(validClaimsSet(clientId, issuer),
+ rpKey.toRSAKey().toRSAPrivateKey(), JWSAlgorithm.RS512);
+ final FlowExecutionResult result = launchWithJwtAuthentication(jwt, null,
+ ClientAuthenticationMethod.PRIVATE_KEY_JWT, rpKey.toRSAKey().toPublicKey());
+ assertSuccessResponse(result, clientId);
+ final PushedAuthorizationSuccessResponse response =
+ parseSuccessResponse(result, PushedAuthorizationSuccessResponse.class);
+ verifyAuthorizeEndpoint(clientId, response.getRequestURI().toString());
+ }
+
+ @Test
+ public void testUnmatchingRpConfigurationSignature() throws Exception {
+ final String clientId = uniqueClientId();
+ final OIDCClientMetadata metadata = new OIDCClientMetadata();
+ metadata.setRedirectionURI(new URI(redirectUri));
+ metadata.setJWKSet(new JWKSet(rpKey.toPublicJWK()));
+ rpConfigureMockHttpClient(clientId, rpEntityConfigurationUnmatchingKey(clientId, metadata));
+ final SignedJWT jwt = createPrivateKeyJWT(validClaimsSet(clientId, issuer),
+ rpKey.toRSAKey().toRSAPrivateKey(), JWSAlgorithm.RS512);
+ final FlowExecutionResult result = launchWithJwtAuthentication(jwt, null,
+ ClientAuthenticationMethod.PRIVATE_KEY_JWT, rpKey.toRSAKey().toPublicKey());
+ assertErrorCode(result, OAuth2Error.INVALID_CLIENT_CODE);
+ }
+
+ @Test
+ public void testWithPublicClientWithoutRequestObject() throws Exception {
+ final OIDCClientMetadata metadata = new OIDCClientMetadata();
+ metadata.setRedirectionURI(new URI(redirectUri));
+ metadata.setResponseTypes(Set.of(ResponseType.CODE));
+ metadata.setJWKSet(new JWKSet(rpKey.toPublicJWK()));
+ metadata.setTokenEndpointAuthMethod(ClientAuthenticationMethod.NONE);
+ final String clientId = uniqueClientId();
+ rpConfigureMockHttpClient(clientId, metadata);
+ setHttpFormRequest("POST", createRequestParameters(clientId));
+ final FlowExecutionResult result =
+ flowExecutor.launchExecution(PushedAuthorizeFlowTest.FLOW_ID, null, externalContext);
+ assertErrorCode(result, OAuth2Error.INVALID_CLIENT_CODE);
+ }
+
+ @Test
+ public void testWithPublicClientWithSignedRequestObject() throws Exception {
+ final OIDCClientMetadata metadata = new OIDCClientMetadata();
+ metadata.setRedirectionURI(new URI(redirectUri));
+ metadata.setResponseTypes(Set.of(ResponseType.CODE));
+ metadata.setJWKSet(new JWKSet(rpKey.toPublicJWK()));
+ metadata.setTokenEndpointAuthMethod(ClientAuthenticationMethod.NONE);
+ final String clientId = uniqueClientId();
+ rpConfigureMockHttpClient(clientId, metadata);
+ setHttpFormRequest("POST", createRequestParameters(clientId, "openid", "code", signedRequestObject(Map.of(
+ "client_id", clientId,
+ "iss", clientId,
+ "aud", issuer,
+ "exp", Instant.now().plus(Duration.ofMinutes(5)).toEpochMilli(),
+ "jti", UUID.randomUUID(),
+ "response_type", "code",
+ "scope", "openid",
+ "redirect_uri", redirectUri)).serialize()));
+ final FlowExecutionResult result =
+ flowExecutor.launchExecution(PushedAuthorizeFlowTest.FLOW_ID, null, externalContext);
+ assertSuccessResponse(result, clientId);
+ final PushedAuthorizationSuccessResponse response =
+ parseSuccessResponse(result, PushedAuthorizationSuccessResponse.class);
+ verifyAuthorizeEndpoint(clientId, response.getRequestURI().toString());
+ }
+
+ @Test
+ public void testWithPublicClientWithSignedRequestObject_missingJti() throws Exception {
+ final OIDCClientMetadata metadata = new OIDCClientMetadata();
+ metadata.setRedirectionURI(new URI(redirectUri));
+ metadata.setResponseTypes(Set.of(ResponseType.CODE));
+ metadata.setJWKSet(new JWKSet(rpKey.toPublicJWK()));
+ metadata.setTokenEndpointAuthMethod(ClientAuthenticationMethod.NONE);
+ final String clientId = uniqueClientId();
+ rpConfigureMockHttpClient(clientId, metadata);
+ setHttpFormRequest("POST", createRequestParameters(clientId, "openid", "code", signedRequestObject(Map.of(
+ "client_id", clientId,
+ "iss", clientId,
+ "aud", issuer,
+ "exp", Instant.now().plus(Duration.ofMinutes(5)).toEpochMilli(),
+ "response_type", "code",
+ "scope", "openid",
+ "redirect_uri", redirectUri)).serialize()));
+ final FlowExecutionResult result =
+ flowExecutor.launchExecution(PushedAuthorizeFlowTest.FLOW_ID, null, externalContext);
+ assertErrorCode(result, OAuth2Error.INVALID_REQUEST_CODE);
+ }
+
+ @Test
+ public void testWithPublicClientWithSignedRequestObject_missingIss() throws Exception {
+ final OIDCClientMetadata metadata = new OIDCClientMetadata();
+ metadata.setRedirectionURI(new URI(redirectUri));
+ metadata.setResponseTypes(Set.of(ResponseType.CODE));
+ metadata.setJWKSet(new JWKSet(rpKey.toPublicJWK()));
+ metadata.setTokenEndpointAuthMethod(ClientAuthenticationMethod.NONE);
+ final String clientId = uniqueClientId();
+ rpConfigureMockHttpClient(clientId, metadata);
+ setHttpFormRequest("POST", createRequestParameters(clientId, "openid", "code", signedRequestObject(Map.of(
+ "client_id", clientId,
+ "aud", issuer,
+ "exp", Instant.now().plus(Duration.ofMinutes(5)).toEpochMilli(),
+ "jti", UUID.randomUUID(),
+ "response_type", "code",
+ "scope", "openid",
+ "redirect_uri", redirectUri)).serialize()));
+ final FlowExecutionResult result =
+ flowExecutor.launchExecution(PushedAuthorizeFlowTest.FLOW_ID, null, externalContext);
+ assertErrorCode(result, OAuth2Error.INVALID_REQUEST_CODE);
+ }
+
+ @Test
+ public void testWithPublicClientWithSignedRequestObject_invalidIss() throws Exception {
+ final OIDCClientMetadata metadata = new OIDCClientMetadata();
+ metadata.setRedirectionURI(new URI(redirectUri));
+ metadata.setResponseTypes(Set.of(ResponseType.CODE));
+ metadata.setJWKSet(new JWKSet(rpKey.toPublicJWK()));
+ metadata.setTokenEndpointAuthMethod(ClientAuthenticationMethod.NONE);
+ final String clientId = uniqueClientId();
+ rpConfigureMockHttpClient(clientId, metadata);
+ setHttpFormRequest("POST", createRequestParameters(clientId, "openid", "code", signedRequestObject(Map.of(
+ "client_id", clientId,
+ "iss", clientId + "2",
+ "aud", issuer,
+ "exp", Instant.now().plus(Duration.ofMinutes(5)).toEpochMilli(),
+ "jti", UUID.randomUUID(),
+ "response_type", "code",
+ "scope", "openid",
+ "redirect_uri", redirectUri)).serialize()));
+ final FlowExecutionResult result =
+ flowExecutor.launchExecution(PushedAuthorizeFlowTest.FLOW_ID, null, externalContext);
+ assertErrorCode(result, OAuth2Error.INVALID_REQUEST_CODE);
+ }
+
+ @Test
+ public void testWithPublicClientWithSignedRequestObject_missingClientId() throws Exception {
+ final OIDCClientMetadata metadata = new OIDCClientMetadata();
+ metadata.setRedirectionURI(new URI(redirectUri));
+ metadata.setResponseTypes(Set.of(ResponseType.CODE));
+ metadata.setJWKSet(new JWKSet(rpKey.toPublicJWK()));
+ metadata.setTokenEndpointAuthMethod(ClientAuthenticationMethod.NONE);
+ final String clientId = uniqueClientId();
+ rpConfigureMockHttpClient(clientId, metadata);
+ setHttpFormRequest("POST", createRequestParameters(clientId, "openid", "code", signedRequestObject(Map.of(
+ "iss", clientId,
+ "aud", issuer,
+ "exp", Instant.now().plus(Duration.ofMinutes(5)).toEpochMilli(),
+ "jti", UUID.randomUUID(),
+ "response_type", "code",
+ "scope", "openid",
+ "redirect_uri", redirectUri)).serialize()));
+ final FlowExecutionResult result =
+ flowExecutor.launchExecution(PushedAuthorizeFlowTest.FLOW_ID, null, externalContext);
+ assertErrorCode(result, OAuth2Error.INVALID_CLIENT_CODE);
+ }
+
+ @Test
+ public void testWithPublicClientWithSignedRequestObject_invalidClientId() throws Exception {
+ final OIDCClientMetadata metadata = new OIDCClientMetadata();
+ metadata.setRedirectionURI(new URI(redirectUri));
+ metadata.setResponseTypes(Set.of(ResponseType.CODE));
+ metadata.setJWKSet(new JWKSet(rpKey.toPublicJWK()));
+ metadata.setTokenEndpointAuthMethod(ClientAuthenticationMethod.NONE);
+ final String clientId = uniqueClientId();
+ rpConfigureMockHttpClient(clientId, metadata);
+ setHttpFormRequest("POST", createRequestParameters(clientId, "openid", "code", signedRequestObject(Map.of(
+ "client_id", clientId + "2",
+ "iss", clientId,
+ "aud", issuer,
+ "exp", Instant.now().plus(Duration.ofMinutes(5)).toEpochMilli(),
+ "jti", UUID.randomUUID(),
+ "response_type", "code",
+ "scope", "openid",
+ "redirect_uri", redirectUri)).serialize()));
+ final FlowExecutionResult result =
+ flowExecutor.launchExecution(PushedAuthorizeFlowTest.FLOW_ID, null, externalContext);
+ assertErrorCode(result, OAuth2Error.INVALID_CLIENT_CODE);
+ }
+
+ @Test
+ public void testWithPublicClientWithSignedRequestObject_missingExp() throws Exception {
+ final OIDCClientMetadata metadata = new OIDCClientMetadata();
+ metadata.setRedirectionURI(new URI(redirectUri));
+ metadata.setResponseTypes(Set.of(ResponseType.CODE));
+ metadata.setJWKSet(new JWKSet(rpKey.toPublicJWK()));
+ metadata.setTokenEndpointAuthMethod(ClientAuthenticationMethod.NONE);
+ final String clientId = uniqueClientId();
+ rpConfigureMockHttpClient(clientId, metadata);
+ setHttpFormRequest("POST", createRequestParameters(clientId, "openid", "code", signedRequestObject(Map.of(
+ "client_id", clientId,
+ "iss", clientId,
+ "aud", issuer,
+ "jti", UUID.randomUUID(),
+ "response_type", "code",
+ "scope", "openid",
+ "redirect_uri", redirectUri)).serialize()));
+ final FlowExecutionResult result =
+ flowExecutor.launchExecution(PushedAuthorizeFlowTest.FLOW_ID, null, externalContext);
+ assertErrorCode(result, OAuth2Error.INVALID_REQUEST_CODE);
+ }
+
+ @Test
+ public void testWithPublicClientWithSignedRequestObject_constainsForbiddenSub() throws Exception {
+ final OIDCClientMetadata metadata = new OIDCClientMetadata();
+ metadata.setRedirectionURI(new URI(redirectUri));
+ metadata.setResponseTypes(Set.of(ResponseType.CODE));
+ metadata.setJWKSet(new JWKSet(rpKey.toPublicJWK()));
+ metadata.setTokenEndpointAuthMethod(ClientAuthenticationMethod.NONE);
+ final String clientId = uniqueClientId();
+ rpConfigureMockHttpClient(clientId, metadata);
+ setHttpFormRequest("POST", createRequestParameters(clientId, "openid", "code", signedRequestObject(Map.of(
+ "client_id", clientId,
+ "sub", "mockValue",
+ "iss", clientId,
+ "aud", issuer,
+ "exp", Instant.now().plus(Duration.ofMinutes(5)).toEpochMilli(),
+ "jti", UUID.randomUUID(),
+ "response_type", "code",
+ "scope", "openid",
+ "redirect_uri", redirectUri)).serialize()));
+ final FlowExecutionResult result =
+ flowExecutor.launchExecution(PushedAuthorizeFlowTest.FLOW_ID, null, externalContext);
+ assertErrorCode(result, OAuth2Error.INVALID_REQUEST_CODE);
+ }
+
+ @Test
+ public void testWithPublicClientWithSignedRequestObject_containsAdditionalAudience() throws Exception {
+ final OIDCClientMetadata metadata = new OIDCClientMetadata();
+ metadata.setRedirectionURI(new URI(redirectUri));
+ metadata.setResponseTypes(Set.of(ResponseType.CODE));
+ metadata.setJWKSet(new JWKSet(rpKey.toPublicJWK()));
+ metadata.setTokenEndpointAuthMethod(ClientAuthenticationMethod.NONE);
+ final String clientId = uniqueClientId();
+ rpConfigureMockHttpClient(clientId, metadata);
+ setHttpFormRequest("POST", createRequestParameters(clientId, "openid", "code", signedRequestObject(Map.of(
+ "client_id", clientId,
+ "iss", clientId,
+ "aud", List.of(issuer, "https://additional.example.org"),
+ "exp", Instant.now().plus(Duration.ofMinutes(5)).toEpochMilli(),
+ "jti", UUID.randomUUID(),
+ "response_type", "code",
+ "scope", "openid",
+ "redirect_uri", redirectUri)).serialize()));
+ final FlowExecutionResult result =
+ flowExecutor.launchExecution(PushedAuthorizeFlowTest.FLOW_ID, null, externalContext);
+ assertErrorCode(result, OAuth2Error.INVALID_REQUEST_CODE);
+ }
+
+ @Test
+ public void testWithPublicClientWithPlainRequestObject() throws Exception {
+ final OIDCClientMetadata metadata = new OIDCClientMetadata();
+ metadata.setRedirectionURI(new URI(redirectUri));
+ metadata.setResponseTypes(Set.of(ResponseType.CODE));
+ metadata.setJWKSet(new JWKSet(rpKey.toPublicJWK()));
+ metadata.setTokenEndpointAuthMethod(ClientAuthenticationMethod.NONE);
+ final String clientId = uniqueClientId();
+ rpConfigureMockHttpClient(clientId, metadata);
+ setHttpFormRequest("POST", createRequestParameters(clientId, "openid", "code", plainRequestObject(Map.of(
+ "client_id", clientId,
+ "iss", clientId,
+ "aud", issuer,
+ "exp", Instant.now().plus(Duration.ofMinutes(5)).toEpochMilli(),
+ "jti", UUID.randomUUID(),
+ "response_type", "code",
+ "scope", "openid",
+ "redirect_uri", redirectUri)).serialize()));
+ final FlowExecutionResult result =
+ flowExecutor.launchExecution(PushedAuthorizeFlowTest.FLOW_ID, null, externalContext);
+ assertErrorCode(result, OAuth2Error.INVALID_CLIENT_CODE);
+ }
+
+ @Test
+ public void testWithTestVectors() throws Exception {
+ final List<Map<String, Object>> vectors = loadPolicyTestVectors();
+ for (final Map<String, Object> vector : vectors) {
+ initializeMocks();
+ initializeThreadLocals();
+ final String clientId = uniqueClientId();
+ rpConfigureMockHttpClient(clientId, vector);
+ final SignedJWT jwt = createPrivateKeyJWT(validClaimsSet(clientId, issuer),
+ rpKey.toRSAKey().toRSAPrivateKey(), JWSAlgorithm.RS256);
+ final FlowExecutionResult result = launchWithJwtAuthentication(jwt, null,
+ ClientAuthenticationMethod.PRIVATE_KEY_JWT, rpKey.toRSAKey().toPublicKey());
+ final String ERROR_MESSAGE = "Unexpected result with test vector " + vector.get("n");
+ if (vector.get("error") instanceof String error) {
+ assertErrorCode(result, "invalid_metadata", ERROR_MESSAGE);
+ if ("invalid_policy".equals(error)) {
+ assertErrorDescriptionContains(result, "Merged metadata policy is invalid", ERROR_MESSAGE);
+ } else {
+ assertErrorDescriptionContains(result, "Requested metadata is not compliant with the merged policy",
+ ERROR_MESSAGE);
+ }
+ } else {
+ assertSuccessResponse(result, clientId, ERROR_MESSAGE);
+ }
+ }
+ }
+
+ protected void verifyAuthorizeEndpoint(final String clientId, final String requestUri) {
+ verifyAuthorizeEndpoint(clientId, requestUri, null);
+ }
+
+ protected void verifyAuthorizeEndpoint(final String clientId, final String requestUri, final String jkt) {
+ initializeMocks();
+ initializeThreadLocals();
+ setBasicAuth("jdoe", "changeit");
+ request.setMethod("GET");
+
+ setRequestParameters(request, List.of(new Pair<>("client_id", clientId),
+ new Pair<>("request_uri", requestUri)));
+
+ final FlowExecutionResult result = flowExecutor.launchExecution("oidc/authorize", null, externalContext);
+ Assert.assertEquals(result.getOutcome().getId(), END_STATE_ID);
+ if (jkt != null) {
+ final String url = response.getRedirectedUrl();
+ assert url != null;
+ final String code = url.substring(url.indexOf("code=") + 5);
+ assert code != null;
+ try {
+ final AuthorizeCodeClaimsSet claimsSet = AuthorizeCodeClaimsSet.parse(code, getDataSealer());
+ assert claimsSet != null;
+ Assert.assertEquals(claimsSet.getDpopProofJwkThumbprint(), jkt);
+ } catch (ParseException | DataSealerException e) {
+ Assert.fail(e.getMessage());
+ }
+ }
+ }
+ protected FlowExecutionResult launchWithJwtAuthentication(final JWT jwt, final JWSAlgorithm algorithm,
+ final ClientAuthenticationMethod method, final PublicKey publicKey) throws Exception {
+ // use 'iss' claim from JWT as clientId if set, 'sub' otherwise
+ final String iss = jwt.getJWTClaimsSet().getStringClaim("iss");
+ final String clientId = iss == null ? jwt.getJWTClaimsSet().getStringClaim("sub") : iss;
+ final Map<String, String> requestParameters = createRequestParameters(clientId);
+ populateClientAssertionParams(requestParameters, jwt);
+ setHttpFormRequest("POST", requestParameters);
+ return flowExecutor.launchExecution(PushedAuthorizeFlowTest.FLOW_ID, null, externalContext);
+ }
+
+ protected void populateClientAssertionParams(final Map<String, String> requestParameters,
+ final JWT jwt) {
+ requestParameters.put("client_assertion", jwt.serialize());
+ requestParameters.put("client_assertion_type", "urn:ietf:params:oauth:client-assertion-type:jwt-bearer");
+ }
+
+ protected JWTClaimsSet validClaimsSet(final String clientId, final String audience) {
+ return new JWTClaimsSet.Builder()
+ .subject(clientId)
+ .issuer(clientId)
+ .audience(audience)
+ .expirationTime(Date.from(Instant.now().plusSeconds(600)))
+ .jwtID(idGenerator.generateIdentifier())
+ .build();
+ }
+
+ protected Map<String,String> createRequestParameters(final String id) {
+ return createRequestParameters(id, "openid", "code", null);
+ }
+
+ protected Map<String,String> createRequestParameters(final String id, final String scope,
+ final String responseType, final String requestObject) {
+ final Map<String,String> result = new HashMap<>();
+ result.put("client_id", id);
+ if (responseType != null) {
+ result.put("response_type", responseType);
+ }
+ if (scope != null) {
+ result.put("scope", scope);
+ }
+ result.put("redirect_uri", redirectUri);
+ if (requestObject != null) {
+ result.put("request", requestObject);
+ }
+ return result;
+ }
+
+ protected static void setRequestParameters(final MockHttpServletRequest request,
+ final List<Pair<String, String>> pairs) {
+ final StringBuffer query = new StringBuffer();
+ for (final Pair<String, String> pair : pairs) {
+ final String first = pair.getFirst();
+ assert first != null;
+ request.addParameter(first, pair.getSecond());
+ try {
+ query.append(pair.getFirst() + "=" + URLEncoder.encode(pair.getSecond(), "UTF-8") + "&");
+ } catch (UnsupportedEncodingException e) {
+ Assert.fail(e.getMessage());
+ }
+ }
+ request.setQueryString(query.toString());
+ }
+
+ protected void assertSuccessResponse(final FlowExecutionResult result, final String id) {
+ assertSuccessResponse(result, id, null);
+ }
+
+ protected void assertSuccessResponse(final FlowExecutionResult result, final String id, final String message) {
+ final PushedAuthorizationSuccessResponse resp =
+ parseSuccessResponse(result, PushedAuthorizationSuccessResponse.class);
+ Assert.assertNotNull(resp, message);
+ Assert.assertNotNull(resp.getRequestURI(), message);
+ Assert.assertNotNull(resp.getLifetime(), message);
+ final String requestUri = resp.getRequestURI().toString();
+ Assert.assertTrue(requestUri.startsWith("urn:ietf:params:oauth:request_uri:"));
+ final Map<String,Object> claims = statelessDeserializer.apply(null, resp.getRequestURI());
+ Assert.assertNotNull(claims.get(ClaimsSetExtensionSupport.KEY_AUTO_REGISTERED_TRUST_CHAIN));
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/RegistrationFlowTest.java b/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/RegistrationFlowTest.java
new file mode 100644
index 0000000..0e5e013
--- /dev/null
+++ b/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/RegistrationFlowTest.java
@@ -0,0 +1,342 @@
+/*
+ * 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.oidfed;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.argThat;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.opensaml.storage.StorageRecord;
+import org.opensaml.storage.StorageService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.webflow.executor.FlowExecutionResult;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.nimbusds.jose.jwk.JWKSet;
+import com.nimbusds.oauth2.sdk.ParseException;
+import com.nimbusds.oauth2.sdk.Scope;
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatementClaimsSet;
+import com.nimbusds.openid.connect.sdk.rp.OIDCClientInformation;
+import com.nimbusds.openid.connect.sdk.rp.OIDCClientMetadata;
+
+import net.minidev.json.JSONObject;
+import net.minidev.json.parser.JSONParser;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.messaging.impl.ExplicitClientRegistrationResponse;
+import net.shibboleth.oidc.metadata.impl.BaseStorageServiceClientInformationComponent;
+
+/**
+ * Flow tests for the OpenID federation explicit registration flow.
+ */
+public class RegistrationFlowTest extends AbstractFederationFlowTest {
+
+ public static final String FLOW_ID = "oidfed/register";
+
+ @Autowired
+ @Qualifier("shibboleth.StorageService")
+ StorageService storageService;
+
+ public RegistrationFlowTest() {
+ super(FLOW_ID);
+ }
+
+ @Test
+ public void testInvalidContentType() throws Exception {
+ setJsonRequest("POST", "{}");
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ assertErrorCode(result, "invalid_client_metadata");
+ }
+
+ @Test
+ public void testEmptyEntityConfiguration() throws Exception {
+ setRequest("POST", "", "application/entity-statement+jwt");
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ assertErrorCode(result, "invalid_client_metadata");
+ }
+
+ @Test
+ public void testInvalidEntityConfiguration_wrongSignerKey() throws Exception {
+ final String clientId = uniqueClientId();
+ rpConfigureMockHttpClient(clientId);
+ final OIDCClientMetadata metadata = new OIDCClientMetadata();
+ metadata.setRedirectionURI(new URI(redirectUri));
+ metadata.setJWKSet(new JWKSet(rpKey.toPublicJWK()));
+ setRequest("POST", rpEntityConfigurationUnmatchingKey(clientId, metadata),
+ "application/entity-statement+jwt");
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ verify(federationHttpClient, times(0)).executeOpen(any(),
+ argThat(new RequestUriMatcher(entityConfigurationUrl(clientId))), any());
+ assertErrorCode(result, "invalid_request");
+ }
+
+ @Test
+ public void testValidEntityConfiguration_invalidType() throws Exception {
+ final String clientId = uniqueClientId();
+ rpConfigureMockHttpClient(clientId);
+ setRequest("POST", rpEntityConfiguration(clientId), "application/json");
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ assertErrorCode(result, "invalid_client_metadata");
+ }
+
+ @Test
+ public void testValidEntityConfiguration() throws Exception {
+ final String clientId = uniqueClientId();
+ rpConfigureMockHttpClient(clientId);
+ setRequest("POST", rpEntityConfiguration(clientId), "application/entity-statement+jwt");
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ verify(federationHttpClient, times(0)).executeOpen(any(),
+ argThat(new RequestUriMatcher(entityConfigurationUrl(clientId))), any());
+ assertResponseStatement(parseSuccessResponse(result, ExplicitClientRegistrationResponse.class), clientId);
+ }
+
+ @Test
+ public void testValidEntityConfiguration_customScope() throws Exception {
+ final String clientId = uniqueClientId();
+ rpConfigureMockHttpClient(clientId);
+ final OIDCClientMetadata metadata = new OIDCClientMetadata();
+ metadata.setRedirectionURI(new URI(redirectUri));
+ metadata.setJWKSet(new JWKSet(rpKey.toPublicJWK()));
+ final Scope scope = Scope.parse("openid profile email custom");
+ metadata.setScope(scope);
+ setRequest("POST", rpEntityConfiguration(clientId, metadata), "application/entity-statement+jwt");
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ verify(federationHttpClient, times(0)).executeOpen(any(),
+ argThat(new RequestUriMatcher(entityConfigurationUrl(clientId))), any());
+ final OIDCClientMetadata providedMetadata = assertResponseStatement(
+ parseSuccessResponse(result, ExplicitClientRegistrationResponse.class), clientId);
+ Assert.assertEquals(providedMetadata.getScope(), scope);
+ }
+
+ @Test
+ public void testValidEntityConfiguration_repeat() throws Exception {
+ final String clientId = uniqueClientId();
+ for (int i = 0; i < 2; i++) {
+ rpConfigureMockHttpClient(clientId);
+ setRequest("POST", rpEntityConfiguration(clientId), "application/entity-statement+jwt");
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ verify(federationHttpClient, times(0)).executeOpen(any(),
+ argThat(new RequestUriMatcher(entityConfigurationUrl(clientId))), any());
+ assertResponseStatement(parseSuccessResponse(result, ExplicitClientRegistrationResponse.class), clientId);
+ }
+ }
+
+ @Test
+ public void testValidTrustChain() throws Exception {
+ final String clientId = uniqueClientId();
+ final String trustChain = "[\"" + rpEntityConfiguration(clientId) + "\", \"" +
+ subordinateStatement(clientId, Map.of("openid_relying_party", new OIDCClientMetadata().toJSONObject()))
+ + "\", \"" + trustedAnchorConfiguration() + "\"]";
+ setRequest("POST", trustChain, "application/trust-chain+json");
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ verify(federationHttpClient, times(0)).executeOpen(any(),
+ argThat(new RequestUriMatcher(entityConfigurationUrl(clientId))), any());
+ verify(federationHttpClient, times(0)).executeOpen(any(),
+ argThat(new RequestUriMatcher(super.subordinateStatementUrl(anchorFetchEndpoint, clientId))), any());
+ assertResponseStatement(parseSuccessResponse(result, ExplicitClientRegistrationResponse.class), clientId);
+ }
+
+ @Test
+ public void testValidTrustChain_validMaxLengthInAnchor() throws Exception {
+ final String clientId = uniqueClientId();
+ final String trustChain = "[\"" + rpEntityConfiguration(clientId) + "\", \"" +
+ subordinateStatement(anchorId, anchorKey, leafKey, clientId, Collections.emptyMap(),
+ Map.of("max_path_length", Integer.valueOf(0))) + "\", \"" + trustedAnchorConfiguration() + "\"]";
+ setRequest("POST", trustChain, "application/trust-chain+json");
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ verify(federationHttpClient, times(0)).executeOpen(any(),
+ argThat(new RequestUriMatcher(entityConfigurationUrl(clientId))), any());
+ verify(federationHttpClient, times(0)).executeOpen(any(),
+ argThat(new RequestUriMatcher(super.subordinateStatementUrl(anchorFetchEndpoint, clientId))), any());
+ assertResponseStatement(parseSuccessResponse(result, ExplicitClientRegistrationResponse.class), clientId);
+ }
+
+ @Test
+ public void testValidTrustChain_invalidMaxLengthInAnchor() throws Exception {
+ final String clientId = uniqueClientId();
+ final String intermediateId = uniqueIntermediateId();
+ final String trustChain = "[\"" + rpEntityConfiguration(clientId) + "\", \"" +
+ subordinateStatement(intermediateId, intermediateKey, leafKey, clientId, Collections.emptyMap(),
+ Collections.emptyMap()) + "\", \"" +
+ subordinateStatement(anchorId, anchorKey, intermediateKey, intermediateId, Collections.emptyMap(),
+ Map.of("max_path_length", Integer.valueOf(0))) + "\", \"" + trustedAnchorConfiguration() + "\"]";
+ setRequest("POST", trustChain, "application/trust-chain+json");
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ assertErrorCode(result, "invalid_request");
+ }
+
+ @Test
+ public void testValidTrustChain_validNamingConstraintInAnchor() throws Exception {
+ final String clientId = uniqueClientId();
+ final String trustChain = "[\"" + rpEntityConfiguration(clientId) + "\", \"" +
+ subordinateStatement(anchorId, anchorKey, leafKey, clientId, Collections.emptyMap(),
+ Map.of("naming_constraints", Map.of("permitted", List.of(".federation.local")))) +
+ "\", \"" + trustedAnchorConfiguration() + "\"]";
+ setRequest("POST", trustChain, "application/trust-chain+json");
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ verify(federationHttpClient, times(0)).executeOpen(any(),
+ argThat(new RequestUriMatcher(entityConfigurationUrl(clientId))), any());
+ verify(federationHttpClient, times(0)).executeOpen(any(),
+ argThat(new RequestUriMatcher(super.subordinateStatementUrl(anchorFetchEndpoint, clientId))), any());
+ assertResponseStatement(parseSuccessResponse(result, ExplicitClientRegistrationResponse.class), clientId);
+ }
+
+ @Test
+ public void testValidTrustChain_invalidNamingConstraintInAnchor() throws Exception {
+ final String clientId = uniqueClientId();
+ final String trustChain = "[\"" + rpEntityConfiguration(clientId) + "\", \"" +
+ subordinateStatement(anchorId, anchorKey, leafKey, clientId, Collections.emptyMap(),
+ Map.of("naming_constraints", Map.of("permitted", List.of(".wrongfederation.local")))) +
+ "\", \"" + trustedAnchorConfiguration() + "\"]";
+ setRequest("POST", trustChain, "application/trust-chain+json");
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ assertErrorCode(result, "invalid_request");
+ }
+
+ @Test
+ public void testValidTrustChain_validEntityTypeInAnchor() throws Exception {
+ final String clientId = uniqueClientId();
+ final String trustChain = "[\"" + rpEntityConfiguration(clientId) + "\", \"" +
+ subordinateStatement(anchorId, anchorKey, leafKey, clientId, Collections.emptyMap(),
+ Map.of("allowed_entity_types", List.of("openid_relying_party"))) + "\", \"" +
+ trustedAnchorConfiguration() + "\"]";
+ setRequest("POST", trustChain, "application/trust-chain+json");
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ verify(federationHttpClient, times(0)).executeOpen(any(),
+ argThat(new RequestUriMatcher(entityConfigurationUrl(clientId))), any());
+ verify(federationHttpClient, times(0)).executeOpen(any(),
+ argThat(new RequestUriMatcher(super.subordinateStatementUrl(anchorFetchEndpoint, clientId))), any());
+ assertResponseStatement(parseSuccessResponse(result, ExplicitClientRegistrationResponse.class), clientId);
+ }
+
+ @Test
+ public void testValidTrustChain_invalidEmptyEntityTypeInAnchor() throws Exception {
+ final String clientId = uniqueClientId();
+ final String trustChain = "[\"" + rpEntityConfiguration(clientId) + "\", \"" +
+ subordinateStatement(anchorId, anchorKey, leafKey, clientId, Collections.emptyMap(),
+ Map.of("allowed_entity_types", Collections.emptyList())) + "\", \"" +
+ trustedAnchorConfiguration() + "\"]";
+ setRequest("POST", trustChain, "application/trust-chain+json");
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ assertErrorCode(result, "invalid_request");
+ }
+
+ @Test
+ public void testValidTrustChain_invalidEntityTypeInAnchor() throws Exception {
+ final String clientId = uniqueClientId();
+ final String trustChain = "[\"" + rpEntityConfiguration(clientId) + "\", \"" +
+ subordinateStatement(anchorId, anchorKey, leafKey, clientId, Collections.emptyMap(),
+ Map.of("allowed_entity_types", List.of("openid_provider"))) + "\", \"" +
+ trustedAnchorConfiguration() + "\"]";
+ setRequest("POST", trustChain, "application/trust-chain+json");
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ assertErrorCode(result, "invalid_request");
+ }
+
+ @Test
+ public void testInvalidTrustChain_wrongRpEntityConfigurationSignerKey() throws Exception {
+ final String clientId = uniqueClientId();
+ rpConfigureMockHttpClient(clientId);
+ final OIDCClientMetadata metadata = new OIDCClientMetadata();
+ metadata.setRedirectionURI(new URI(redirectUri));
+ metadata.setJWKSet(new JWKSet(rpKey.toPublicJWK()));
+ final String trustChain = "[\"" + rpEntityConfigurationUnmatchingKey(clientId, metadata) + "\", \"" +
+ subordinateStatement(clientId, Map.of("openid_relying_party", new OIDCClientMetadata().toJSONObject()))
+ + "\", \"" + trustedAnchorConfiguration() + "\"]";
+ setRequest("POST", trustChain, "application/trust-chain+json");
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ verify(federationHttpClient, times(0)).executeOpen(any(),
+ argThat(new RequestUriMatcher(entityConfigurationUrl(clientId))), any());
+ verify(federationHttpClient, times(0)).executeOpen(any(),
+ argThat(new RequestUriMatcher(super.subordinateStatementUrl(anchorFetchEndpoint, clientId))), any());
+ assertErrorCode(result, "invalid_request");
+ }
+
+ @Test
+ public void testValidTrustChain_customScope() throws Exception {
+ final String clientId = uniqueClientId();
+ final OIDCClientMetadata metadata = new OIDCClientMetadata();
+ metadata.setRedirectionURI(new URI(redirectUri));
+ metadata.setJWKSet(new JWKSet(rpKey.toPublicJWK()));
+ final Scope scope = Scope.parse("openid profile email custom");
+ metadata.setScope(scope);
+ final String trustChain = "[\"" + rpEntityConfiguration(clientId, metadata) + "\", \"" +
+ subordinateStatement(clientId, Map.of("openid_relying_party", new OIDCClientMetadata().toJSONObject()))
+ + "\", \"" + trustedAnchorConfiguration() + "\"]";
+ setRequest("POST", trustChain, "application/trust-chain+json");
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ final OIDCClientMetadata providedMetadata = assertResponseStatement(
+ parseSuccessResponse(result, ExplicitClientRegistrationResponse.class), clientId);
+ verify(federationHttpClient, times(0)).executeOpen(any(),
+ argThat(new RequestUriMatcher(entityConfigurationUrl(clientId))), any());
+ verify(federationHttpClient, times(0)).executeOpen(any(),
+ argThat(new RequestUriMatcher(super.subordinateStatementUrl(anchorFetchEndpoint, clientId))), any());
+ Assert.assertEquals(providedMetadata.getScope(), scope);
+ }
+
+ @Test
+ public void testValidTrustChain_repeat() throws Exception {
+ final String clientId = uniqueClientId();
+ final String trustChain = "[\"" + rpEntityConfiguration(clientId) + "\", \"" +
+ subordinateStatement(clientId, Map.of("openid_relying_party", new OIDCClientMetadata().toJSONObject()))
+ + "\", \"" + trustedAnchorConfiguration() + "\"]";
+ for (int i = 0; i < 2; i++) {
+ setRequest("POST", trustChain, "application/trust-chain+json");
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ assertResponseStatement(parseSuccessResponse(result, ExplicitClientRegistrationResponse.class), clientId);
+ }
+ }
+
+ protected OIDCClientMetadata assertResponseStatement(final ExplicitClientRegistrationResponse response,
+ final String expectedClientId) throws IOException, ParseException, net.minidev.json.parser.ParseException {
+ final EntityStatement entityStatement = response.getEntityStatement();
+ final EntityStatementClaimsSet statementClaims = entityStatement.getClaimsSet();
+ Assert.assertNotNull(statementClaims.getIssuer());
+ Assert.assertEquals(statementClaims.getIssuer().getValue(), issuer);
+ Assert.assertEquals(statementClaims.getAuthorityHints().stream().map(id -> id.getValue()).toList(),
+ List.of(anchorId));
+ Assert.assertEquals(statementClaims.getClaim("trust_anchor"), anchorId);
+ final OIDCClientInformation clientInfo = entityStatement.getClaimsSet().getRPInformation();
+ final OIDCClientMetadata metadata = clientInfo.getOIDCMetadata();
+ final String providedClientId = clientInfo.getID().getValue();
+ assert providedClientId != null;
+ Assert.assertEquals(providedClientId, expectedClientId);
+ Assert.assertEquals(entityStatement.getClaimsSet().getSubject().getValue(), expectedClientId);
+ assert storageService != null;
+ final StorageRecord<String> storageRecord =
+ storageService.read(BaseStorageServiceClientInformationComponent.CONTEXT_NAME, providedClientId);
+ Assert.assertNotNull(storageRecord, "Record with clientId " + providedClientId + " was null");
+ assert storageRecord != null;
+ final String record = storageRecord.getValue();
+ Assert.assertNotNull(record);
+ final JSONParser parser = new JSONParser(JSONParser.DEFAULT_PERMISSIVE_MODE);
+ final OIDCClientInformation storedInfo = OIDCClientInformation.parse((JSONObject) parser.parse(record));
+ Assert.assertEquals(storedInfo.getID(), clientInfo.getID());
+ Assert.assertEquals(storedInfo.getSecret(), clientInfo.getSecret());
+ Assert.assertEquals(storedInfo.getOIDCMetadata().getRedirectionURIStrings(),
+ metadata.getRedirectionURIStrings());
+ Assert.assertTrue(metadata.getRedirectionURIStrings().contains(redirectUri));
+ return metadata;
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/ResolveEntityFlowTest.java b/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/ResolveEntityFlowTest.java
new file mode 100644
index 0000000..93f2cb0
--- /dev/null
+++ b/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/ResolveEntityFlowTest.java
@@ -0,0 +1,122 @@
+/*
+ * 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.oidfed;
+
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.webflow.executor.FlowExecutionResult;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.nimbusds.jwt.SignedJWT;
+import com.nimbusds.oauth2.sdk.Response;
+
+import net.shibboleth.idp.plugin.oidc.op.oidfed.messaging.impl.ResolveEntityResponse;
+import net.shibboleth.oidc.profile.messaging.JSONErrorResponse;
+
+import net.minidev.json.JSONObject;
+
+/**
+ * Flow tests for the OpenID federation resolve entity flow.
+ */
+public class ResolveEntityFlowTest extends AbstractFederationFlowTest {
+
+ public static final String FLOW_ID = "oidfed/resolve-entity";
+
+ public ResolveEntityFlowTest() {
+ super(FLOW_ID);
+ }
+
+ @Test
+ public void testInvalidMethod() throws Exception {
+ setJsonRequest("POST", "{}");
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ assertErrorCode(result, "invalid_request");
+ }
+
+ @Test
+ public void testInvalidSubject() throws Exception {
+ request.setMethod("GET");
+ request.setQueryString("sub=mockClientId&trust_anchor=" + anchorId + "&entity_type=openid_relying_party");
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ assertErrorCode(result, "invalid_subject");
+ }
+
+ @Test
+ public void testUntrustedAnchor() throws Exception {
+ request.setMethod("GET");
+ final String clientId = uniqueClientId();
+ rpConfigureMockHttpClient(clientId);
+ request.setQueryString("sub=" + clientId + "&trust_anchor=mockAnchors&entity_type=openid_relying_party");
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ assertErrorCode(result, "invalid_trust_anchor");
+ }
+
+ @Test
+ public void testRPWithTrustedTrustAnchor() throws Exception {
+ request.setMethod("GET");
+ final String clientId = uniqueClientId();
+ rpConfigureMockHttpClient(clientId);
+ request.setQueryString("sub=" + clientId + "&trust_anchor=" + anchorId + "&entity_type=openid_relying_party");
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ final ResolveEntityResponse parsedResponse =
+ parseSuccessResponse(result, ResolveEntityResponse.class);
+ final SignedJWT response = parsedResponse.getJWT();
+ Assert.assertEquals(response.getJWTClaimsSet().getSubject(), clientId);
+ Assert.assertNotNull(response.getJWTClaimsSet().getClaim("metadata"));
+ }
+
+ @Test
+ public void testRPWithTrustedTrustAnchorInvalidMetadata() throws Exception {
+ request.setMethod("GET");
+ final String clientId = uniqueClientId();
+ rpConfigureMockHttpClient(clientId, new JSONObject(Map.of("response_types", "invalid")));
+ request.setQueryString("sub=" + clientId + "&trust_anchor=" + anchorId + "&entity_type=openid_relying_party");
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ assertErrorCode(result, "invalid_metadata");
+ }
+
+ @Test
+ public void testOPWithTrustedTrustAnchor() throws Exception {
+ request.setMethod("GET");
+ final String entityId = uniqueClientId();
+ opConfigureMockHttpClient(entityId);
+ request.setQueryString("sub=" + entityId + "&trust_anchor=" + anchorId + "&entity_type=openid_provider");
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ final ResolveEntityResponse parsedResponse =
+ parseSuccessResponse(result, ResolveEntityResponse.class);
+ final SignedJWT response = parsedResponse.getJWT();
+ Assert.assertEquals(response.getJWTClaimsSet().getSubject(), entityId);
+ Assert.assertNotNull(response.getJWTClaimsSet().getClaim("metadata"));
+ }
+
+ @Test
+ public void testOPWithTrustedTrustAnchorInvalidMetadata() throws Exception {
+ request.setMethod("GET");
+ final String entityId = uniqueClientId();
+ opConfigureMockHttpClient(entityId, new JSONObject(Map.of("issuer", List.of("unexpected", "values"))));
+ request.setQueryString("sub=" + entityId + "&trust_anchor=" + anchorId + "&entity_type=openid_provider");
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ assertErrorCode(result, "invalid_metadata");
+ }
+
+ protected JSONErrorResponse parseErrorResponse(final FlowExecutionResult result) {
+ final Response response = parseResponse(result);
+ Assert.assertTrue(response instanceof JSONErrorResponse);
+ return (JSONErrorResponse) response;
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/test/resources/credentials/fed-local-anchor.jwk b/idp-oidfed-op-impl/src/test/resources/credentials/fed-local-anchor.jwk
new file mode 100644
index 0000000..8601a78
--- /dev/null
+++ b/idp-oidfed-op-impl/src/test/resources/credentials/fed-local-anchor.jwk
@@ -0,0 +1,13 @@
+{
+ "alg": "RS256",
+ "kid": "locallyTrustedAnchorKey",
+ "kty": "RSA",
+ "p": "y_ul6_wF0dnPzfK_BW0q5dM2aKRFOekotB6mFmWXE4VY_EVRpPAcHQppBbOUOBMkg_NSmjRK3x8wZYhLeavqfsFNcpGMAMsL1LA_FtPFo1R2B8n-FpcA9uRimjDxlzIQKrbEYM1OGPA7jLCE57fNzta2YM4e1sjP3W7-TfOa7v0",
+ "q": "x--fmMMzN9CRakq-pi6I0ClQq4PXJnJROGzVSjMGKs-YbaFXaWPnF_rHqJunmFavTiiSwCv36kiseEAA8fTl-Ms75MXp7LGo30e0F7JJ3vXDD5MwvapswwoiWJWCgJxCOnWJdWvm_iZApK9xcaM_ngTWQuQEq1JhPq6rEB4wck0",
+ "d": "AnBEysAXveM6Lkt2U4RaRoq30upD1EwX7GBE0xCEyzXHESoZIhriDICL9DcCnH7wz0GHittysTrnzEcOWA37mMRKtMJ9ZX3P4QXhfcxGPVvJoDXuH3hR1rbXsu-b9-aYsGNeO6fZSafqhXBeXYU3q1CJFFjoe72drw3DJ3xwCRdYv3y94YBw09kAQYOA4zAtxrUF3ZhlLH9K4sfFLAEzztJX-OuY3a2UFeNC1FkpNDKovbXU0yrkP_y5jjSPrjI2lBQg4yFN5hM3YM7bvG001E796CEhqRYsnLazNDpRXAIQc_jbs_3YrdrlaWR-abMj1zr0zw44a8JZ5Tvd7imZaQ",
+ "e": "AQAB",
+ "qi": "OlB4Yfvc6MBNsFUPpFGXmuYjVDkgTtcAEG60n1TDsrh4C2ir0-ZyaQg1gV3D3EabD96lnp7IiO3uX6X6e6AJgC2AW052bc1EuRQkhyyXeEYN23u3elF1y2F4eQUbNgfc2ghZfUqx5xhZDWFXbrMC7NaOCn1UOIfBe2kuvqSL8Es",
+ "dp": "ebkddgjaYDOd8cPdgZt3cdXsLd15AenExFdVvR-6W4fDZibnZYly_VFtAl37IMsriyH0NNjnpOWzt6LxhxWzxRgM40U_SmngEXdq7nBJDAImvNcorMpHZQ08Wc7DG_pf811FKo7Y_8C7iGT9qljgk4FFK9dUR89lWzoUvueTmPE",
+ "dq": "UBHQ8pbJ_kJS2iSQ8XCVbff9zJKCKW2CxXwgdxS0FZUJ0G3a2eQeemX-a7HajpG4py5shvWU1YjBOW84ca3II7kQhXAVXKtRnAnVP-Aw4U-_DI-_51VHNVzroFpP5z2s8Eh-Aj5yRboADXQNlJryMVBylltG222kcDv3Wf8dG8k",
+ "n": "n0-NFV06ZDKLo1v8KrSJsQ8bbLEffVJw1F5jGXqrKh_4PpBt9FmyWY3gIA9aK1p1WneMaWRNlM1EObierCr0EdXCQbgpKorrPqxiwyl6cOMIH4fN_9uWGqD2HlyGcjcESrNjZz75tNr_9oegh6fWSMgrxyySpU38ALWUX1ZuNS8A4tj8XdJSbSHqftf7qOdgzuy0yaD5h7NwoBCRPOIY88vOLHkcQ4nYdkk8GLSIf5GgGb7JFiPuFHN7pK---LNnFBifag2wbEZ9nnAcAol4jc2gF7zq2mqhMSlbIVmTRj4Y9wxh3DPbmC8xZ-8nbhPmgi4vlij9JWJGEvfLuXaMGQ"
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/test/resources/credentials/fed-signing-es256.jwk b/idp-oidfed-op-impl/src/test/resources/credentials/fed-signing-es256.jwk
new file mode 100644
index 0000000..a70c96c
--- /dev/null
+++ b/idp-oidfed-op-impl/src/test/resources/credentials/fed-signing-es256.jwk
@@ -0,0 +1,10 @@
+{
+ "kty": "EC",
+ "d": "CO-ctmQcB-hS042i2omOIPpaaAaKkBAU6s_v4W09oA0",
+ "use": "sig",
+ "crv": "P-256",
+ "kid": "fedtestkeyES256",
+ "x": "2uzfE1oK0cf1_c11SFc9vFdGLnJoH3e0AKTrGPAmUis",
+ "y": "14410NGKqwLM58b26ZcvGOruFixpHt_SJTw8I5wwgLQ",
+ "alg": "ES256"
+}
diff --git a/idp-oidfed-op-impl/src/test/resources/credentials/fed-signing-es384.jwk b/idp-oidfed-op-impl/src/test/resources/credentials/fed-signing-es384.jwk
new file mode 100644
index 0000000..c42f913
--- /dev/null
+++ b/idp-oidfed-op-impl/src/test/resources/credentials/fed-signing-es384.jwk
@@ -0,0 +1,9 @@
+{
+ "kty": "EC",
+ "d": "e65hCxxbNq5gubmkgZD73A1cDf_GfGzkl4KZtbRg0GxAktztyDg4pI4bcxXaUNOb",
+ "use": "sig",
+ "crv": "P-384",
+ "kid": "fedtestkeyES384",
+ "x": "uVsAjiFw4Hv0Kcwl2532baUKPTzDht2966ar_pJ8ZdAzquFwJPdRjCfpbkqZUi46",
+ "y": "yp3W3Cmc1QQptLC3s072Iy69l1ubx_WSFRivMYqCpK4Ec89HKvYh3mTKcfjHvk2l"
+}
diff --git a/idp-oidfed-op-impl/src/test/resources/credentials/fed-signing-es521.jwk b/idp-oidfed-op-impl/src/test/resources/credentials/fed-signing-es521.jwk
new file mode 100644
index 0000000..b42d56a
--- /dev/null
+++ b/idp-oidfed-op-impl/src/test/resources/credentials/fed-signing-es521.jwk
@@ -0,0 +1,9 @@
+{
+ "kty": "EC",
+ "d": "ADaJK1sgPtlu4xAFGmb8scq8XGujamVjP3z7Xr4xErwuurSynn8sNtZKX8SfoId9syS27VLFHe12CbeBR6nbReFv",
+ "use": "sig",
+ "crv": "P-521",
+ "kid": "fedtestkeyES512",
+ "x": "AKObj9VTXWndDB7RC9dqSEkEsCqYgOHxq9AgvlDA8XBKxPzp39XrnBD0CMFy0C1HFvoiFKh9lPXJewkkruAOLW-6",
+ "y": "AMG6cRDBekWfD8imLDkBCmm-mtI16mFbifxZ06bgI5GwdyRTIMYUaBizmOzRK038Am4h6EjF8RCFr7383iKcqGZt"
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/test/resources/credentials/fed-signing-rs.jwk b/idp-oidfed-op-impl/src/test/resources/credentials/fed-signing-rs.jwk
new file mode 100644
index 0000000..a6297ee
--- /dev/null
+++ b/idp-oidfed-op-impl/src/test/resources/credentials/fed-signing-rs.jwk
@@ -0,0 +1,8 @@
+{
+ "kty": "RSA",
+ "d": "gv7aqFcXV86jDcCn6-JCqEEIRcv1Rh1AEv4dKziFzQal1nROliDdtkJjELpOYlFY9CgI-xAXt8ivwJ4q1eA_G9WTId7qLxPdcQW4QjfRl8VVEPUhka6Gc8y95WUO4VONEwzZnZ4V7KobE0QGADXvXUw3MtIZdGgvRCS-6avQXITjhTnlkUONxeqpy2BE6l0cI8GSM1vlLy66vjsQ06aAizMB-g3yMMpbKNd73oYgrdpEjAtddH3-sLhv_TG7pMlbB_etnPGkWKdIbpvTKr2P2oZN_8Qvq7G4ETIe9nIv7i8T7GXZfTxWspYkszbrpRACM9Ic8fSctvil2j013JeSgQ",
+ "e": "AQAB",
+ "use": "sig",
+ "kid": "fedtestkeyRS",
+ "n": "pNf03ghVzMAw5sWrwDAMAZdSYNY2q7OVlxMInljMgz8XB5mf8XKH3EtP7AKrb8IAf7rGhfuH3T1N1C7F-jwIeYjXxMm2nIAZ0hXApgbccvBpf4n2H7IZflMjt4A3tt587QQSxQ069drCP4sYevxhTcLplJy6RWA0cLj-5CHyWy94zPeeA4GRd6xgHFLz0RNiSF0pF0kE4rmRgQVZ-b4_BmD9SsWnIpwhms5Ihciw36WyAGQUeZqULGsfwAMwlNLIaTCBLAoRgv370p-XsLrgz86pTkNBJqXP5GwI-ZfgiLmJuHjQ9l85KqHM87f-QdsqiV8KoRcslgXPqb6VOTJBVw"
+}
diff --git a/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/attribute-filter.xml b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/attribute-filter.xml
new file mode 100644
index 0000000..a8e9921
--- /dev/null
+++ b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/attribute-filter.xml
@@ -0,0 +1,188 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ This file is an EXAMPLE policy file. While the policy presented in this
+ example file is illustrative of some simple cases, it relies on the names of
+ non-existent example services and the example attributes demonstrated in the
+ default attribute-resolver.xml file.
+
+ This example does contain some usable "general purpose" policies that may be
+ useful in conjunction with specific deployment choices, but those policies may
+ not be applicable to your specific needs or constraints.
+-->
+<AttributeFilterPolicyGroup id="ShibbolethFilterPolicy"
+ xmlns="urn:mace:shibboleth:2.0:afp"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:oidc="urn:mace:shibboleth:2.0:afp:oidc"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:afp http://shibboleth.net/schema/idp/shibboleth-afp.xsd
+ urn:mace:shibboleth:2.0:afp:oidc http://shibboleth.net/schema/oidc/shibboleth-afp-oidc.xsd">
+
+
+ <!--
+ Example rule relying on a locally applied tag in metadata to trigger attribute
+ release of some specific attributes. Add additional attributes as desired.
+ -->
+ <AttributeFilterPolicy id="Per-Attribute-singleValued">
+ <PolicyRequirementRule xsi:type="ANY" />
+
+ <AttributeRule attributeID="eduPersonPrincipalName">
+ <PermitValueRule xsi:type="EntityAttributeExactMatch"
+ attributeName="http://shibboleth.net/ns/attributes/releaseAllValues"
+ attributeNameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
+ attributeValue="eduPersonPrincipalName" />
+ </AttributeRule>
+
+ <AttributeRule attributeID="mail">
+ <PermitValueRule xsi:type="EntityAttributeExactMatch"
+ attributeName="http://shibboleth.net/ns/attributes/releaseAllValues"
+ attributeNameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
+ attributeValue="mail" />
+ </AttributeRule>
+ </AttributeFilterPolicy>
+
+ <!--
+ Same as above but more efficient form for an attribute with multiple values.
+ -->
+ <AttributeFilterPolicy id="Per-Attribute-Affiliation">
+ <PolicyRequirementRule xsi:type="OR">
+ <Rule xsi:type="EntityAttributeExactMatch"
+ attributeName="http://shibboleth.net/ns/attributes/releaseAllValues"
+ attributeNameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
+ attributeValue="eduPersonScopedAffiliation" />
+ <Rule xsi:type="ProxiedRequesterEntityAttributeExactMatch"
+ attributeName="http://shibboleth.net/ns/attributes/releaseAllValues"
+ attributeNameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
+ attributeValue="eduPersonScopedAffiliation" />
+ </PolicyRequirementRule>
+
+ <AttributeRule attributeID="eduPersonScopedAffiliation" permitAny="true" />
+ </AttributeFilterPolicy>
+
+ <!--
+ Example rule for honoring Subject ID requirement tag in metadata.
+ The example supplies pairwise-id if subject-id isn't explicitly required.
+ -->
+ <AttributeFilterPolicy id="subject-identifiers">
+ <PolicyRequirementRule xsi:type="ANY" />
+
+ <AttributeRule attributeID="samlPairwiseID">
+ <PermitValueRule xsi:type="OR">
+ <Rule xsi:type="EntityAttributeExactMatch"
+ attributeName="urn:oasis:names:tc:SAML:profiles:subject-id:req"
+ attributeNameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
+ attributeValue="pairwise-id" />
+ <Rule xsi:type="EntityAttributeExactMatch"
+ attributeName="urn:oasis:names:tc:SAML:profiles:subject-id:req"
+ attributeNameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
+ attributeValue="any" />
+ </PermitValueRule>
+ </AttributeRule>
+
+ <AttributeRule attributeID="samlSubjectID">
+ <PermitValueRule xsi:type="EntityAttributeExactMatch"
+ attributeName="urn:oasis:names:tc:SAML:profiles:subject-id:req"
+ attributeNameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
+ attributeValue="subject-id" />
+ </AttributeRule>
+ </AttributeFilterPolicy>
+
+ <!-- Release an additional attribute to an SP. -->
+ <AttributeFilterPolicy id="example1">
+ <PolicyRequirementRule xsi:type="Requester" value="https://sp.example.org" />
+
+ <AttributeRule attributeID="uid" permitAny="true" />
+ </AttributeFilterPolicy>
+
+ <!-- Release eduPersonScopedAffiliation to two specific SPs. -->
+ <AttributeFilterPolicy id="example2">
+ <PolicyRequirementRule xsi:type="OR">
+ <Rule xsi:type="Requester" value="https://sp.example.org" />
+ <Rule xsi:type="AND">
+ <Rule xsi:type="OR">
+ <Rule xsi:type="Requester" value="mockClientId" />
+ <Rule xsi:type="Requester" value="policyAcceptedClient1" />
+ <Rule xsi:type="Requester" value="mockSamlClientId" />
+ </Rule>
+ <Rule xsi:type="ProxiedRequester" value="https://rp.example.org" />
+ </Rule>
+ <Rule xsi:type="Requester" value="https://another.example.org/shibboleth" />
+ </PolicyRequirementRule>
+
+ <AttributeRule attributeID="eduPersonScopedAffiliation" permitAny="true" />
+ </AttributeFilterPolicy>
+
+ <AttributeFilterPolicy id="OAUTH_SUBJECT">
+ <PolicyRequirementRule xsi:type="AND">
+ <Rule xsi:type="NOT">
+ <Rule xsi:type="oidc:OIDCScope" value="openid" />
+ </Rule>
+ <Rule xsi:type="Profile" value="http://shibboleth.net/ns/profiles/oidc/sso/browser" />
+ </PolicyRequirementRule>
+ <AttributeRule attributeID="subject">
+ <PermitValueRule xsi:type="ANY" />
+ </AttributeRule>
+ </AttributeFilterPolicy>
+
+ <AttributeFilterPolicy id="OPENID_SCOPE">
+ <PolicyRequirementRule xsi:type="oidc:OIDCScope" value="openid" />
+ <AttributeRule attributeID="subject">
+ <PermitValueRule xsi:type="ANY" />
+ </AttributeRule>
+ </AttributeFilterPolicy>
+
+ <AttributeFilterPolicy id="OPENID_SCOPE_EMAIL">
+ <PolicyRequirementRule xsi:type="oidc:OIDCScope" value="email" />
+ <AttributeRule attributeID="mail">
+ <PermitValueRule xsi:type="ANY" />
+ </AttributeRule>
+ </AttributeFilterPolicy>
+
+ <AttributeFilterPolicy id="OPENID_SCOPE_PROFILE">
+ <PolicyRequirementRule xsi:type="oidc:OIDCScope" value="profile" />
+ <AttributeRule attributeID="subject">
+ <PermitValueRule xsi:type="ANY" />
+ </AttributeRule>
+ <AttributeRule attributeID="name">
+ <PermitValueRule xsi:type="ANY" />
+ </AttributeRule>
+ <AttributeRule attributeID="family_name">
+ <PermitValueRule xsi:type="ANY" />
+ </AttributeRule>
+ <AttributeRule attributeID="given_name">
+ <PermitValueRule xsi:type="ANY" />
+ </AttributeRule>
+ <AttributeRule attributeID="middle_name">
+ <PermitValueRule xsi:type="ANY" />
+ </AttributeRule>
+ <AttributeRule attributeID="nickname">
+ <PermitValueRule xsi:type="ANY" />
+ </AttributeRule>
+ <AttributeRule attributeID="preferred_username">
+ <PermitValueRule xsi:type="ANY" />
+ </AttributeRule>
+ <AttributeRule attributeID="profile">
+ <PermitValueRule xsi:type="ANY" />
+ </AttributeRule>
+ <AttributeRule attributeID="picture">
+ <PermitValueRule xsi:type="ANY" />
+ </AttributeRule>
+ <AttributeRule attributeID="website">
+ <PermitValueRule xsi:type="ANY" />
+ </AttributeRule>
+ <AttributeRule attributeID="gender">
+ <PermitValueRule xsi:type="ANY" />
+ </AttributeRule>
+ <AttributeRule attributeID="birthdate">
+ <PermitValueRule xsi:type="ANY" />
+ </AttributeRule>
+ <AttributeRule attributeID="zoneinfo">
+ <PermitValueRule xsi:type="ANY" />
+ </AttributeRule>
+ <AttributeRule attributeID="locale">
+ <PermitValueRule xsi:type="ANY" />
+ </AttributeRule>
+ <AttributeRule attributeID="updated_at">
+ <PermitValueRule xsi:type="ANY" />
+ </AttributeRule>
+ </AttributeFilterPolicy>
+
+</AttributeFilterPolicyGroup>
diff --git a/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/attribute-registry.xml b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/attribute-registry.xml
new file mode 100644
index 0000000..2733f86
--- /dev/null
+++ b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/attribute-registry.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:util="http://www.springframework.org/schema/util"
+ xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:c="http://www.springframework.org/schema/c"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
+ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
+
+ default-init-method="initialize"
+ default-destroy-method="destroy">
+
+ <!--
+ The system comes preconfigured to load rules directly from resource files
+ configured in services.xml so they're monitored for changes.
+
+ You can add mappings here, add more XML resource files, or drop property
+ files into the directory noted below, but they won't be monitored for changes
+ themselves.
+ -->
+
+ <!-- Default directory for custom mappings. -->
+ <bean parent="shibboleth.TranscodingRuleLoader"
+ c:dir="%{idp.home}/conf/attributes/custom"
+ c:extensions="#{{'.txt', '.props', '.properties', '.rule'}}" />
+</beans>
diff --git a/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/attribute-resolver.xml b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/attribute-resolver.xml
new file mode 100644
index 0000000..d621a2f
--- /dev/null
+++ b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/attribute-resolver.xml
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ This file is an EXAMPLE configuration file. While the configuration
+ presented in this example file is semi-functional, it isn't very
+ interesting. It is here only as a starting point for your deployment
+ process.
+
+ Very few attribute definitions and data connectors are demonstrated,
+ and the data is derived statically from the logged-in username and a
+ static example connector.
+
+ Attribute-resolver-full.xml contains more examples of attributes,
+ encoders, and data connectors. Deployers should refer to the Shibboleth
+ documentation for a complete list of components and their options.
+-->
+<AttributeResolver
+ xmlns="urn:mace:shibboleth:2.0:resolver"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:oidc="urn:mace:shibboleth:2.0:resolver:oidc"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:resolver http://shibboleth.net/schema/idp/shibboleth-attribute-resolver.xsd
+ urn:mace:shibboleth:2.0:resolver:oidc http://shibboleth.net/schema/oidc/shibboleth-attribute-encoder-oidc.xsd">
+
+
+ <!-- ========================================== -->
+ <!-- Attribute Definitions -->
+ <!-- ========================================== -->
+
+ <!--
+ The EPPN is the "standard" federated username in higher ed.
+ For guidelines on the implementation of this attribute, refer
+ to the Shibboleth and eduPerson documentation. Above all, do
+ not expose a value for this attribute without considering the
+ long term implications.
+ -->
+ <AttributeDefinition id="eduPersonPrincipalName" xsi:type="Scoped" scope="%{idp.scope}">
+ <InputAttributeDefinition ref="uid" />
+ <AttributeEncoder xsi:type="oidc:OIDCScopedString" name="eppn" />
+ </AttributeDefinition>
+
+ <!--
+ The uid is the closest thing to a "standard" LDAP attribute
+ representing a local username, but you should generally *never*
+ expose uid to federated services, as it is rarely globally unique.
+ -->
+ <AttributeDefinition id="uid" xsi:type="PrincipalName" />
+
+ <!--
+ In the rest of the world, the email address is the standard identifier,
+ despite the problems with that practice. Consider making the EPPN
+ value the same as your official email addresses whenever possible.
+ -->
+ <AttributeDefinition id="mail" xsi:type="Template">
+ <InputAttributeDefinition ref="uid" />
+ <Template>
+ <![CDATA[
+ ${uid}@example.org
+ ]]>
+ </Template>
+ </AttributeDefinition>
+
+ <!--
+ This is an example of an attribute sourced from a data connector.
+ -->
+ <AttributeDefinition id="eduPersonScopedAffiliation" xsi:type="Scoped" scope="%{idp.scope}">
+ <InputDataConnector ref="staticAttributes" attributeNames="affiliation" />
+ <AttributeEncoder xsi:type="oidc:OIDCScopedString" />
+ </AttributeDefinition>
+
+ <!-- Subject Identifier is a attribute that must always be resolved.
+ There has to be exactly one resolved and filtered attribute that would be encoded as 'sub'.
+ This example attribute (the data connector actually ) will generate public or pairwise 'sub'
+ depending on client registration data.
+ -->
+ <AttributeDefinition id="subject" xsi:type="Simple" activationConditionRef="shibboleth.oidc.Conditions.SubjectRequired">
+ <InputDataConnector ref="computedSubjectId" attributeNames="subjectId"/>
+ <AttributeEncoder xsi:type="oidc:OIDCString" name="sub" />
+ </AttributeDefinition>
+
+ <AttributeDefinition id="customRevocation" xsi:type="DateTime" epochInSeconds="false" resolutionPhases="oauth2/tokenRevocation">
+ <InputAttributeDefinition ref="revocationTime"/>
+ </AttributeDefinition>
+
+ <AttributeDefinition id="revocationTime" xsi:type="ScriptedAttribute" dependencyOnly="true"
+ resolutionPhases="oauth2/tokenRevocation" customObjectRef="shibboleth.RelyingPartyIdLookup.Simple">
+ <InputAttributeDefinition ref="uid" />
+ <Script><![CDATA[
+ if (custom.apply(profileContext).equals('mockClientIdActivateRevocationCondition')) {
+ revocationTime.addValue((new Date().getTime() + 3600000).toString());
+ }
+ ]]>
+ </Script>
+ </AttributeDefinition>
+
+ <!-- ========================================== -->
+ <!-- Data Connectors -->
+ <!-- ========================================== -->
+
+ <DataConnector id="staticAttributes" xsi:type="Static">
+ <Attribute id="affiliation">
+ <Value>member</Value>
+ </Attribute>
+ </DataConnector>
+
+ <DataConnector id="computedSubjectId" xsi:type="ComputedId"
+ generatedAttributeID="subjectId"
+ salt="%{idp.oidc.subject.salt}"
+ algorithm="%{idp.oidc.subject.algorithm:SHA}"
+ encoding="BASE32">
+ <InputAttributeDefinition ref="%{idp.oidc.subject.sourceAttribute}"/>
+ </DataConnector>
+</AttributeResolver>
diff --git a/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/attributes/custom/mail.properties b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/attributes/custom/mail.properties
new file mode 100644
index 0000000..ab79bf6
--- /dev/null
+++ b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/attributes/custom/mail.properties
@@ -0,0 +1,4 @@
+id=mail
+transcoder=OIDCStringTranscoder
+oidc.name=email
+oidc.nameFromSamlMetadata=true
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/authn/oauth2client-authn-config.xml b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/authn/oauth2client-authn-config.xml
new file mode 100644
index 0000000..032594b
--- /dev/null
+++ b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/authn/oauth2client-authn-config.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:util="http://www.springframework.org/schema/util"
+ xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:c="http://www.springframework.org/schema/c"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
+ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
+
+ default-init-method="initialize"
+ default-destroy-method="destroy">
+
+ <!-- Ordered list of CredentialValidators to apply to a request. -->
+ <util:list id="shibboleth.authn.OAuth2Client.Validators">
+ <ref bean="shibboleth.OIDCClientInfoValidator" />
+ <ref bean="shibboleth.JWTValidator" />
+ <bean parent="shibboleth.HTPasswdValidator">
+ <property name="resource">
+ <bean class="net.shibboleth.shared.spring.resource.ConditionalResource">
+ <constructor-arg>
+ <bean class="org.springframework.core.io.ClassPathResource" c:path="/credentials/htpasswd.txt" />
+ </constructor-arg>
+ </bean>
+ </property>
+ </bean>
+ </util:list>
+
+</beans>
diff --git a/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/credentials.xml b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/credentials.xml
new file mode 100644
index 0000000..122a9d1
--- /dev/null
+++ b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/credentials.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:util="http://www.springframework.org/schema/util"
+ xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:c="http://www.springframework.org/schema/c"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
+ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
+
+ default-init-method="initialize"
+ default-destroy-method="destroy">
+
+ <import resource="oidc-credentials.xml" />
+
+ <!--
+ NOTE: if you're using a legacy relying-party.xml file from a V2 configuration, this file is ignored.
+
+ This defines the signing and encryption key and certificate pairs referenced by your relying-party.xml
+ configuration. You don't normally need to touch this, unless you have advanced requirements such as
+ supporting multiple sets of keys for different relying parties, in which case you may want to define
+ all your credentials here for convenience.
+ -->
+
+ <!--
+ The list of ALL of your IdP's signing credentials. If you define additional signing credentials,
+ for example for specific relying parties or different key types, make sure to include them within this list.
+ -->
+ <util:list id="shibboleth.SigningCredentials">
+ <ref bean="shibboleth.DefaultSigningCredential" />
+ </util:list>
+
+ <!-- Your IdP's default signing key, set via property file. -->
+ <bean id="shibboleth.DefaultSigningCredential"
+ class="net.shibboleth.idp.profile.spring.factory.BasicX509CredentialFactoryBean"
+ p:privateKeyResource="%{idp.signing.key}"
+ p:certificateResource="%{idp.signing.cert}"
+ p:entityId-ref="entityID" />
+
+ <!-- Your IdP's default client TLS credential, by default the same as the default signing credential. -->
+ <alias alias="shibboleth.DefaultClientTLSCredential" name="shibboleth.DefaultSigningCredential" />
+
+ <!--
+ The list of ALL of your IdP's encryption credentials. By default this is just an alias
+ for 'shibboleth.DefaultEncryptionCredentials'. It could be re-defined as
+ a list with additional credentials if needed.
+ -->
+ <alias alias="shibboleth.EncryptionCredentials" name="shibboleth.DefaultEncryptionCredentials" />
+
+ <!-- Your IdP's default encryption (really decryption) keys, set via property file. -->
+ <util:list id="shibboleth.DefaultEncryptionCredentials">
+ <bean class="net.shibboleth.idp.profile.spring.factory.BasicX509CredentialFactoryBean"
+ p:privateKeyResource="%{idp.encryption.key}"
+ p:certificateResource="%{idp.encryption.cert}"
+ p:entityId-ref="entityID" />
+
+ <!--
+ For key rollover, uncomment and point to your original keypair, and use the one above
+ to point to your new keypair. Once metadata has propagated, comment this one out again.
+ -->
+ <!--
+ <bean class="net.shibboleth.idp.profile.spring.factory.BasicX509CredentialFactoryBean"
+ p:privateKeyResource="%{idp.encryption.key.2}"
+ p:certificateResource="%{idp.encryption.cert.2}"
+ p:entityId-ref="entityID" />
+ -->
+ </util:list>
+
+</beans>
diff --git a/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/global.xml b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/global.xml
new file mode 100644
index 0000000..e11b63a
--- /dev/null
+++ b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/global.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:util="http://www.springframework.org/schema/util"
+ xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:c="http://www.springframework.org/schema/c"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
+ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
+
+ default-init-method="initialize"
+ default-destroy-method="destroy">
+
+ <bean id="CustomTokenRevocationCondition" parent="shibboleth.BiConditions.Expression"
+ c:expression="#custom.test(#input1, #input2)">
+ <property name="customObject">
+ <ref bean="shibboleth.oauth2.AttributeTokenRevocationCondition"/>
+ </property>
+ </bean>
+
+ <util:list id="shibboleth.oidc.ClientSecretValueResolvers">
+ <bean parent="shibboleth.oidc.PropertiesClientSecretValueResolver"
+ p:resource="classpath:/net/shibboleth/idp/oidc/metadata/impl/client-secret-test.properties" />
+ </util:list>
+
+ <bean id="exampleMetadata-saml-oidc-clientsecret" class="org.springframework.core.io.ClassPathResource">
+ <constructor-arg value="/net/shibboleth/idp/oidc/metadata/impl/EntityDescriptor-with-oidcmd-clientsecret.xml"/>
+ </bean>
+
+ <bean id="exampleMetadata-saml-oauth2-resource" class="org.springframework.core.io.ClassPathResource">
+ <constructor-arg value="/net/shibboleth/idp/oidc/metadata/impl/EntityDescriptor-with-oauth2-resource.xml"/>
+ </bean>
+
+ <util:set id="testbed.MetadataIndexes">
+ <bean class="org.opensaml.saml.metadata.resolver.index.impl.SAMLArtifactMetadataIndex" />
+ </util:set>
+
+
+ <util:list id="testbed.MetadataResolverResources">
+ <value>%{idp.home}/conf/metadata-providers.xml</value>
+ <value>%{idp.home}/conf/metadata-filters.xml</value>
+ </util:list>
+
+ <!-- Copy of IdP signing key for tests. -->
+<!--
+ <bean id="testbed.DefaultRSSigningCredential" parent="shibboleth.JWKCredential"
+ p:resource="%{idp.signing.oidc.rs.key}" />
+-->
+ <bean id="CustomConfigurationValues" parent="shibboleth.oidc.discovery.DefaultDynamicValueResolvers"
+ class="org.springframework.beans.factory.config.MapFactoryBean">
+ <property name="sourceMap">
+ <map merge="true">
+ <entry key="STATIC_TEST_ATTRIBUTE">
+ <bean parent="shibboleth.oidc.discovery.FunctionMetadataValueResolver">
+ <property name="resolverFunction">
+ <bean parent="shibboleth.Functions.Constant" c:target="TestValue"/>
+ </property>
+ </bean>
+ </entry>
+ </map>
+ </property>
+ </bean>
+
+ <bean id="CustomEntityConfigurationValues" parent="shibboleth.oidfed.configuration.DefaultDynamicValueResolvers"
+ class="org.springframework.beans.factory.config.MapFactoryBean">
+ <property name="sourceMap">
+ <map merge="true">
+ <entry key="STATIC_CONF_ATTRIBUTE">
+ <bean parent="shibboleth.oidc.discovery.FunctionMetadataValueResolver">
+ <property name="resolverFunction">
+ <bean parent="shibboleth.Functions.Constant" c:target="TestAttributeValue"/>
+ </property>
+ </bean>
+ </entry>
+ </map>
+ </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" />
+
+ <bean id="MockitoMockFactory" class="org.mockito.Mockito" />
+
+ <bean id="shibboleth.oidfed.HttpClient"
+ factory-bean="MockitoMockFactory"
+ factory-method="mock">
+ <constructor-arg value="#{T(org.apache.hc.client5.http.classic.HttpClient)}" />
+ </bean>
+
+</beans>
diff --git a/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/idp.properties b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/idp.properties
new file mode 100644
index 0000000..d78cd53
--- /dev/null
+++ b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/idp.properties
@@ -0,0 +1,209 @@
+# Auto-load all files matching conf/**/*.properties
+# Disable if you want to manually maintain a list of sources.
+#idp.searchForProperties = false
+
+# Load any additional property resources from a comma-delimited list
+idp.additionalProperties = /conf/ldap.properties, \
+ /conf/saml-nameid.properties, \
+ /conf/services.properties, \
+ /conf/admin/admin.properties, \
+ /conf/authn/authn.properties, \
+ /conf/authn/duo.properties, \
+ /conf/oidc.properties, \
+ /credentials/secrets.properties
+
+# In most cases (and unless noted in the surrounding comments) the
+# commented settings in the distributed files are the default
+# behavior for V3. Uncomment them and change the value to change
+# functionality.
+#
+# Uncommented properties are either required or ship non-defaulted.
+
+# Set the entityID of the IdP
+idp.entityID = https://idp.example.org
+
+# Set the file path which backs the IdP's own metadata publishing endpoint at /shibboleth.
+# Set to empty value to disable and return a 404.
+#idp.entityID.metadataFile=%{idp.home}/metadata/idp-metadata.xml
+
+# Set the scope used in the attribute resolver for scoped attributes
+idp.scope = example.org
+
+# General cookie properties (maxAge only applies to persistent cookies)
+# Note the default for idp.cookie.secure, you will usually want it set.
+#idp.cookie.secure = false
+#idp.cookie.httpOnly = true
+#idp.cookie.domain =
+#idp.cookie.path =
+#idp.cookie.maxAge = 31536000
+
+# HSTS/CSP response headers
+#idp.hsts = max-age=0
+# X-Frame-Options value, set to DENY or SAMEORIGIN to block framing
+#idp.frameoptions = DENY
+# Content-Security-Policy value, set to match X-Frame-Options default
+#idp.csp = frame-ancestors 'none';
+
+# Set the location of user-supplied web flow definitions
+#idp.webflows = %{idp.home}/flows
+
+# Set the location of Velocity view templates
+#idp.views = %{idp.home}/views
+
+# Settings for internal AES encryption key
+#idp.sealer.storeType = JCEKS
+#idp.sealer.updateInterval = PT15M
+#idp.sealer.aliasBase = secret
+idp.sealer.storeResource = %{idp.home}/credentials/sealer.jks
+idp.sealer.versionResource = %{idp.home}/credentials/sealer.kver
+idp.sealer.storePassword = password
+idp.sealer.keyPassword = password
+
+# Settings for public/private signing and encryption key(s)
+# During decryption key rollover, point the ".2" properties at a second
+# keypair, uncomment in credentials.xml, then publish it in your metadata.
+idp.signing.key = %{idp.home}/credentials/idp-signing.key
+idp.signing.cert = %{idp.home}/credentials/idp-signing.crt
+idp.encryption.key = %{idp.home}/credentials/idp-encryption.key
+idp.encryption.cert = %{idp.home}/credentials/idp-encryption.crt
+#idp.encryption.key.2 = %{idp.home}/credentials/idp-encryption-old.key
+#idp.encryption.cert.2 = %{idp.home}/credentials/idp-encryption-old.crt
+
+# Sets the bean ID to use as a default security configuration set
+#idp.security.config = shibboleth.DefaultSecurityConfiguration
+
+# To downgrade to SHA-1, set to shibboleth.SigningConfiguration.SHA1
+#idp.signing.config = shibboleth.SigningConfiguration.SHA256
+
+# To upgrade to AES-GCM encryption, set to shibboleth.EncryptionConfiguration.GCM
+# This is unlikely to work for all SPs, but this is a quick way to test them.
+#idp.encryption.config = shibboleth.EncryptionConfiguration.CBC
+
+# Configures trust evaluation of keys used by services at runtime
+# Defaults to supporting both explicit key and PKIX using SAML metadata.
+#idp.trust.signatures = shibboleth.ChainingSignatureTrustEngine
+# To pick only one set to one of:
+# shibboleth.ExplicitKeySignatureTrustEngine, shibboleth.PKIXSignatureTrustEngine
+#idp.trust.certificates = shibboleth.ChainingX509TrustEngine
+# To pick only one set to one of:
+# shibboleth.ExplicitKeyX509TrustEngine, shibboleth.PKIXX509TrustEngine
+
+# If true, encryption will happen whenever a key to use can be located, but
+# failure to encrypt won't result in request failure.
+#idp.encryption.optional = false
+
+# Configuration of client- and server-side storage plugins
+#idp.storage.cleanupInterval = PT10M
+idp.storage.htmlLocalStorage = true
+
+# Set to true to expose more detailed errors in responses to SPs
+#idp.errors.detailed = false
+# Set to false to skip signing of SAML response messages that signal errors
+#idp.errors.signed = true
+# Name of bean containing a list of Java exception classes to ignore
+#idp.errors.excludedExceptions = ExceptionClassListBean
+# Name of bean containing a property set mapping exception names to views
+#idp.errors.exceptionMappings = ExceptionToViewPropertyBean
+# Set if a different default view name for events and exceptions is needed
+#idp.errors.defaultView = error
+
+# Set to false to disable the IdP session layer
+#idp.session.enabled = true
+
+# Set to "shibboleth.StorageService" for server-side storage of user sessions
+idp.session.StorageService = shibboleth.StorageService
+
+# Size of session IDs
+#idp.session.idSize = 32
+# Bind sessions to IP addresses
+#idp.session.consistentAddress = true
+# Inactivity timeout
+#idp.session.timeout = PT60M
+# Extra time to store sessions for logout
+#idp.session.slop = PT0S
+# Tolerate storage-related errors
+#idp.session.maskStorageFailure = false
+# Track information about SPs logged into
+idp.session.trackSPSessions = true
+# Support lookup by SP for SAML logout
+idp.session.secondaryServiceIndex = true
+# Length of time to track SP sessions
+#idp.session.defaultSPlifetime = PT2H
+
+# Set to "shibboleth.StorageService" or custom bean for alternate storage of consent
+#idp.consent.StorageService = shibboleth.ClientPersistentStorageService
+idp.consent.StorageService = shibboleth.StorageService
+
+# Set to "shibboleth.consent.AttributeConsentStorageKey" to use an attribute
+# to key user consent storage records (and set the attribute name)
+#idp.consent.attribute-release.userStorageKey = shibboleth.consent.PrincipalConsentStorageKey
+#idp.consent.attribute-release.userStorageKeyAttribute = uid
+#idp.consent.terms-of-use.userStorageKey = shibboleth.consent.PrincipalConsentStorageKey
+#idp.consent.terms-of-use.userStorageKeyAttribute = uid
+
+# Suffix of message property used as value of consent storage records when idp.consent.compareValues is true.
+# Defaults to text displayed to the user.
+#idp.consent.terms-of-use.consentValueMessageCodeSuffix = .text
+
+# Flags controlling how built-in attribute consent feature operates
+#idp.consent.allowDoNotRemember = true
+#idp.consent.allowGlobal = true
+#idp.consent.allowPerAttribute = false
+
+# Whether attribute values and terms of use text are compared
+#idp.consent.compareValues = false
+# Maximum number of consent records for space-limited storage (e.g. cookies)
+#idp.consent.maxStoredRecords = 10
+# Maximum number of consent records for larger/server-side storage (0 = no limit)
+#idp.consent.expandedMaxStoredRecords = 0
+
+# Time in milliseconds to expire consent storage records.
+#idp.consent.storageRecordLifetime = P1Y
+
+# Whether to lookup metadata, etc. for every SP involved in a logout
+# for use by user interface logic; adds overhead so off by default.
+#idp.logout.elaboration = false
+
+# Whether to require logout requests/responses be signed/authenticated.
+#idp.logout.authenticated = true
+
+# Bean to determine whether user should be allowed to cancel logout
+#idp.logout.promptUser=shibboleth.Conditions.FALSE
+
+# Message freshness and replay cache tuning
+#idp.policy.messageLifetime = PT3M
+#idp.policy.clockSkew = PT3M
+
+# Set to custom bean for alternate storage of replay cache
+#idp.replayCache.StorageService = shibboleth.StorageService
+#idp.replayCache.strict = true
+
+# Toggles whether to allow outbound messages via SAML artifact
+#idp.artifact.enabled = true
+# Suppresses typical signing/encryption when artifact binding used
+#idp.artifact.secureChannel = true
+# May differ to direct SAML 2 artifact lookups to specific server nodes
+#idp.artifact.endpointIndex = 2
+# Set to custom bean for alternate storage of artifact map state
+#idp.artifact.StorageService = shibboleth.StorageService
+
+# Comma-delimited languages to use if not match can be found with the
+# browser-supported languages, defaults to an empty list.
+idp.ui.fallbackLanguages=en,fr,de
+
+# Storage service used by CAS protocol
+# Defaults to shibboleth.StorageService (in-memory)
+# MUST be server-side storage (e.g. in-memory, memcached, database)
+# NOTE that idp.session.StorageService requires server-side storage
+# when CAS protocol is enabled
+#idp.cas.StorageService=shibboleth.StorageService
+
+# CAS service registry implementation class
+#idp.cas.serviceRegistryClass=net.shibboleth.idp.cas.service.PatternServiceRegistry
+
+# F-TICKS auditing - set a salt to include hashed username
+#idp.fticks.federation=MyFederation
+#idp.fticks.algorithm=SHA-256
+#idp.fticks.salt=somethingsecret
+#idp.fticks.loghost=localhost
+#idp.fticks.logport=514
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/logback.xml b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/logback.xml
new file mode 100644
index 0000000..2e38cbb
--- /dev/null
+++ b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/logback.xml
@@ -0,0 +1,197 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+
+ <!--
+ Variables for simplifying logging configuration.
+ http://logback.qos.ch/manual/configuration.html#variableSubstitution
+ -->
+
+ <!--
+ If you want to use custom properties in this config file,
+ we load the main property file for you.
+ -->
+ <variable file="src/test/resources/conf/local-log-config.properties" />
+
+ <!-- Location and retention. -->
+
+ <variable name="idp.logfiles" value="${idp.logfiles:-${idp.home}/logs}" />
+ <variable name="idp.loghistory" value="${idp.loghistory:-180}" />
+
+ <!-- Much higher performance if you operate on DEBUG. -->
+ <!-- <variable name="idp.process.appender" value="ASYNC_PROCESS" /> -->
+
+ <!-- Logging level shortcuts. -->
+ <variable name="idp.loglevel.idp" value="${idp.loglevel.idp:-OFF}" />
+ <variable name="idp.loglevel.ldap" value="${idp.loglevel.ldap:-OFF}" />
+ <variable name="idp.loglevel.messages" value="${idp.loglevel.messages:-OFF}" />
+ <variable name="idp.loglevel.encryption" value="${idp.loglevel.encryption:-OFF}" />
+ <variable name="idp.loglevel.opensaml" value="${idp.loglevel.opensaml:-OFF}" />
+ <variable name="idp.loglevel.props" value="${idp.loglevel.props:-OFF}" />
+ <variable name="idp.loglevel.httpclient" value="${idp.loglevel.httpclient:-OFF}" />
+
+ <variable name="idp.loglevel.oidc" value="${idp.loglevel.oidc:-OFF}" />
+ <variable name="idp.loglevel.oidc-op" value="${idp.loglevel.oidc-op:-OFF}" />
+
+ <!-- Don't turn these up unless you want a *lot* of noise. -->
+ <variable name="idp.loglevel.spring" value="${idp.loglevel.spring:-OFF}" />
+ <variable name="idp.loglevel.container" value="${idp.loglevel.container:-OFF}" />
+ <variable name="idp.loglevel.xmlsec" value="${idp.loglevel.xmlsec:-OFF}" />
+
+ <!-- =========================================================== -->
+ <!-- ============== Logging Categories and Levels ============== -->
+ <!-- =========================================================== -->
+
+ <!-- Logs IdP, but not OpenSAML, messages -->
+ <logger name="net.shibboleth" level="${idp.loglevel.idp}"/>
+ <logger name="net.shibboleth.oidc" level="${idp.loglevel.oidc}"/>
+ <logger name="net.shibboleth.idp.plugin.oidc.op" level="${idp.loglevel.oidc-op}"/>
+
+ <!-- Logs OpenSAML, but not IdP, messages -->
+ <logger name="org.opensaml.saml" level="${idp.loglevel.opensaml}"/>
+
+ <!-- Logs LDAP related messages -->
+ <logger name="org.ldaptive" level="${idp.loglevel.ldap}"/>
+
+ <!-- Logs embedded HTTP client messages -->
+ <logger name="org.apache.http" level="${idp.loglevel.httpclient}"/>
+
+ <!-- Logs inbound and outbound protocols messages at DEBUG level -->
+ <logger name="PROTOCOL_MESSAGE" level="${idp.loglevel.messages}" />
+
+ <!-- Logs unencrypted SAML at DEBUG level -->
+ <logger name="org.opensaml.saml.saml2.encryption.Encrypter" level="${idp.loglevel.encryption}" />
+ <logger name="org.opensaml.saml.saml2.encryption.Decrypter" level="${idp.loglevel.encryption}" />
+
+ <!-- Logs system properties during startup at DEBUG level -->
+ <logger name="net.shibboleth.idp.log.LogbackLoggingService" level="${idp.loglevel.props}" />
+
+ <!-- Especially chatty. -->
+ <logger name="org.apache.xml.security" level="${idp.loglevel.xmlsec}" />
+ <logger name="org.springframework" level="${idp.loglevel.spring}"/>
+ <logger name="org.apache.catalina" level="${idp.loglevel.container}"/>
+ <logger name="org.eclipse.jetty" level="${idp.loglevel.container}"/>
+
+
+ <!-- =========================================================== -->
+ <!-- ============== Low Level Details or Changes =============== -->
+ <!-- =========================================================== -->
+
+ <!-- Process log. -->
+ <appender name="IDP_PROCESS" class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <File>${idp.logfiles}/idp-process.log</File>
+
+ <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+ <fileNamePattern>${idp.logfiles}/idp-process-%d{yyyy-MM-dd}.log.gz</fileNamePattern>
+ <maxHistory>${idp.loghistory}</maxHistory>
+ </rollingPolicy>
+
+ <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+ <charset>UTF-8</charset>
+ <Pattern>%date{ISO8601} - %mdc{idp.remote_addr} - %level [%logger:%line] - %msg%n%ex{short}</Pattern>
+ </encoder>
+
+ <!-- Ignore Velocity status page error. -->
+ <filter class="ch.qos.logback.core.filter.EvaluatorFilter">
+ <evaluator>
+ <matcher>
+ <Name>VelocityStatusMatcher</Name>
+ <regex>ResourceManager\s*: unable to find resource 'status\.vm' in any resource loader\.</regex>
+ </matcher>
+ <expression>VelocityStatusMatcher.matches(formattedMessage)</expression>
+ </evaluator>
+ <OnMatch>DENY</OnMatch>
+ </filter>
+ </appender>
+
+ <appender name="ASYNC_PROCESS" class="ch.qos.logback.classic.AsyncAppender">
+ <appender-ref ref="IDP_PROCESS" />
+ <discardingThreshold>0</discardingThreshold>
+ </appender>
+
+ <appender name="IDP_WARN" class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <!-- Suppress anything below WARN. -->
+ <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+ <level>WARN</level>
+ </filter>
+
+ <File>${idp.logfiles}/idp-warn.log</File>
+
+ <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+ <fileNamePattern>${idp.logfiles}/idp-warn-%d{yyyy-MM-dd}.log.gz</fileNamePattern>
+ <maxHistory>${idp.loghistory}</maxHistory>
+ </rollingPolicy>
+
+ <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+ <charset>UTF-8</charset>
+ <Pattern>%date{ISO8601} - %mdc{idp.remote_addr} - %level [%logger:%line] - %msg%n%ex{full}</Pattern>
+ </encoder>
+
+ <!-- Ignore Velocity status page error. -->
+ <filter class="ch.qos.logback.core.filter.EvaluatorFilter">
+ <evaluator>
+ <matcher>
+ <Name>VelocityStatusMatcher</Name>
+ <regex>ResourceManager\s*: unable to find resource 'status\.vm' in any resource loader\.</regex>
+ </matcher>
+ <expression>VelocityStatusMatcher.matches(formattedMessage)</expression>
+ </evaluator>
+ <OnMatch>DENY</OnMatch>
+ </filter>
+ </appender>
+
+ <!-- Audit log. -->
+ <appender name="IDP_AUDIT" class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <File>${idp.logfiles}/idp-audit.log</File>
+
+ <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+ <fileNamePattern>${idp.logfiles}/idp-audit-%d{yyyy-MM-dd}.log.gz</fileNamePattern>
+ <maxHistory>${idp.loghistory}</maxHistory>
+ </rollingPolicy>
+
+ <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+ <charset>UTF-8</charset>
+ <Pattern>%msg%n</Pattern>
+ </encoder>
+ </appender>
+
+ <!-- Consent audit log. -->
+ <appender name="IDP_CONSENT_AUDIT" class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <File>${idp.logfiles}/idp-consent-audit.log</File>
+
+ <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+ <fileNamePattern>${idp.logfiles}/idp-consent-audit-%d{yyyy-MM-dd}.log.gz</fileNamePattern>
+ <maxHistory>${idp.loghistory}</maxHistory>
+ </rollingPolicy>
+
+ <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+ <charset>UTF-8</charset>
+ <Pattern>%msg%n</Pattern>
+ </encoder>
+ </appender>
+
+ <!-- F-TICKS syslog destination. -->
+ <appender name="IDP_FTICKS" class="ch.qos.logback.classic.net.SyslogAppender">
+ <syslogHost>${idp.fticks.loghost:-localhost}</syslogHost>
+ <port>${idp.fticks.logport:-514}</port>
+ <facility>AUTH</facility>
+ <suffixPattern>[%thread] %logger %msg</suffixPattern>
+ </appender>
+
+ <logger name="Shibboleth-Audit" level="${idp.loglevel.audit:-OFF}">
+ <appender-ref ref="${idp.audit.appender:-IDP_AUDIT}"/>
+ </logger>
+
+ <logger name="Shibboleth-FTICKS" level="${idp.loglevel.fticks:-OFF}" additivity="false">
+ <appender-ref ref="${idp.fticks.appender:-IDP_FTICKS}"/>
+ </logger>
+
+ <logger name="Shibboleth-Consent-Audit" level="${idp.loglevel.consent-audit:-OFF}">
+ <appender-ref ref="${idp.consent.appender:-IDP_CONSENT_AUDIT}"/>
+ </logger>
+
+ <root level="${idp.loglevel.root:-OFF}">
+ <appender-ref ref="${idp.process.appender:-IDP_PROCESS}"/>
+ <appender-ref ref="${idp.warn.appender:-IDP_WARN}" />
+ </root>
+
+</configuration>
diff --git a/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/metadata-policy1.json b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/metadata-policy1.json
new file mode 100644
index 0000000..71276cd
--- /dev/null
+++ b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/metadata-policy1.json
@@ -0,0 +1,21 @@
+{
+ "grant_types": {
+ "one_of": ["authorization_code","implicit"]
+ },
+ "client_name": {
+ "default": "A known test application"
+ },
+ "organization_name": {
+ "value": "A trusted organization"
+ },
+ "redirect_uris": {
+ "regexp": "^https:\/\/(?:([^.]+).)?example.org\/(.*)",
+ "essential": true
+ },
+ "id_token_signed_response_alg": {
+ "subset_of": ["RS256", "RS384", "RS512"]
+ },
+ "scope": {
+ "subset_of": ["openid", "profile", "email", "phone"]
+ }
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/metadata-providers.xml b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/metadata-providers.xml
new file mode 100644
index 0000000..3b78e27
--- /dev/null
+++ b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/metadata-providers.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- This file is an EXAMPLE metadata configuration file. -->
+<MetadataProvider id="ShibbolethMetadata" xsi:type="ChainingMetadataProvider"
+ xmlns="urn:mace:shibboleth:2.0:metadata" xmlns:resource="urn:mace:shibboleth:2.0:resource"
+ xmlns:security="urn:mace:shibboleth:2.0:security"
+ xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
+ xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:metadata http://shibboleth.net/schema/idp/shibboleth-metadata.xsd
+ urn:mace:shibboleth:2.0:resource http://shibboleth.net/schema/idp/shibboleth-resource.xsd
+ urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd
+ urn:oasis:names:tc:SAML:2.0:assertion http://docs.oasis-open.org/security/saml/v2.0/saml-schema-assertion-2.0.xsd
+ urn:oasis:names:tc:SAML:2.0:metadata http://docs.oasis-open.org/security/saml/v2.0/saml-schema-metadata-2.0.xsd">
+
+ <!-- ========================================== -->
+ <!-- Metadata Configuration -->
+ <!-- ========================================== -->
+
+ <MetadataProvider id="SP1MD" xsi:type="ResourceBackedMetadataProvider"
+ maxRefreshDelay="PT5M" indexesRef="testbed.MetadataIndexes"
+ resourceRef="exampleMetadata-saml-oidc-clientsecret" />
+
+ <MetadataProvider id="SP2MD" xsi:type="ResourceBackedMetadataProvider"
+ maxRefreshDelay="PT5M" indexesRef="testbed.MetadataIndexes"
+ resourceRef="exampleMetadata-saml-oauth2-resource" />
+
+</MetadataProvider>
diff --git a/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/oidc-clientinfo-resolvers.xml b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/oidc-clientinfo-resolvers.xml
new file mode 100644
index 0000000..b181076
--- /dev/null
+++ b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/oidc-clientinfo-resolvers.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:util="http://www.springframework.org/schema/util"
+ xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:c="http://www.springframework.org/schema/c"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
+ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
+
+ default-init-method="initialize"
+ default-destroy-method="destroy">
+
+ <util:list id="shibboleth.oidc.ClientInformationResolvers">
+ <ref bean="ExampleStorageClientInformationResolver" />
+ </util:list>
+
+ <bean id="ExampleStorageClientInformationResolver" parent="shibboleth.oidc.StorageClientInformationResolver"
+ p:storageService-ref="shibboleth.StorageService" />
+
+</beans>
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/oidc-credentials.xml b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/oidc-credentials.xml
new file mode 100644
index 0000000..2652e65
--- /dev/null
+++ b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/oidc-credentials.xml
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:c="http://www.springframework.org/schema/c" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
+ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
+
+ default-init-method="initialize" default-destroy-method="destroy">
+
+ <!-- This file contains default oidc signing credentials. This file should be imported to credentials.xml -->
+
+ <bean id="shibboleth.oidc.DefaultRSSigningCredential" parent="shibboleth.JWKCredential"
+ p:resource="%{idp.signing.oidc.rs.key}" />
+
+ <bean id="shibboleth.oidc.DefaultESSigningCredential" parent="shibboleth.JWKCredential"
+ p:resource="%{idp.signing.oidc.es.key}" />
+
+ <bean id="shibboleth.oidc.DefaultES384SigningCredential" parent="shibboleth.JWKCredential"
+ p:resource="/credentials/idp-signing-es384.jwk" />
+
+ <bean id="shibboleth.oidc.DefaultES512SigningCredential" parent="shibboleth.JWKCredential"
+ p:resource="/credentials/idp-signing-es521.jwk" />
+
+ <bean id="shibboleth.oidc.DefaultRSAEncryptionCredential" parent="shibboleth.JWKCredential"
+ p:resource="%{idp.signing.oidc.rsa.enc.key}" />
+
+ <bean id="shibboleth.oidc.DefaultECEncryptionCredential" parent="shibboleth.JWKCredential"
+ p:resource="/credentials/idp-encryption-ec.jwk" />
+
+ <bean id="shibboleth.oidfed.DefaultRSSigningCredential" parent="shibboleth.JWKCredential"
+ p:resource="/credentials/fed-signing-rs.jwk" />
+
+ <bean id="shibboleth.oidfed.DefaultES256SigningCredential" parent="shibboleth.JWKCredential"
+ p:resource="/credentials/fed-signing-es256.jwk" />
+
+ <bean id="shibboleth.oidfed.DefaultES384SigningCredential" parent="shibboleth.JWKCredential"
+ p:resource="/credentials/fed-signing-es384.jwk" />
+
+ <bean id="shibboleth.oidfed.DefaultES521SigningCredential" parent="shibboleth.JWKCredential"
+ p:resource="/credentials/fed-signing-es521.jwk" />
+
+ <!--
+ Lists ALL of your OP's response signing credentials for the default security configuration.
+ If you define additional signing credentials make sure to include them within this list.
+ -->
+ <util:list id="shibboleth.oidc.SigningCredentials">
+ <ref bean="shibboleth.oidc.DefaultRSSigningCredential" />
+ <ref bean="shibboleth.oidc.DefaultESSigningCredential" />
+ <ref bean="shibboleth.oidc.DefaultES384SigningCredential" />
+ <ref bean="shibboleth.oidc.DefaultES512SigningCredential" />
+ </util:list>
+
+ <!--
+ Lists ALL of your OP's request decryption credentials for the default security configuration.
+ If you define additional decryption credentials make sure to include them within this list.
+ -->
+ <util:list id="shibboleth.oidc.EncryptionCredentials">
+ <ref bean="shibboleth.oidc.DefaultRSAEncryptionCredential" />
+ <ref bean="shibboleth.oidc.DefaultECEncryptionCredential" />
+ </util:list>
+
+ <!--
+ List ALL of your OP's signing credentials for the default federation security configuration.
+ If you define additional signing credentials make sure to include them within this list.
+ -->
+ <util:list id="shibboleth.oidfed.SigningCredentials">
+ <ref bean="shibboleth.oidfed.DefaultRSSigningCredential" />
+ <ref bean="shibboleth.oidfed.DefaultES256SigningCredential" />
+ <ref bean="shibboleth.oidfed.DefaultES384SigningCredential" />
+ <ref bean="shibboleth.oidfed.DefaultES521SigningCredential" />
+ </util:list>
+
+ <!--
+ If you need to publish a key set different from shibboleth.oidc.EncryptionCredentials, define
+ a list bean named "shibboleth.oidc.EncryptionCredentialsToPublish".
+ -->
+
+ <!-- Example of two active encryption credentials, but only publishing the second before removing from use. -->
+ <!--
+ <util:list id="shibboleth.oidc.EncryptionCredentialsToPublish">
+ <ref bean="shibboleth.oidc.OnlyNewDefaultRSAEncryptionCredential" />
+ </util:list>
+ -->
+
+ <!--
+ If you need to publish a key set different from shibboleth.oidc.SigningCredentials, define
+ a list bean named "shibboleth.oidc.SigningCredentialsToPublish".
+ -->
+
+ <!-- Example of publishing two signing credentials, before active use. -->
+ <!--
+ <util:list id="shibboleth.oidc.SigningCredentialsToPublish">
+ <ref bean="shibboleth.oidc.DefaultRSSigningCredential" />
+ <ref bean="shibboleth.oidc.DefaultESSigningCredential" />
+ <ref bean="shibboleth.oidc.UpcomingDefaultRSSigningCredential" />
+ </util:list>
+ -->
+
+</beans>
diff --git a/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/oidc.properties b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/oidc.properties
new file mode 100644
index 0000000..b996d9f
--- /dev/null
+++ b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/oidc.properties
@@ -0,0 +1,40 @@
+idp.signing.oidc.rs.key = /credentials/idp-signing-rs.jwk
+idp.signing.oidc.es.key = /credentials/idp-signing-es.jwk
+idp.signing.oidc.rsa.enc.key = /credentials/idp-encryption-rsa.jwk
+idp.oidc.issuer = https://op.example.org
+idp.oidc.subject.sourceAttribute = uid
+idp.oidc.subject.salt = isfd07fsddfs70sdf9d99s8
+idp.oidc.discovery.template = src/test/resources/net/shibboleth/idp/module/conf/openid-configuration.json
+
+idp.oidc.nodePrefix = ServerA
+
+idp.oidc.admin.registration.policyLocationPolicy = AccessByIPAddress
+idp.oidc.admin.registration.policyIdPolicy = AccessByIPAddress
+idp.oidc.admin.registration.clientIdPolicy = AccessByIPAddress
+
+idp.oidc.dynreg.defaultMetadataPolicyFile = src/test/resources/net/shibboleth/idp/module/conf/metadata-policy1.json
+
+idp.oauth2.requireAuthenticationRequestPredicate = shibboleth.Conditions.FALSE
+idp.oauth2.grantTypes = authorization_code,refresh_token,client_credentials
+idp.oauth2.defaultAllowedAudience = https://rp.example.org
+
+idp.oidc.discovery.resolver.values = CustomConfigurationValues
+
+idp.oidc.DefaultUnregisteredClientPolicyFile = src/test/resources/net/shibboleth/idp/module/conf/unregistered-policy.json
+
+idp.oauth2.jwtAuth.targetedEndpointAsJWTAudience = true
+idp.oauth2.revocationCondition = CustomTokenRevocationCondition
+idp.oauth2.revocationCondition.attributeId = customRevocation
+
+idp.authn.Password.supportedPrincipals = \
+ saml2/urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport, \
+ saml2/urn:oasis:names:tc:SAML:2.0:ac:classes:Password, \
+ saml1/urn:oasis:names:tc:SAML:1.0:am:password, \
+ oidc/password
+
+idp.authn.OAuth2Client.audit.format = %a|%T|%SP|%I|%s|%AF|%CV|%u|%tu|%AR|%UA|%iss|%sub|%exp|%iat|%typ
+
+idp.oidfed.authorize.automaticRegistrationCondition = shibboleth.Conditions.TRUE
+idp.oidfed.par.automaticRegistrationCondition = shibboleth.Conditions.TRUE
+idp.oidfed.configuration.resolver.values = CustomEntityConfigurationValues
+idp.oidfed.configuration.MetadataSkaletonFile = src/test/resources/net/shibboleth/idp/module/conf/oidfed-entity-configuration-metadata.json
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/oidfed-entity-configuration-metadata.json b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/oidfed-entity-configuration-metadata.json
new file mode 100644
index 0000000..f412263
--- /dev/null
+++ b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/oidfed-entity-configuration-metadata.json
@@ -0,0 +1,7 @@
+{
+ "federation_entity": {
+ "organization_name" : "Example organization",
+ "organization_uri" : "https://org.example.org",
+ "contacts" : [ "contact at example.org" ]
+ }
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/oidfed/oidfed-trust-anchors.json b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/oidfed/oidfed-trust-anchors.json
new file mode 100644
index 0000000..5464750
--- /dev/null
+++ b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/oidfed/oidfed-trust-anchors.json
@@ -0,0 +1,13 @@
+{
+ "https://trust-anchor.federation.local": {
+ "keys": [
+ {
+ "alg": "RS256",
+ "kty":"RSA",
+ "e":"AQAB",
+ "kid":"locallyTrustedAnchorKey",
+ "n":"n0-NFV06ZDKLo1v8KrSJsQ8bbLEffVJw1F5jGXqrKh_4PpBt9FmyWY3gIA9aK1p1WneMaWRNlM1EObierCr0EdXCQbgpKorrPqxiwyl6cOMIH4fN_9uWGqD2HlyGcjcESrNjZz75tNr_9oegh6fWSMgrxyySpU38ALWUX1ZuNS8A4tj8XdJSbSHqftf7qOdgzuy0yaD5h7NwoBCRPOIY88vOLHkcQ4nYdkk8GLSIf5GgGb7JFiPuFHN7pK---LNnFBifag2wbEZ9nnAcAol4jc2gF7zq2mqhMSlbIVmTRj4Y9wxh3DPbmC8xZ-8nbhPmgi4vlij9JWJGEvfLuXaMGQ"
+ }
+ ]
+ }
+}
diff --git a/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/openid-configuration.json b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/openid-configuration.json
new file mode 100644
index 0000000..d291c81
--- /dev/null
+++ b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/openid-configuration.json
@@ -0,0 +1,41 @@
+{
+ "issuer": "https://op.example.org",
+ "authorization_endpoint": "https://op.example.org/idp/profile/oidc/authorize",
+ "registration_endpoint": "https://op.example.org/idp/profile/oidc/register",
+ "jwks_uri": "https://op.example.org/idp/profile/oidc/keyset",
+ "response_types_supported": [
+ "id_token"
+ ],
+ "subject_types_supported": [
+ "public",
+ "pairwise"
+ ],
+ "grant_types_supported": [
+ "implicit"
+ ],
+ "id_token_signing_alg_values_supported": [
+ "RS256"
+ ],
+ "request_parameter_supported": false,
+ "request_uri_parameter_supported": false,
+ "require_request_uri_registration": false,
+ "scopes_supported": [
+ "openid",
+ "profile",
+ "email",
+ "address",
+ "phone",
+ "info"
+ ],
+ "claims_supported": [
+ "aud",
+ "acr",
+ "exp",
+ "iat",
+ "iss",
+ "sub",
+ "eduPersonPrincipalName",
+ "eduPersonAffiliation",
+ "mail"
+ ]
+}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/relying-party.xml b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/relying-party.xml
new file mode 100644
index 0000000..339ce76
--- /dev/null
+++ b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/relying-party.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:util="http://www.springframework.org/schema/util"
+ xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:c="http://www.springframework.org/schema/c"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
+ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
+
+ default-init-method="initialize"
+ default-destroy-method="destroy">
+
+ <!-- Exclude single ES-algorithm for testing -->
+ <util:list id="shibboleth.oidc.ExcludedSignatureAlgorithms">
+ <util:constant
+ static-field="net.shibboleth.oidc.jwa.support.SignatureConstants.ALGO_ID_SIGNATURE_ES_384" />
+ </util:list>
+
+ <util:list id="shibboleth.oidc.ExcludedEncryptionAlgorithms">
+ <util:constant
+ static-field="net.shibboleth.oidc.jwa.support.KeyManagementConstants.ALGO_ID_ALG_RSA_OAEP_384" />
+ <util:constant
+ static-field="net.shibboleth.oidc.jwa.support.EncryptionConstants.ALGO_ID_ENC_ALG_A192CBC_HS384" />
+ </util:list>
+
+ <!--
+ Unverified RP configuration, defaults to no support for any profiles. Add <ref> elements to the list
+ to enable specific default profile settings (as below), or create new beans inline to override defaults.
+
+ "Unverified" typically means the IdP has no metadata, or equivalent way of assuring the identity and
+ legitimacy of a requesting system. To run an "open" IdP, you can enable profiles here.
+ -->
+
+ <bean id="shibboleth.UnverifiedRelyingParty" parent="RelyingParty">
+ <property name="profileConfigurations">
+ <list>
+ <ref bean="OIDC.Keyset" />
+ <ref bean="OIDC.Registration" />
+ <ref bean="OIDC.Configuration" />
+ <bean parent="OIDC.SSO" />
+ <bean parent="OAUTH2.Token" />
+ <bean parent="OAUTH2.TokenAudience" p:encryptionOptional="true" />
+ <bean parent="OIDC.UserInfo" />
+ <bean parent="OAUTH2.Introspection" />
+ <bean parent="OAUTH2.Revocation" />
+ <bean parent="OAUTH2.PAR" />
+ <bean parent="OIDFED.Configuration" p:cachedSuccessResponseLifetime="PT2S" />
+ <bean parent="OIDFED.ResolveEntity" />
+ </list>
+ </property>
+ </bean>
+
+ <!-- Default configuration, with default settings applied for all profiles. -->
+
+ <bean id="shibboleth.DefaultRelyingParty" parent="RelyingParty.MDDriven">
+ <property name="profileConfigurations">
+ <list>
+ <ref bean="Shibboleth.SSO.MDDriven" />
+ <ref bean="SAML1.AttributeQuery.MDDriven" />
+ <ref bean="SAML1.ArtifactResolution.MDDriven" />
+ <ref bean="SAML2.SSO.MDDriven" />
+ <ref bean="SAML2.ECP.MDDriven" />
+ <ref bean="SAML2.Logout.MDDriven" />
+ <ref bean="SAML2.AttributeQuery.MDDriven" />
+ <ref bean="SAML2.ArtifactResolution.MDDriven" />
+ <ref bean="OIDC.SSO.MDDriven" />
+ <ref bean="OIDC.UserInfo.MDDriven" />
+ <ref bean="OIDC.Registration.MDDriven" />
+ <ref bean="OIDC.Logout.MDDriven" />
+ <ref bean="OAUTH2.Token.MDDriven" />
+ <ref bean="OAUTH2.Introspection.MDDriven" />
+ <ref bean="OAUTH2.Revocation.MDDriven" />
+ <bean parent="OAUTH2.PAR.MDDriven" />
+ </list>
+ </property>
+ </bean>
+
+ <util:list id="shibboleth.RelyingPartyOverrides">
+ <bean parent="RelyingPartyByName" c:relyingPartyIds="https://trust-anchor.federation.local">
+ <property name="profileConfigurations">
+ <list>
+ <bean parent="OIDFED.AutomaticRegistration" p:mandatoryTrustMarks=""/>
+ <bean parent="OIDFED.ExplicitRegistration" p:mandatoryTrustMarks=""/>
+ </list>
+ </property>
+ </bean>
+ <bean parent="RelyingPartyByTrustAnchor" c:trustAnchorIds="https://trust-anchor.federation.local">
+ <property name="profileConfigurations">
+ <list>
+ <ref bean="OIDC.SSO.MDDriven" />
+ <bean parent="OAUTH2.Token.MDDriven" p:tokenEndpointAuthMethods="client_secret_basic,client_secret_post,client_secret_jwt,private_key_jwt,none"/>
+ <bean parent="OAUTH2.PAR.MDDriven" p:tokenEndpointAuthMethods="client_secret_basic,client_secret_post,client_secret_jwt,private_key_jwt,none"/>
+ </list>
+ </property>
+ </bean>
+ </util:list>
+
+</beans>
diff --git a/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/services.xml b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/services.xml
new file mode 100644
index 0000000..c2cf11c
--- /dev/null
+++ b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/services.xml
@@ -0,0 +1,92 @@
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:c="http://www.springframework.org/schema/c" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
+ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
+
+ default-init-method="initialize"
+ default-destroy-method="destroy">
+
+ <!-- Advanced configuration of services from HTTP.
+
+ To use an HTTP resource you first need to configure the Apache HttpClient which will be used
+ to communicate with the web server. Any HttpClient can be used, but two Factory Beans allow simple
+ configuration of in-memory or file-based caching clients.
+
+ Examples are:
+
+ A resource which will be supplied from an in-memory cache for as long as the file on the webserver does not change.
+ If the webserver becomes unavailable the resource will be unavailable.
+
+ <bean id="inMemoryResource" class="net.shibboleth.ext.spring.resource.HTTPResource"
+ c:client-ref="shibboleth.MemoryCachingHttpClient"
+ c:url="http://example.org/path/to/file.xml" />
+
+ Two resources which will be supplied from an on disk cache (suitable for multiple or large files) for as long
+ as the file on the webserver does not change. If the webserver becomes unavailable the last used contents
+ of the file will be returned (even if that was in a previous IdP lifetime).
+
+ <bean id="fileResource" class="net.shibboleth.ext.spring.resource.FileBackedHTTPResource"
+ c:client-ref="shibboleth.FileCachingHttpClient"
+ c:url="http://example.org/path/to/file.xml"
+ c:backingFile="/var/shibboleth/caches/resourcecache/file.xml"/>
+
+ <bean id="otherFileResource" class="net.shibboleth.ext.spring.resource.FileBackedHTTPResource"
+ c:client-ref="shibboleth.FileCachingHttpClient"
+ c:url="http://another.server.example.org/path/to/different/file.xml"
+ c:backingFile="/var/shibboleth/caches/resourcecache/differentFile.xml"/>
+
+ In all cases you should review the "idp.httpclient.*" properties defined in services.properties
+ -->
+
+ <!--
+ Otherwise by default we look at resources whose names are derived from %{idp.home}. Services not configured
+ using native Spring syntax also need to load the property-placeholder file in order to pull settings from
+ property sources.
+ -->
+
+ <!-- This set of resources supports a native Spring relying-party.xml file. -->
+ <util:list id="shibboleth.RelyingPartyResolverResources">
+ <value>%{idp.home}/conf/relying-party.xml</value>
+ <value>%{idp.home}/conf/credentials.xml</value>
+ </util:list>
+
+ <util:list id="shibboleth.MetadataResolverResources">
+ <value>%{idp.home}/conf/metadata-providers.xml</value>
+ </util:list>
+
+ <!-- This set of resources uses only AttributeEncoders for compatibility. -->
+ <util:list id ="shibboleth.AttributeRegistryResources">
+ <value>%{idp.home}/conf/attribute-registry.xml</value>
+ <value>%{idp.home}/conf/attribute-resolver.xml</value>
+<!-- <value>%{idp.home}/conf/attributes/default-rules.xml</value> -->
+ </util:list>
+
+ <util:list id ="shibboleth.AttributeResolverResources">
+ <value>%{idp.home}/conf/attribute-resolver.xml</value>
+ </util:list>
+
+ <util:list id ="shibboleth.AttributeFilterResources">
+ <value>%{idp.home}/conf/attribute-filter.xml</value>
+ </util:list>
+
+ <util:list id ="shibboleth.NameIdentifierGenerationResources">
+ <value>%{idp.home}/conf/saml-nameid.xml</value>
+ </util:list>
+
+ <util:list id="shibboleth.AccessControlResources">
+ <value>%{idp.home}/conf/access-control.xml</value>
+ </util:list>
+
+ <!--
+ This collection of resources differs slightly in that it should not include the file extension.
+ Message sources are internationalized, and Spring will search for a compatible language extension
+ and fall back to one with only a .properties extension.
+ -->
+ <util:list id="shibboleth.MessageSourceResources">
+ <value>%{idp.home}/messages/messages</value>
+ </util:list>
+
+</beans>
diff --git a/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/unregistered-policy.json b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/unregistered-policy.json
new file mode 100644
index 0000000..dd89684
--- /dev/null
+++ b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/unregistered-policy.json
@@ -0,0 +1,15 @@
+{
+ "client_id": {
+ "one_of": ["policyAcceptedClient1","policyAcceptedClient2"]
+ },
+ "scope": {
+ "value": "openid info"
+ },
+ "redirect_uri": {
+ "regexp": "^https:\/\/(?:([^.]+).)?example.org\/(.*)",
+ "bean": "alwaysTruePolicyOperator"
+ },
+ "response_type": {
+ "one_of": ["code"]
+ }
+}
diff --git a/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/credentials/ldap-server.crt b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/credentials/ldap-server.crt
new file mode 100644
index 0000000..e6390b3
--- /dev/null
+++ b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/credentials/ldap-server.crt
@@ -0,0 +1,13 @@
+-----BEGIN CERTIFICATE-----
+MIICATCCAWoCCQCZy4ovDlQTvDANBgkqhkiG9w0BAQUFADBFMRMwEQYKCZImiZPy
+LGQBGRYDbmV0MRowGAYKCZImiZPyLGQBGRYKc2hpYmJvbGV0aDESMBAGA1UEAxMJ
+bG9jYWxob3N0MB4XDTEzMDkyMDA0NDE1OFoXDTIzMDkxODA0NDE1OFowRTETMBEG
+CgmSJomT8ixkARkWA25ldDEaMBgGCgmSJomT8ixkARkWCnNoaWJib2xldGgxEjAQ
+BgNVBAMTCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA+Pj+
+Rk0FosrK8tdNJLASSbfRFEJDf0498bnwtor76PONwkTLjnm7paTMAy7oGIAccuBf
+n7183mlo/yh22x+7Fdux4ESvdp1FWl7nGlBBWUrLZzXwwGybC0qv3/Cmvfkvm6zh
+zgY7YyQYlA/RCjTk/pUfrXaIIaKwd+B2miBDrDUCAwEAATANBgkqhkiG9w0BAQUF
+AAOBgQCKQsndxYjsGIvK3lnlztIuKQmRlj7IHL/T6abBYwmQcyMa5o3hv6/Rx+Ze
+NSRfyhakPY4v5yUBi1fyIVIGcAbnak+GQIfsO8uDhzZt6DwshzHrnCbHTLQx6NTB
+4mvLjAdt7riBIl5y5n3tbtrZdpTgFhQxjLWTBpWIO0XKxqtBhw==
+-----END CERTIFICATE-----
diff --git a/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/oidc/metadata/impl/metadata-policy-test-vectors-2025-02-13.json b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/oidc/metadata/impl/metadata-policy-test-vectors-2025-02-13.json
new file mode 100644
index 0000000..c70ca6b
--- /dev/null
+++ b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/oidc/metadata/impl/metadata-policy-test-vectors-2025-02-13.json
@@ -0,0 +1,50299 @@
+[
+ {
+ "n" : 1,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "RS256"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 2,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256"
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "RS256"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 3,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256"
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "RS256"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 4,
+ "combination" : [ "value", "value" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256"
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256"
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256"
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "RS256"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 5,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "EdDSA"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 6,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256"
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "EdDSA"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 7,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256"
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "EdDSA"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 8,
+ "combination" : [ "value", "value" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256"
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256"
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256"
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "EdDSA"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 9,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 10,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256"
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 11,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256"
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 12,
+ "combination" : [ "value", "value" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256"
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256"
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256"
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 13,
+ "combination" : [ "value", "value" ],
+ "TA" : {
+ "logo_uri" : {
+ "value" : null
+ }
+ },
+ "INT" : {
+ "logo_uri" : {
+ "value" : "https:\/\/example.com\/logo.png"
+ }
+ },
+ "metadata" : {
+ "logo_uri" : "https:\/\/example.com\/logo.png"
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate logo_uri policy: Value mismatch"
+ },
+ {
+ "n" : 14,
+ "combination" : [ "value", "value" ],
+ "TA" : {
+ "logo_uri" : {
+ "value" : null
+ }
+ },
+ "INT" : {
+ "logo_uri" : {
+ "value" : "https:\/\/example.com\/logo.png"
+ }
+ },
+ "metadata" : {
+ "logo_uri" : "https:\/\/images.example.com\/logo.jpg"
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate logo_uri policy: Value mismatch"
+ },
+ {
+ "n" : 15,
+ "combination" : [ "value", "value" ],
+ "TA" : {
+ "logo_uri" : {
+ "value" : null
+ }
+ },
+ "INT" : {
+ "logo_uri" : {
+ "value" : "https:\/\/example.com\/logo.png"
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate logo_uri policy: Value mismatch"
+ },
+ {
+ "n" : 16,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 17,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 18,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 19,
+ "combination" : [ "value", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 20,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 21,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 22,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 23,
+ "combination" : [ "value", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 24,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 25,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 26,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 27,
+ "combination" : [ "value", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 28,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 29,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 30,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 31,
+ "combination" : [ "value", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 32,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 33,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 34,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 35,
+ "combination" : [ "value", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 36,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 37,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 38,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 39,
+ "combination" : [ "value", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 40,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 41,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 42,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 43,
+ "combination" : [ "value", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 44,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 45,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 46,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 47,
+ "combination" : [ "value", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 48,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 49,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 50,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 51,
+ "combination" : [ "value", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 52,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 53,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 54,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 55,
+ "combination" : [ "value", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 56,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 57,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 58,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 59,
+ "combination" : [ "value", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 60,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 61,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 62,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 63,
+ "combination" : [ "value", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 64,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 65,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 66,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 67,
+ "combination" : [ "value", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 68,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 69,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 70,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 71,
+ "combination" : [ "value", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 72,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 73,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 74,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 75,
+ "combination" : [ "value", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 76,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 77,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 78,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 79,
+ "combination" : [ "value", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 80,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 81,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 82,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 83,
+ "combination" : [ "value", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 84,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 85,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 86,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 87,
+ "combination" : [ "value", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Value mismatch"
+ },
+ {
+ "n" : 88,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "resolved" : {
+ "require_auth_time" : true
+ }
+ },
+ {
+ "n" : 89,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Value mismatch"
+ },
+ {
+ "n" : 90,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Value mismatch"
+ },
+ {
+ "n" : 91,
+ "combination" : [ "value", "value" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "resolved" : {
+ "require_auth_time" : false
+ }
+ },
+ {
+ "n" : 92,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "resolved" : {
+ "require_auth_time" : true
+ }
+ },
+ {
+ "n" : 93,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Value mismatch"
+ },
+ {
+ "n" : 94,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Value mismatch"
+ },
+ {
+ "n" : 95,
+ "combination" : [ "value", "value" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "resolved" : {
+ "require_auth_time" : false
+ }
+ },
+ {
+ "n" : 96,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "resolved" : {
+ "require_auth_time" : true
+ }
+ },
+ {
+ "n" : 97,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Value mismatch"
+ },
+ {
+ "n" : 98,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Value mismatch"
+ },
+ {
+ "n" : 99,
+ "combination" : [ "value", "value" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "resolved" : {
+ "require_auth_time" : false
+ }
+ },
+ {
+ "n" : 100,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "resolved" : {
+ "require_auth_time" : true
+ }
+ },
+ {
+ "n" : 101,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Value mismatch"
+ },
+ {
+ "n" : 102,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Value mismatch"
+ },
+ {
+ "n" : 103,
+ "combination" : [ "value", "value" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "resolved" : {
+ "require_auth_time" : false
+ }
+ },
+ {
+ "n" : 104,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "resolved" : {
+ "require_auth_time" : true
+ }
+ },
+ {
+ "n" : 105,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Value mismatch"
+ },
+ {
+ "n" : 106,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Value mismatch"
+ },
+ {
+ "n" : 107,
+ "combination" : [ "value", "value" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "resolved" : {
+ "require_auth_time" : false
+ }
+ },
+ {
+ "n" : 108,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "resolved" : {
+ "require_auth_time" : true
+ }
+ },
+ {
+ "n" : 109,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Value mismatch"
+ },
+ {
+ "n" : 110,
+ "combination" : [ "value", "value", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Value mismatch"
+ },
+ {
+ "n" : 111,
+ "combination" : [ "value", "value" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "resolved" : {
+ "require_auth_time" : false
+ }
+ },
+ {
+ "n" : 112,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 113,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 114,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 115,
+ "combination" : [ "value", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 116,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 117,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 118,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 119,
+ "combination" : [ "value", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 120,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 121,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 122,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 123,
+ "combination" : [ "value", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 124,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 125,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 126,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 127,
+ "combination" : [ "value", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 128,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 129,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 130,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 131,
+ "combination" : [ "value", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 132,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 133,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 134,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 135,
+ "combination" : [ "value", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 136,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 137,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 138,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 139,
+ "combination" : [ "value", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 140,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 141,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 142,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 143,
+ "combination" : [ "value", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 144,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 145,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 146,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 147,
+ "combination" : [ "value", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 148,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 149,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 150,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 151,
+ "combination" : [ "value", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 152,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 153,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 154,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 155,
+ "combination" : [ "value", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 156,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 157,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 158,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 159,
+ "combination" : [ "value", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 160,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 161,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 162,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 163,
+ "combination" : [ "value", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 164,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 165,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 166,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 167,
+ "combination" : [ "value", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 168,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 169,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 170,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 171,
+ "combination" : [ "value", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 172,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 173,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 174,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 175,
+ "combination" : [ "value", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 176,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 177,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 178,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 179,
+ "combination" : [ "value", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 180,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 181,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 182,
+ "combination" : [ "value", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 183,
+ "combination" : [ "value", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ add operator combination: The value must be a subset of the values of add"
+ },
+ {
+ "n" : 184,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "RS256"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 185,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256"
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "RS256"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 186,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256"
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "RS256"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 187,
+ "combination" : [ "value", "default" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256"
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256"
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "value" : "RS256"
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "RS256"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 188,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "EdDSA"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 189,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256"
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "EdDSA"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 190,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256"
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "EdDSA"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 191,
+ "combination" : [ "value", "default" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256"
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256"
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "value" : "RS256"
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "EdDSA"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 192,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 193,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256"
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 194,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256"
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 195,
+ "combination" : [ "value", "default" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256"
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256"
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "value" : "RS256"
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 196,
+ "combination" : [ "value", "default" ],
+ "TA" : {
+ "logo_uri" : {
+ "value" : null
+ }
+ },
+ "INT" : {
+ "logo_uri" : {
+ "default" : "https:\/\/example.com\/logo.png"
+ }
+ },
+ "metadata" : {
+ "logo_uri" : "https:\/\/example.com\/logo.png"
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate logo_uri policy: Illegal value \/ default operator combination: The value must be non-null"
+ },
+ {
+ "n" : 197,
+ "combination" : [ "value", "default" ],
+ "TA" : {
+ "logo_uri" : {
+ "value" : null
+ }
+ },
+ "INT" : {
+ "logo_uri" : {
+ "default" : "https:\/\/example.com\/logo.png"
+ }
+ },
+ "metadata" : {
+ "logo_uri" : "https:\/\/images.example.com\/logo.jpg"
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate logo_uri policy: Illegal value \/ default operator combination: The value must be non-null"
+ },
+ {
+ "n" : 198,
+ "combination" : [ "value", "default" ],
+ "TA" : {
+ "logo_uri" : {
+ "value" : null
+ }
+ },
+ "INT" : {
+ "logo_uri" : {
+ "default" : "https:\/\/example.com\/logo.png"
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate logo_uri policy: Illegal value \/ default operator combination: The value must be non-null"
+ },
+ {
+ "n" : 199,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 200,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 201,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 202,
+ "combination" : [ "value", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 203,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 204,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 205,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 206,
+ "combination" : [ "value", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 207,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 208,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 209,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 210,
+ "combination" : [ "value", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 211,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 212,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 213,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 214,
+ "combination" : [ "value", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 215,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 216,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 217,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 218,
+ "combination" : [ "value", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 219,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 220,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 221,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 222,
+ "combination" : [ "value", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 223,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 224,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 225,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 226,
+ "combination" : [ "value", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 227,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 228,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 229,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 230,
+ "combination" : [ "value", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 231,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 232,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 233,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 234,
+ "combination" : [ "value", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 235,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 236,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 237,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 238,
+ "combination" : [ "value", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 239,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 240,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 241,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 242,
+ "combination" : [ "value", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 243,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 244,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 245,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 246,
+ "combination" : [ "value", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 247,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 248,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 249,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 250,
+ "combination" : [ "value", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 251,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 252,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 253,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 254,
+ "combination" : [ "value", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 255,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 256,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 257,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 258,
+ "combination" : [ "value", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 259,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 260,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 261,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 262,
+ "combination" : [ "value", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 263,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 264,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 265,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 266,
+ "combination" : [ "value", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 267,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 268,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 269,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 270,
+ "combination" : [ "value", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 271,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "resolved" : {
+ "require_auth_time" : true
+ }
+ },
+ {
+ "n" : 272,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Value mismatch"
+ },
+ {
+ "n" : 273,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Value mismatch"
+ },
+ {
+ "n" : 274,
+ "combination" : [ "value", "default" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "resolved" : {
+ "require_auth_time" : false
+ }
+ },
+ {
+ "n" : 275,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "resolved" : {
+ "require_auth_time" : true
+ }
+ },
+ {
+ "n" : 276,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Value mismatch"
+ },
+ {
+ "n" : 277,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Value mismatch"
+ },
+ {
+ "n" : 278,
+ "combination" : [ "value", "default" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "resolved" : {
+ "require_auth_time" : false
+ }
+ },
+ {
+ "n" : 279,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "resolved" : {
+ "require_auth_time" : true
+ }
+ },
+ {
+ "n" : 280,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Value mismatch"
+ },
+ {
+ "n" : 281,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Value mismatch"
+ },
+ {
+ "n" : 282,
+ "combination" : [ "value", "default" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "resolved" : {
+ "require_auth_time" : false
+ }
+ },
+ {
+ "n" : 283,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "resolved" : {
+ "require_auth_time" : true
+ }
+ },
+ {
+ "n" : 284,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Value mismatch"
+ },
+ {
+ "n" : 285,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Value mismatch"
+ },
+ {
+ "n" : 286,
+ "combination" : [ "value", "default" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "resolved" : {
+ "require_auth_time" : false
+ }
+ },
+ {
+ "n" : 287,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "resolved" : {
+ "require_auth_time" : true
+ }
+ },
+ {
+ "n" : 288,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Value mismatch"
+ },
+ {
+ "n" : 289,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Value mismatch"
+ },
+ {
+ "n" : 290,
+ "combination" : [ "value", "default" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "resolved" : {
+ "require_auth_time" : false
+ }
+ },
+ {
+ "n" : 291,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "resolved" : {
+ "require_auth_time" : true
+ }
+ },
+ {
+ "n" : 292,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Value mismatch"
+ },
+ {
+ "n" : 293,
+ "combination" : [ "value", "default", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Value mismatch"
+ },
+ {
+ "n" : 294,
+ "combination" : [ "value", "default" ],
+ "TA" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "value" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "resolved" : {
+ "require_auth_time" : false
+ }
+ },
+ {
+ "n" : 295,
+ "combination" : [ "value", "one_of", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "RS256"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 296,
+ "combination" : [ "value", "one_of", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ]
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "RS256"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 297,
+ "combination" : [ "value", "one_of", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256"
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "RS256"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 298,
+ "combination" : [ "value", "one_of" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256"
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ]
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "value" : "RS256"
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "RS256"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 299,
+ "combination" : [ "value", "one_of", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "EdDSA"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 300,
+ "combination" : [ "value", "one_of", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ]
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "EdDSA"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 301,
+ "combination" : [ "value", "one_of", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256"
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "EdDSA"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 302,
+ "combination" : [ "value", "one_of" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256"
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ]
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "value" : "RS256"
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "EdDSA"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 303,
+ "combination" : [ "value", "one_of", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 304,
+ "combination" : [ "value", "one_of", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ]
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 305,
+ "combination" : [ "value", "one_of", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256"
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 306,
+ "combination" : [ "value", "one_of" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256"
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ]
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "value" : "RS256"
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 307,
+ "combination" : [ "value", "one_of" ],
+ "TA" : {
+ "logo_uri" : {
+ "value" : null
+ }
+ },
+ "INT" : {
+ "logo_uri" : {
+ "one_of" : [ "https:\/\/example.com\/logo.png", "https:\/\/example.org\/logo.png" ]
+ }
+ },
+ "metadata" : {
+ "logo_uri" : "https:\/\/example.com\/logo.png"
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate logo_uri policy: Illegal value \/ one_of operator combination: The value must be among the one_of values"
+ },
+ {
+ "n" : 308,
+ "combination" : [ "value", "one_of" ],
+ "TA" : {
+ "logo_uri" : {
+ "value" : null
+ }
+ },
+ "INT" : {
+ "logo_uri" : {
+ "one_of" : [ "https:\/\/example.com\/logo.png", "https:\/\/example.org\/logo.png" ]
+ }
+ },
+ "metadata" : {
+ "logo_uri" : "https:\/\/images.example.com\/logo.jpg"
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate logo_uri policy: Illegal value \/ one_of operator combination: The value must be among the one_of values"
+ },
+ {
+ "n" : 309,
+ "combination" : [ "value", "one_of" ],
+ "TA" : {
+ "logo_uri" : {
+ "value" : null
+ }
+ },
+ "INT" : {
+ "logo_uri" : {
+ "one_of" : [ "https:\/\/example.com\/logo.png", "https:\/\/example.org\/logo.png" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate logo_uri policy: Illegal value \/ one_of operator combination: The value must be among the one_of values"
+ },
+ {
+ "n" : 310,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 311,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 312,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 313,
+ "combination" : [ "value", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "value" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 314,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 315,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 316,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 317,
+ "combination" : [ "value", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "value" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 318,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 319,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 320,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 321,
+ "combination" : [ "value", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "value" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 322,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 323,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 324,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 325,
+ "combination" : [ "value", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "value" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 326,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 327,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 328,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 329,
+ "combination" : [ "value", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "value" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 330,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 331,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 332,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 333,
+ "combination" : [ "value", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "value" : [ ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 334,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 335,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 336,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 337,
+ "combination" : [ "value", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 338,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 339,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 340,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 341,
+ "combination" : [ "value", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 342,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 343,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 344,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 345,
+ "combination" : [ "value", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 346,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 347,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 348,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 349,
+ "combination" : [ "value", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 350,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 351,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 352,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 353,
+ "combination" : [ "value", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 354,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 355,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 356,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 357,
+ "combination" : [ "value", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 358,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 359,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 360,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 361,
+ "combination" : [ "value", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 362,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 363,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 364,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 365,
+ "combination" : [ "value", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 366,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 367,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 368,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 369,
+ "combination" : [ "value", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 370,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 371,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 372,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 373,
+ "combination" : [ "value", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 374,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 375,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 376,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 377,
+ "combination" : [ "value", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 378,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 379,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 380,
+ "combination" : [ "value", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 381,
+ "combination" : [ "value", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 382,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 383,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 384,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 385,
+ "combination" : [ "value", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 386,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 387,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 388,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 389,
+ "combination" : [ "value", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 390,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 391,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 392,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 393,
+ "combination" : [ "value", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 394,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 395,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 396,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 397,
+ "combination" : [ "value", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 398,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 399,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 400,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 401,
+ "combination" : [ "value", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 402,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 403,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 404,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 405,
+ "combination" : [ "value", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 406,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 407,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 408,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 409,
+ "combination" : [ "value", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 410,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 411,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 412,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 413,
+ "combination" : [ "value", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 414,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 415,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 416,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 417,
+ "combination" : [ "value", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 418,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 419,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 420,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 421,
+ "combination" : [ "value", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 422,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 423,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 424,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 425,
+ "combination" : [ "value", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 426,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 427,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 428,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 429,
+ "combination" : [ "value", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 430,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 431,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 432,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 433,
+ "combination" : [ "value", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 434,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 435,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 436,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 437,
+ "combination" : [ "value", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 438,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 439,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 440,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 441,
+ "combination" : [ "value", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 442,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 443,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 444,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 445,
+ "combination" : [ "value", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 446,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 447,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 448,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 449,
+ "combination" : [ "value", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 450,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 451,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 452,
+ "combination" : [ "value", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 453,
+ "combination" : [ "value", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal value \/ superset_of operator combination: The value must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 454,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 455,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 456,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 457,
+ "combination" : [ "add", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 458,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 459,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 460,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 461,
+ "combination" : [ "add", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 462,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 463,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 464,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 465,
+ "combination" : [ "add", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 466,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 467,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 468,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 469,
+ "combination" : [ "add", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 470,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 471,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 472,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 473,
+ "combination" : [ "add", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 474,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 475,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 476,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 477,
+ "combination" : [ "add", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 478,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 479,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 480,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 481,
+ "combination" : [ "add", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 482,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 483,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 484,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 485,
+ "combination" : [ "add", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 486,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 487,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 488,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 489,
+ "combination" : [ "add", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 490,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 491,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 492,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 493,
+ "combination" : [ "add", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 494,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 495,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 496,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 497,
+ "combination" : [ "add", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 498,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 499,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 500,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 501,
+ "combination" : [ "add", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 502,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 503,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 504,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 505,
+ "combination" : [ "add", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 506,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 507,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 508,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 509,
+ "combination" : [ "add", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 510,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 511,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 512,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 513,
+ "combination" : [ "add", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 514,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 515,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 516,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 517,
+ "combination" : [ "add", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 518,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 519,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 520,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 521,
+ "combination" : [ "add", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 522,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 523,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 524,
+ "combination" : [ "add", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 525,
+ "combination" : [ "add", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 526,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 527,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 528,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 529,
+ "combination" : [ "add", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 530,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password", "authorization_code" ]
+ }
+ },
+ {
+ "n" : 531,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password", "authorization_code" ]
+ }
+ },
+ {
+ "n" : 532,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password", "authorization_code" ]
+ }
+ },
+ {
+ "n" : 533,
+ "combination" : [ "add", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password", "authorization_code" ]
+ }
+ },
+ {
+ "n" : 534,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 535,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 536,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 537,
+ "combination" : [ "add", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 538,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 539,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 540,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 541,
+ "combination" : [ "add", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 542,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 543,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 544,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 545,
+ "combination" : [ "add", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 546,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 547,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 548,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 549,
+ "combination" : [ "add", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 550,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 551,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 552,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 553,
+ "combination" : [ "add", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 554,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password", "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 555,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password", "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 556,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password", "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 557,
+ "combination" : [ "add", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password", "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 558,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 559,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 560,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 561,
+ "combination" : [ "add", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 562,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 563,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 564,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 565,
+ "combination" : [ "add", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 566,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 567,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 568,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 569,
+ "combination" : [ "add", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 570,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 571,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 572,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 573,
+ "combination" : [ "add", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 574,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 575,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 576,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 577,
+ "combination" : [ "add", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 578,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password", "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 579,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password", "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 580,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password", "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 581,
+ "combination" : [ "add", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password", "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 582,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 583,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 584,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 585,
+ "combination" : [ "add", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 586,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 587,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 588,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 589,
+ "combination" : [ "add", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 590,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 591,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 592,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 593,
+ "combination" : [ "add", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 594,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 595,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 596,
+ "combination" : [ "add", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 597,
+ "combination" : [ "add", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 598,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 599,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 600,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 601,
+ "combination" : [ "add", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 602,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password" ]
+ }
+ },
+ {
+ "n" : 603,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password" ]
+ }
+ },
+ {
+ "n" : 604,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password" ]
+ }
+ },
+ {
+ "n" : 605,
+ "combination" : [ "add", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password" ]
+ }
+ },
+ {
+ "n" : 606,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 607,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 608,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 609,
+ "combination" : [ "add", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 610,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 611,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 612,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 613,
+ "combination" : [ "add", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 614,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 615,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 616,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 617,
+ "combination" : [ "add", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 618,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 619,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 620,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 621,
+ "combination" : [ "add", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 622,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 623,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 624,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 625,
+ "combination" : [ "add", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 626,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password" ]
+ }
+ },
+ {
+ "n" : 627,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password" ]
+ }
+ },
+ {
+ "n" : 628,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password" ]
+ }
+ },
+ {
+ "n" : 629,
+ "combination" : [ "add", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password" ]
+ }
+ },
+ {
+ "n" : 630,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 631,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 632,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 633,
+ "combination" : [ "add", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 634,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 635,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 636,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 637,
+ "combination" : [ "add", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 638,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 639,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 640,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 641,
+ "combination" : [ "add", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 642,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 643,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 644,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 645,
+ "combination" : [ "add", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 646,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 647,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 648,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 649,
+ "combination" : [ "add", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 650,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password", "authorization_code" ]
+ }
+ },
+ {
+ "n" : 651,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password", "authorization_code" ]
+ }
+ },
+ {
+ "n" : 652,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password", "authorization_code" ]
+ }
+ },
+ {
+ "n" : 653,
+ "combination" : [ "add", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password", "authorization_code" ]
+ }
+ },
+ {
+ "n" : 654,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 655,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 656,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 657,
+ "combination" : [ "add", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 658,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 659,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 660,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 661,
+ "combination" : [ "add", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 662,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 663,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 664,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 665,
+ "combination" : [ "add", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 666,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 667,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 668,
+ "combination" : [ "add", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 669,
+ "combination" : [ "add", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 670,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 671,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 672,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 673,
+ "combination" : [ "add", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 674,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 675,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 676,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 677,
+ "combination" : [ "add", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 678,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 679,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 680,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 681,
+ "combination" : [ "add", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 682,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 683,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 684,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 685,
+ "combination" : [ "add", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 686,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 687,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 688,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 689,
+ "combination" : [ "add", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 690,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 691,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 692,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 693,
+ "combination" : [ "add", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 694,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 695,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 696,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 697,
+ "combination" : [ "add", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 698,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 699,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 700,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 701,
+ "combination" : [ "add", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 702,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 703,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 704,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 705,
+ "combination" : [ "add", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 706,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 707,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 708,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 709,
+ "combination" : [ "add", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 710,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 711,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 712,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 713,
+ "combination" : [ "add", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 714,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 715,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 716,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 717,
+ "combination" : [ "add", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 718,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 719,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 720,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 721,
+ "combination" : [ "add", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 722,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 723,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 724,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 725,
+ "combination" : [ "add", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 726,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 727,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 728,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 729,
+ "combination" : [ "add", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 730,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 731,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 732,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 733,
+ "combination" : [ "add", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 734,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 735,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 736,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 737,
+ "combination" : [ "add", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 738,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 739,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 740,
+ "combination" : [ "add", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 741,
+ "combination" : [ "add", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 742,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 743,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 744,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 745,
+ "combination" : [ "add", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 746,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 747,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 748,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 749,
+ "combination" : [ "add", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 750,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 751,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 752,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 753,
+ "combination" : [ "add", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 754,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 755,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 756,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 757,
+ "combination" : [ "add", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 758,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 759,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 760,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 761,
+ "combination" : [ "add", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 762,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 763,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 764,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 765,
+ "combination" : [ "add", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 766,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 767,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 768,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 769,
+ "combination" : [ "add", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 770,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 771,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 772,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 773,
+ "combination" : [ "add", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 774,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 775,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 776,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 777,
+ "combination" : [ "add", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 778,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 779,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 780,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 781,
+ "combination" : [ "add", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 782,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 783,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 784,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 785,
+ "combination" : [ "add", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 786,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 787,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 788,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 789,
+ "combination" : [ "add", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 790,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 791,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 792,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 793,
+ "combination" : [ "add", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 794,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 795,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 796,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 797,
+ "combination" : [ "add", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 798,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 799,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 800,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 801,
+ "combination" : [ "add", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 802,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 803,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 804,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 805,
+ "combination" : [ "add", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 806,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 807,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 808,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 809,
+ "combination" : [ "add", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 810,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 811,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 812,
+ "combination" : [ "add", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 813,
+ "combination" : [ "add", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 814,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "RS256"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 815,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256"
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "RS256"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 816,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256"
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "RS256"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 817,
+ "combination" : [ "default", "value" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256"
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256"
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "value" : "RS256"
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "RS256"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 818,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "EdDSA"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 819,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256"
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "EdDSA"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 820,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256"
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "EdDSA"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 821,
+ "combination" : [ "default", "value" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256"
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256"
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "value" : "RS256"
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "EdDSA"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 822,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 823,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256"
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 824,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256"
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 825,
+ "combination" : [ "default", "value" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256"
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256"
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "value" : "RS256"
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 826,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 827,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 828,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 829,
+ "combination" : [ "default", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 830,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 831,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 832,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 833,
+ "combination" : [ "default", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 834,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 835,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 836,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 837,
+ "combination" : [ "default", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 838,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 839,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 840,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 841,
+ "combination" : [ "default", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 842,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 843,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 844,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 845,
+ "combination" : [ "default", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 846,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 847,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 848,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 849,
+ "combination" : [ "default", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 850,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 851,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 852,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 853,
+ "combination" : [ "default", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 854,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 855,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 856,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 857,
+ "combination" : [ "default", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 858,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 859,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 860,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 861,
+ "combination" : [ "default", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 862,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 863,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 864,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 865,
+ "combination" : [ "default", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 866,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 867,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 868,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 869,
+ "combination" : [ "default", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 870,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 871,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 872,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 873,
+ "combination" : [ "default", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 874,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 875,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 876,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 877,
+ "combination" : [ "default", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 878,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 879,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 880,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 881,
+ "combination" : [ "default", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 882,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 883,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 884,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 885,
+ "combination" : [ "default", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 886,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 887,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 888,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 889,
+ "combination" : [ "default", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 890,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 891,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 892,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 893,
+ "combination" : [ "default", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 894,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 895,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 896,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 897,
+ "combination" : [ "default", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 898,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "resolved" : {
+ "require_auth_time" : true
+ }
+ },
+ {
+ "n" : 899,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 900,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 901,
+ "combination" : [ "default", "value" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "resolved" : {
+ "require_auth_time" : true
+ }
+ },
+ {
+ "n" : 902,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "resolved" : {
+ "require_auth_time" : false
+ }
+ },
+ {
+ "n" : 903,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 904,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 905,
+ "combination" : [ "default", "value" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "resolved" : {
+ "require_auth_time" : false
+ }
+ },
+ {
+ "n" : 906,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "resolved" : {
+ "require_auth_time" : true
+ }
+ },
+ {
+ "n" : 907,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 908,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 909,
+ "combination" : [ "default", "value" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "resolved" : {
+ "require_auth_time" : true
+ }
+ },
+ {
+ "n" : 910,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "resolved" : {
+ "require_auth_time" : false
+ }
+ },
+ {
+ "n" : 911,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 912,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 913,
+ "combination" : [ "default", "value" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "resolved" : {
+ "require_auth_time" : false
+ }
+ },
+ {
+ "n" : 914,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "resolved" : {
+ "require_auth_time" : true
+ }
+ },
+ {
+ "n" : 915,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 916,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 917,
+ "combination" : [ "default", "value" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "resolved" : {
+ "require_auth_time" : true
+ }
+ },
+ {
+ "n" : 918,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "resolved" : {
+ "require_auth_time" : false
+ }
+ },
+ {
+ "n" : 919,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 920,
+ "combination" : [ "default", "value", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 921,
+ "combination" : [ "default", "value" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "resolved" : {
+ "require_auth_time" : false
+ }
+ },
+ {
+ "n" : 922,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 923,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 924,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 925,
+ "combination" : [ "default", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 926,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password", "authorization_code" ]
+ }
+ },
+ {
+ "n" : 927,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password", "authorization_code" ]
+ }
+ },
+ {
+ "n" : 928,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password", "authorization_code" ]
+ }
+ },
+ {
+ "n" : 929,
+ "combination" : [ "default", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password", "authorization_code" ]
+ }
+ },
+ {
+ "n" : 930,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 931,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 932,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 933,
+ "combination" : [ "default", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 934,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 935,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 936,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 937,
+ "combination" : [ "default", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 938,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 939,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 940,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 941,
+ "combination" : [ "default", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 942,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 943,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 944,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 945,
+ "combination" : [ "default", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "default" : [ ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 946,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 947,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 948,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 949,
+ "combination" : [ "default", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 950,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password", "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 951,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password", "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 952,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password", "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 953,
+ "combination" : [ "default", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password", "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 954,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 955,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 956,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 957,
+ "combination" : [ "default", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 958,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 959,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 960,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 961,
+ "combination" : [ "default", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 962,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 963,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 964,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 965,
+ "combination" : [ "default", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 966,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 967,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 968,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 969,
+ "combination" : [ "default", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 970,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 971,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 972,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 973,
+ "combination" : [ "default", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 974,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password", "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 975,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password", "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 976,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password", "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 977,
+ "combination" : [ "default", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password", "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 978,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 979,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 980,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 981,
+ "combination" : [ "default", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 982,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 983,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 984,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 985,
+ "combination" : [ "default", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 986,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 987,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 988,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 989,
+ "combination" : [ "default", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 990,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 991,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 992,
+ "combination" : [ "default", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 993,
+ "combination" : [ "default", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 994,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "RS256"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 995,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256"
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "RS256"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 996,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256"
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "RS256"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 997,
+ "combination" : [ "default", "default" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256"
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256"
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256"
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "RS256"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 998,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "EdDSA"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "EdDSA"
+ }
+ },
+ {
+ "n" : 999,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256"
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "EdDSA"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "EdDSA"
+ }
+ },
+ {
+ "n" : 1000,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256"
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "EdDSA"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "EdDSA"
+ }
+ },
+ {
+ "n" : 1001,
+ "combination" : [ "default", "default" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256"
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256"
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256"
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "EdDSA"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "EdDSA"
+ }
+ },
+ {
+ "n" : 1002,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 1003,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256"
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 1004,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256"
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 1005,
+ "combination" : [ "default", "default" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256"
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256"
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256"
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 1006,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1007,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1008,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1009,
+ "combination" : [ "default", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1010,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1011,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1012,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1013,
+ "combination" : [ "default", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1014,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1015,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1016,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1017,
+ "combination" : [ "default", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1018,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1019,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1020,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1021,
+ "combination" : [ "default", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1022,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1023,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1024,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1025,
+ "combination" : [ "default", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1026,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1027,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1028,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1029,
+ "combination" : [ "default", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1030,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1031,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1032,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1033,
+ "combination" : [ "default", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1034,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1035,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1036,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1037,
+ "combination" : [ "default", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1038,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1039,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1040,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1041,
+ "combination" : [ "default", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1042,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1043,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1044,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1045,
+ "combination" : [ "default", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1046,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1047,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1048,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1049,
+ "combination" : [ "default", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1050,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1051,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1052,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1053,
+ "combination" : [ "default", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1054,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1055,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1056,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1057,
+ "combination" : [ "default", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1058,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1059,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1060,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1061,
+ "combination" : [ "default", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1062,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1063,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1064,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1065,
+ "combination" : [ "default", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1066,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1067,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1068,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1069,
+ "combination" : [ "default", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1070,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1071,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1072,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1073,
+ "combination" : [ "default", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1074,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1075,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1076,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1077,
+ "combination" : [ "default", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1078,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "resolved" : {
+ "require_auth_time" : true
+ }
+ },
+ {
+ "n" : 1079,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1080,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1081,
+ "combination" : [ "default", "default" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "resolved" : {
+ "require_auth_time" : true
+ }
+ },
+ {
+ "n" : 1082,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "resolved" : {
+ "require_auth_time" : false
+ }
+ },
+ {
+ "n" : 1083,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1084,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1085,
+ "combination" : [ "default", "default" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "resolved" : {
+ "require_auth_time" : false
+ }
+ },
+ {
+ "n" : 1086,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "resolved" : {
+ "require_auth_time" : true
+ }
+ },
+ {
+ "n" : 1087,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1088,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1089,
+ "combination" : [ "default", "default" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "resolved" : {
+ "require_auth_time" : true
+ }
+ },
+ {
+ "n" : 1090,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "resolved" : {
+ "require_auth_time" : false
+ }
+ },
+ {
+ "n" : 1091,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1092,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1093,
+ "combination" : [ "default", "default" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "resolved" : {
+ "require_auth_time" : false
+ }
+ },
+ {
+ "n" : 1094,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "resolved" : {
+ "require_auth_time" : true
+ }
+ },
+ {
+ "n" : 1095,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1096,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1097,
+ "combination" : [ "default", "default" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : true
+ },
+ "resolved" : {
+ "require_auth_time" : true
+ }
+ },
+ {
+ "n" : 1098,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "resolved" : {
+ "require_auth_time" : false
+ }
+ },
+ {
+ "n" : 1099,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1100,
+ "combination" : [ "default", "default", "essential" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : true
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate require_auth_time policy: Subordinate default operator does not match"
+ },
+ {
+ "n" : 1101,
+ "combination" : [ "default", "default" ],
+ "TA" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "INT" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "merged" : {
+ "require_auth_time" : {
+ "default" : false
+ }
+ },
+ "metadata" : {
+ "require_auth_time" : false
+ },
+ "resolved" : {
+ "require_auth_time" : false
+ }
+ },
+ {
+ "n" : 1102,
+ "combination" : [ "default", "one_of", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "RS256"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 1103,
+ "combination" : [ "default", "one_of", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ]
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "RS256"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 1104,
+ "combination" : [ "default", "one_of", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256"
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "RS256"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 1105,
+ "combination" : [ "default", "one_of" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256"
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ]
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "one_of" : [ "RS256", "ES256" ]
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "RS256"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 1106,
+ "combination" : [ "default", "one_of", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "EdDSA"
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid id_token_signed_response_alg: Failed one_of check"
+ },
+ {
+ "n" : 1107,
+ "combination" : [ "default", "one_of", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ]
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "EdDSA"
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid id_token_signed_response_alg: Failed one_of check"
+ },
+ {
+ "n" : 1108,
+ "combination" : [ "default", "one_of", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256"
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "EdDSA"
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid id_token_signed_response_alg: Failed one_of check"
+ },
+ {
+ "n" : 1109,
+ "combination" : [ "default", "one_of" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256"
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ]
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "one_of" : [ "RS256", "ES256" ]
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "EdDSA"
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid id_token_signed_response_alg: Failed one_of check"
+ },
+ {
+ "n" : 1110,
+ "combination" : [ "default", "one_of", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 1111,
+ "combination" : [ "default", "one_of", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ]
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 1112,
+ "combination" : [ "default", "one_of", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256"
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 1113,
+ "combination" : [ "default", "one_of" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256"
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ]
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "one_of" : [ "RS256", "ES256" ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 1114,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1115,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1116,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1117,
+ "combination" : [ "default", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1118,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1119,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1120,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1121,
+ "combination" : [ "default", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1122,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1123,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1124,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1125,
+ "combination" : [ "default", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1126,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1127,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1128,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1129,
+ "combination" : [ "default", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1130,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1131,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1132,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1133,
+ "combination" : [ "default", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1134,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1135,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1136,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1137,
+ "combination" : [ "default", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1138,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1139,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1140,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1141,
+ "combination" : [ "default", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1142,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1143,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1144,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1145,
+ "combination" : [ "default", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1146,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1147,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1148,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1149,
+ "combination" : [ "default", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1150,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1151,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1152,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1153,
+ "combination" : [ "default", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1154,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1155,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1156,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1157,
+ "combination" : [ "default", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1158,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1159,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1160,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1161,
+ "combination" : [ "default", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1162,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1163,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1164,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1165,
+ "combination" : [ "default", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1166,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1167,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1168,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1169,
+ "combination" : [ "default", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1170,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1171,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1172,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1173,
+ "combination" : [ "default", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1174,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1175,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1176,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1177,
+ "combination" : [ "default", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1178,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1179,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1180,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1181,
+ "combination" : [ "default", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1182,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1183,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1184,
+ "combination" : [ "default", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1185,
+ "combination" : [ "default", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1186,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1187,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1188,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1189,
+ "combination" : [ "default", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1190,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1191,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1192,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1193,
+ "combination" : [ "default", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1194,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1195,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1196,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1197,
+ "combination" : [ "default", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1198,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 1199,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 1200,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 1201,
+ "combination" : [ "default", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 1202,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1203,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1204,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1205,
+ "combination" : [ "default", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1206,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1207,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1208,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1209,
+ "combination" : [ "default", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1210,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1211,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1212,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1213,
+ "combination" : [ "default", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1214,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1215,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1216,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1217,
+ "combination" : [ "default", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1218,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1219,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1220,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1221,
+ "combination" : [ "default", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1222,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1223,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1224,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1225,
+ "combination" : [ "default", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1226,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1227,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1228,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1229,
+ "combination" : [ "default", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1230,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1231,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1232,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1233,
+ "combination" : [ "default", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ ],
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1234,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1235,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1236,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1237,
+ "combination" : [ "default", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1238,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1239,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1240,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1241,
+ "combination" : [ "default", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1242,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1243,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1244,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1245,
+ "combination" : [ "default", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1246,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1247,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1248,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1249,
+ "combination" : [ "default", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1250,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1251,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1252,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1253,
+ "combination" : [ "default", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1254,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1255,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1256,
+ "combination" : [ "default", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1257,
+ "combination" : [ "default", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1258,
+ "combination" : [ "one_of", "value", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "RS256"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 1259,
+ "combination" : [ "one_of", "value", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256"
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "RS256"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 1260,
+ "combination" : [ "one_of", "value", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ]
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "RS256"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 1261,
+ "combination" : [ "one_of", "value" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ]
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256"
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "value" : "RS256"
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "RS256"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 1262,
+ "combination" : [ "one_of", "value", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "EdDSA"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 1263,
+ "combination" : [ "one_of", "value", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256"
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "EdDSA"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 1264,
+ "combination" : [ "one_of", "value", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ]
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "EdDSA"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 1265,
+ "combination" : [ "one_of", "value" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ]
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256"
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "value" : "RS256"
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "EdDSA"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 1266,
+ "combination" : [ "one_of", "value", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 1267,
+ "combination" : [ "one_of", "value", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256"
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 1268,
+ "combination" : [ "one_of", "value", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ]
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "value" : "RS256",
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 1269,
+ "combination" : [ "one_of", "value" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ]
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "value" : "RS256"
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "value" : "RS256"
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 1270,
+ "combination" : [ "one_of", "default", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "RS256"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 1271,
+ "combination" : [ "one_of", "default", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256"
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "RS256"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 1272,
+ "combination" : [ "one_of", "default", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ]
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "RS256"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 1273,
+ "combination" : [ "one_of", "default" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ]
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256"
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "one_of" : [ "RS256", "ES256" ]
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "RS256"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 1274,
+ "combination" : [ "one_of", "default", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "EdDSA"
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid id_token_signed_response_alg: Failed one_of check"
+ },
+ {
+ "n" : 1275,
+ "combination" : [ "one_of", "default", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256"
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "EdDSA"
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid id_token_signed_response_alg: Failed one_of check"
+ },
+ {
+ "n" : 1276,
+ "combination" : [ "one_of", "default", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ]
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "EdDSA"
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid id_token_signed_response_alg: Failed one_of check"
+ },
+ {
+ "n" : 1277,
+ "combination" : [ "one_of", "default" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ]
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256"
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "one_of" : [ "RS256", "ES256" ]
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "EdDSA"
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid id_token_signed_response_alg: Failed one_of check"
+ },
+ {
+ "n" : 1278,
+ "combination" : [ "one_of", "default", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 1279,
+ "combination" : [ "one_of", "default", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256"
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 1280,
+ "combination" : [ "one_of", "default", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ]
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 1281,
+ "combination" : [ "one_of", "default" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ]
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256"
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "default" : "RS256",
+ "one_of" : [ "RS256", "ES256" ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 1282,
+ "combination" : [ "one_of", "one_of", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "RS256"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 1283,
+ "combination" : [ "one_of", "one_of", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ]
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "RS256"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 1284,
+ "combination" : [ "one_of", "one_of", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ]
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "RS256"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 1285,
+ "combination" : [ "one_of", "one_of" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ]
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ]
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ]
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "RS256"
+ },
+ "resolved" : {
+ "id_token_signed_response_alg" : "RS256"
+ }
+ },
+ {
+ "n" : 1286,
+ "combination" : [ "one_of", "one_of", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "EdDSA"
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid id_token_signed_response_alg: Failed one_of check"
+ },
+ {
+ "n" : 1287,
+ "combination" : [ "one_of", "one_of", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ]
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "EdDSA"
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid id_token_signed_response_alg: Failed one_of check"
+ },
+ {
+ "n" : 1288,
+ "combination" : [ "one_of", "one_of", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ]
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "EdDSA"
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid id_token_signed_response_alg: Failed one_of check"
+ },
+ {
+ "n" : 1289,
+ "combination" : [ "one_of", "one_of" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ]
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ]
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ]
+ }
+ },
+ "metadata" : {
+ "id_token_signed_response_alg" : "EdDSA"
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid id_token_signed_response_alg: Failed one_of check"
+ },
+ {
+ "n" : 1290,
+ "combination" : [ "one_of", "one_of", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid id_token_signed_response_alg: Failed essential check"
+ },
+ {
+ "n" : 1291,
+ "combination" : [ "one_of", "one_of", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ]
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid id_token_signed_response_alg: Failed essential check"
+ },
+ {
+ "n" : 1292,
+ "combination" : [ "one_of", "one_of", "essential" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ]
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid id_token_signed_response_alg: Failed essential check"
+ },
+ {
+ "n" : 1293,
+ "combination" : [ "one_of", "one_of" ],
+ "TA" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ]
+ }
+ },
+ "INT" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ]
+ }
+ },
+ "merged" : {
+ "id_token_signed_response_alg" : {
+ "one_of" : [ "RS256", "ES256" ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : { }
+ },
+ {
+ "n" : 1294,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1295,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1296,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1297,
+ "combination" : [ "subset_of", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1298,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1299,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1300,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1301,
+ "combination" : [ "subset_of", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1302,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1303,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1304,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1305,
+ "combination" : [ "subset_of", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1306,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1307,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1308,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1309,
+ "combination" : [ "subset_of", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1310,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1311,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1312,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1313,
+ "combination" : [ "subset_of", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1314,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1315,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1316,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1317,
+ "combination" : [ "subset_of", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1318,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1319,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1320,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1321,
+ "combination" : [ "subset_of", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1322,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1323,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1324,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1325,
+ "combination" : [ "subset_of", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1326,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1327,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1328,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1329,
+ "combination" : [ "subset_of", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1330,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1331,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1332,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1333,
+ "combination" : [ "subset_of", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1334,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1335,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1336,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1337,
+ "combination" : [ "subset_of", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1338,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1339,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1340,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1341,
+ "combination" : [ "subset_of", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1342,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1343,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1344,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1345,
+ "combination" : [ "subset_of", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1346,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1347,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1348,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1349,
+ "combination" : [ "subset_of", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1350,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1351,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1352,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1353,
+ "combination" : [ "subset_of", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1354,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1355,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1356,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1357,
+ "combination" : [ "subset_of", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1358,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1359,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1360,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1361,
+ "combination" : [ "subset_of", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1362,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1363,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1364,
+ "combination" : [ "subset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1365,
+ "combination" : [ "subset_of", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ value operator combination: The value must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1366,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1367,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1368,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1369,
+ "combination" : [ "subset_of", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1370,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1371,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1372,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1373,
+ "combination" : [ "subset_of", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1374,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1375,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1376,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1377,
+ "combination" : [ "subset_of", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1378,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1379,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1380,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1381,
+ "combination" : [ "subset_of", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1382,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1383,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1384,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1385,
+ "combination" : [ "subset_of", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1386,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1387,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1388,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1389,
+ "combination" : [ "subset_of", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1390,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1391,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1392,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1393,
+ "combination" : [ "subset_of", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1394,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1395,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1396,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1397,
+ "combination" : [ "subset_of", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1398,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1399,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1400,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1401,
+ "combination" : [ "subset_of", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1402,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1403,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1404,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1405,
+ "combination" : [ "subset_of", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1406,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1407,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1408,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1409,
+ "combination" : [ "subset_of", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1410,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1411,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1412,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1413,
+ "combination" : [ "subset_of", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1414,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1415,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1416,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1417,
+ "combination" : [ "subset_of", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1418,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1419,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1420,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1421,
+ "combination" : [ "subset_of", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1422,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1423,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1424,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1425,
+ "combination" : [ "subset_of", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1426,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1427,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1428,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1429,
+ "combination" : [ "subset_of", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1430,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1431,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1432,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1433,
+ "combination" : [ "subset_of", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1434,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1435,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1436,
+ "combination" : [ "subset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1437,
+ "combination" : [ "subset_of", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ add operator combination: The values of add must be a subset of the values of subset_of"
+ },
+ {
+ "n" : 1438,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1439,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1440,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1441,
+ "combination" : [ "subset_of", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1442,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1443,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1444,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1445,
+ "combination" : [ "subset_of", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1446,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1447,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1448,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1449,
+ "combination" : [ "subset_of", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1450,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1451,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1452,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1453,
+ "combination" : [ "subset_of", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1454,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1455,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1456,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1457,
+ "combination" : [ "subset_of", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1458,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1459,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1460,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1461,
+ "combination" : [ "subset_of", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "subset_of" : [ ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1462,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1463,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1464,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1465,
+ "combination" : [ "subset_of", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1466,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1467,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1468,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1469,
+ "combination" : [ "subset_of", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1470,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1471,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1472,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1473,
+ "combination" : [ "subset_of", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1474,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1475,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1476,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1477,
+ "combination" : [ "subset_of", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1478,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1479,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1480,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1481,
+ "combination" : [ "subset_of", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1482,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1483,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1484,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1485,
+ "combination" : [ "subset_of", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1486,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1487,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1488,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1489,
+ "combination" : [ "subset_of", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1490,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1491,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1492,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1493,
+ "combination" : [ "subset_of", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1494,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1495,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1496,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1497,
+ "combination" : [ "subset_of", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1498,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1499,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1500,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1501,
+ "combination" : [ "subset_of", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1502,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1503,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1504,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1505,
+ "combination" : [ "subset_of", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1506,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1507,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1508,
+ "combination" : [ "subset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1509,
+ "combination" : [ "subset_of", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1510,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1511,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1512,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1513,
+ "combination" : [ "subset_of", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1514,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1515,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1516,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1517,
+ "combination" : [ "subset_of", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1518,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1519,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1520,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1521,
+ "combination" : [ "subset_of", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1522,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1523,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1524,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1525,
+ "combination" : [ "subset_of", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1526,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1527,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1528,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1529,
+ "combination" : [ "subset_of", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1530,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed essential check"
+ },
+ {
+ "n" : 1531,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed essential check"
+ },
+ {
+ "n" : 1532,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed essential check"
+ },
+ {
+ "n" : 1533,
+ "combination" : [ "subset_of", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : { }
+ },
+ {
+ "n" : 1534,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1535,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1536,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1537,
+ "combination" : [ "subset_of", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1538,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1539,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1540,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1541,
+ "combination" : [ "subset_of", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1542,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1543,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1544,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1545,
+ "combination" : [ "subset_of", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1546,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1547,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1548,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1549,
+ "combination" : [ "subset_of", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1550,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1551,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1552,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1553,
+ "combination" : [ "subset_of", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1554,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed essential check"
+ },
+ {
+ "n" : 1555,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed essential check"
+ },
+ {
+ "n" : 1556,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed essential check"
+ },
+ {
+ "n" : 1557,
+ "combination" : [ "subset_of", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : { }
+ },
+ {
+ "n" : 1558,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1559,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1560,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1561,
+ "combination" : [ "subset_of", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1562,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1563,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1564,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1565,
+ "combination" : [ "subset_of", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1566,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1567,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1568,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1569,
+ "combination" : [ "subset_of", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1570,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1571,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1572,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1573,
+ "combination" : [ "subset_of", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1574,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1575,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1576,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1577,
+ "combination" : [ "subset_of", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1578,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed essential check"
+ },
+ {
+ "n" : 1579,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed essential check"
+ },
+ {
+ "n" : 1580,
+ "combination" : [ "subset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed essential check"
+ },
+ {
+ "n" : 1581,
+ "combination" : [ "subset_of", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : { }
+ },
+ {
+ "n" : 1582,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1583,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1584,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1585,
+ "combination" : [ "subset_of", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1586,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1587,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1588,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1589,
+ "combination" : [ "subset_of", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1590,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1591,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1592,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1593,
+ "combination" : [ "subset_of", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1594,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1595,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1596,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1597,
+ "combination" : [ "subset_of", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1598,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1599,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1600,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1601,
+ "combination" : [ "subset_of", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1602,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1603,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1604,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1605,
+ "combination" : [ "subset_of", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1606,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1607,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1608,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1609,
+ "combination" : [ "subset_of", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1610,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1611,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1612,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1613,
+ "combination" : [ "subset_of", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1614,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1615,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1616,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1617,
+ "combination" : [ "subset_of", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1618,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1619,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1620,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1621,
+ "combination" : [ "subset_of", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1622,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1623,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1624,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1625,
+ "combination" : [ "subset_of", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1626,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1627,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1628,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1629,
+ "combination" : [ "subset_of", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1630,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1631,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1632,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1633,
+ "combination" : [ "subset_of", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1634,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1635,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1636,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1637,
+ "combination" : [ "subset_of", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1638,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1639,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1640,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1641,
+ "combination" : [ "subset_of", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1642,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1643,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1644,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1645,
+ "combination" : [ "subset_of", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1646,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1647,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1648,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1649,
+ "combination" : [ "subset_of", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1650,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1651,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1652,
+ "combination" : [ "subset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1653,
+ "combination" : [ "subset_of", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate grant_types policy: Illegal subset_of \/ superset_of operator combination: The values of subset_of must be a superset of the values of superset_of"
+ },
+ {
+ "n" : 1654,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1655,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1656,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1657,
+ "combination" : [ "superset_of", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1658,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1659,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1660,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1661,
+ "combination" : [ "superset_of", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1662,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1663,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1664,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1665,
+ "combination" : [ "superset_of", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1666,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1667,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1668,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1669,
+ "combination" : [ "superset_of", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1670,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1671,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1672,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1673,
+ "combination" : [ "superset_of", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1674,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1675,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1676,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1677,
+ "combination" : [ "superset_of", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1678,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1679,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1680,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1681,
+ "combination" : [ "superset_of", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1682,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1683,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1684,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1685,
+ "combination" : [ "superset_of", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1686,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1687,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1688,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1689,
+ "combination" : [ "superset_of", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1690,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1691,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1692,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1693,
+ "combination" : [ "superset_of", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1694,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1695,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1696,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1697,
+ "combination" : [ "superset_of", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1698,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1699,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1700,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1701,
+ "combination" : [ "superset_of", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1702,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1703,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1704,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1705,
+ "combination" : [ "superset_of", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1706,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1707,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1708,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1709,
+ "combination" : [ "superset_of", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1710,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1711,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1712,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1713,
+ "combination" : [ "superset_of", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1714,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1715,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1716,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1717,
+ "combination" : [ "superset_of", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1718,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1719,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1720,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1721,
+ "combination" : [ "superset_of", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1722,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1723,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1724,
+ "combination" : [ "superset_of", "value", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1725,
+ "combination" : [ "superset_of", "value" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "value" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1726,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1727,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1728,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1729,
+ "combination" : [ "superset_of", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1730,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password", "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1731,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password", "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1732,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password", "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1733,
+ "combination" : [ "superset_of", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password", "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1734,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1735,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1736,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1737,
+ "combination" : [ "superset_of", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1738,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 1739,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 1740,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 1741,
+ "combination" : [ "superset_of", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 1742,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1743,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1744,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1745,
+ "combination" : [ "superset_of", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1746,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1747,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1748,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1749,
+ "combination" : [ "superset_of", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code" ],
+ "superset_of" : [ ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1750,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1751,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1752,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1753,
+ "combination" : [ "superset_of", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1754,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password", "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1755,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password", "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1756,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password", "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1757,
+ "combination" : [ "superset_of", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password", "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1758,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1759,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1760,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1761,
+ "combination" : [ "superset_of", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1762,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1763,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1764,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1765,
+ "combination" : [ "superset_of", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1766,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1767,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1768,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1769,
+ "combination" : [ "superset_of", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1770,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1771,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1772,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1773,
+ "combination" : [ "superset_of", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1774,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1775,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1776,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1777,
+ "combination" : [ "superset_of", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1778,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password", "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1779,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password", "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1780,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password", "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1781,
+ "combination" : [ "superset_of", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password", "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1782,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1783,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1784,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1785,
+ "combination" : [ "superset_of", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1786,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1787,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1788,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1789,
+ "combination" : [ "superset_of", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1790,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1791,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1792,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1793,
+ "combination" : [ "superset_of", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1794,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1795,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1796,
+ "combination" : [ "superset_of", "add", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1797,
+ "combination" : [ "superset_of", "add" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "add" : [ "authorization_code", "refresh_token" ],
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1798,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1799,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1800,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1801,
+ "combination" : [ "superset_of", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1802,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password" ]
+ }
+ },
+ {
+ "n" : 1803,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password" ]
+ }
+ },
+ {
+ "n" : 1804,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password" ]
+ }
+ },
+ {
+ "n" : 1805,
+ "combination" : [ "superset_of", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password" ]
+ }
+ },
+ {
+ "n" : 1806,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1807,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1808,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1809,
+ "combination" : [ "superset_of", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1810,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 1811,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 1812,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 1813,
+ "combination" : [ "superset_of", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 1814,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1815,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1816,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1817,
+ "combination" : [ "superset_of", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1818,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1819,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1820,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1821,
+ "combination" : [ "superset_of", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1822,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1823,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1824,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1825,
+ "combination" : [ "superset_of", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1826,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password" ]
+ }
+ },
+ {
+ "n" : 1827,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password" ]
+ }
+ },
+ {
+ "n" : 1828,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password" ]
+ }
+ },
+ {
+ "n" : 1829,
+ "combination" : [ "superset_of", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "password" ]
+ }
+ },
+ {
+ "n" : 1830,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1831,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1832,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1833,
+ "combination" : [ "superset_of", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1834,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 1835,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 1836,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 1837,
+ "combination" : [ "superset_of", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 1838,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1839,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1840,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1841,
+ "combination" : [ "superset_of", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1842,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1843,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1844,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1845,
+ "combination" : [ "superset_of", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1846,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1847,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1848,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1849,
+ "combination" : [ "superset_of", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1850,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1851,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1852,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1853,
+ "combination" : [ "superset_of", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1854,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1855,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1856,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1857,
+ "combination" : [ "superset_of", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1858,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 1859,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 1860,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 1861,
+ "combination" : [ "superset_of", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 1862,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1863,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1864,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1865,
+ "combination" : [ "superset_of", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1866,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1867,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1868,
+ "combination" : [ "superset_of", "default", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1869,
+ "combination" : [ "superset_of", "default" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "default" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1870,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1871,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1872,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1873,
+ "combination" : [ "superset_of", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1874,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1875,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1876,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1877,
+ "combination" : [ "superset_of", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1878,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1879,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1880,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1881,
+ "combination" : [ "superset_of", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1882,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1883,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1884,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1885,
+ "combination" : [ "superset_of", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1886,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1887,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1888,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1889,
+ "combination" : [ "superset_of", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1890,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed essential check"
+ },
+ {
+ "n" : 1891,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed essential check"
+ },
+ {
+ "n" : 1892,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed essential check"
+ },
+ {
+ "n" : 1893,
+ "combination" : [ "superset_of", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : { }
+ },
+ {
+ "n" : 1894,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1895,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1896,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1897,
+ "combination" : [ "superset_of", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1898,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1899,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1900,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1901,
+ "combination" : [ "superset_of", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1902,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1903,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1904,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1905,
+ "combination" : [ "superset_of", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1906,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1907,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1908,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1909,
+ "combination" : [ "superset_of", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1910,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1911,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1912,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1913,
+ "combination" : [ "superset_of", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "resolved" : {
+ "grant_types" : [ ]
+ }
+ },
+ {
+ "n" : 1914,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed essential check"
+ },
+ {
+ "n" : 1915,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed essential check"
+ },
+ {
+ "n" : 1916,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed essential check"
+ },
+ {
+ "n" : 1917,
+ "combination" : [ "superset_of", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : { }
+ },
+ {
+ "n" : 1918,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1919,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1920,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1921,
+ "combination" : [ "superset_of", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1922,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1923,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1924,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1925,
+ "combination" : [ "superset_of", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1926,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1927,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1928,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1929,
+ "combination" : [ "superset_of", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1930,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1931,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1932,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1933,
+ "combination" : [ "superset_of", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1934,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1935,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1936,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1937,
+ "combination" : [ "superset_of", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1938,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed essential check"
+ },
+ {
+ "n" : 1939,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed essential check"
+ },
+ {
+ "n" : 1940,
+ "combination" : [ "superset_of", "subset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed essential check"
+ },
+ {
+ "n" : 1941,
+ "combination" : [ "superset_of", "subset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "subset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : { }
+ },
+ {
+ "n" : 1942,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1943,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1944,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1945,
+ "combination" : [ "superset_of", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code" ]
+ }
+ },
+ {
+ "n" : 1946,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1947,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1948,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1949,
+ "combination" : [ "superset_of", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1950,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1951,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1952,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1953,
+ "combination" : [ "superset_of", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1954,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 1955,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 1956,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 1957,
+ "combination" : [ "superset_of", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ }
+ },
+ {
+ "n" : 1958,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1959,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1960,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1961,
+ "combination" : [ "superset_of", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1962,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed essential check"
+ },
+ {
+ "n" : 1963,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed essential check"
+ },
+ {
+ "n" : 1964,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed essential check"
+ },
+ {
+ "n" : 1965,
+ "combination" : [ "superset_of", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : { }
+ },
+ {
+ "n" : 1966,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1967,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1968,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1969,
+ "combination" : [ "superset_of", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1970,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1971,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1972,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1973,
+ "combination" : [ "superset_of", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1974,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1975,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1976,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1977,
+ "combination" : [ "superset_of", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1978,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1979,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1980,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1981,
+ "combination" : [ "superset_of", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1982,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1983,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1984,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1985,
+ "combination" : [ "superset_of", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1986,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed essential check"
+ },
+ {
+ "n" : 1987,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed essential check"
+ },
+ {
+ "n" : 1988,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed essential check"
+ },
+ {
+ "n" : 1989,
+ "combination" : [ "superset_of", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : { }
+ },
+ {
+ "n" : 1990,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1991,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1992,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1993,
+ "combination" : [ "superset_of", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1994,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1995,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1996,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1997,
+ "combination" : [ "superset_of", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 1998,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 1999,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 2000,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 2001,
+ "combination" : [ "superset_of", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ },
+ "resolved" : {
+ "grant_types" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ {
+ "n" : 2002,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 2003,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 2004,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 2005,
+ "combination" : [ "superset_of", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ "authorization_code", "password" ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 2006,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 2007,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 2008,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 2009,
+ "combination" : [ "superset_of", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : {
+ "grant_types" : [ ]
+ },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed superset_of check"
+ },
+ {
+ "n" : 2010,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed essential check"
+ },
+ {
+ "n" : 2011,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ],
+ "essential" : true
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed essential check"
+ },
+ {
+ "n" : 2012,
+ "combination" : [ "superset_of", "superset_of", "essential" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ],
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_metadata",
+ "error_description" : "Invalid grant_types: Failed essential check"
+ },
+ {
+ "n" : 2013,
+ "combination" : [ "superset_of", "superset_of" ],
+ "TA" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code" ]
+ }
+ },
+ "INT" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "merged" : {
+ "grant_types" : {
+ "superset_of" : [ "authorization_code", "refresh_token" ]
+ }
+ },
+ "metadata" : { },
+ "resolved" : { }
+ },
+ {
+ "n" : 2014,
+ "combination" : [ "value", "essential" ],
+ "TA" : {
+ "logo_uri" : {
+ "value" : null
+ }
+ },
+ "INT" : {
+ "logo_uri" : {
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "logo_uri" : "https:\/\/example.com\/logo.png"
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate logo_uri policy: Illegal value \/ essential operator combination: The value must be non-null when essential is true"
+ },
+ {
+ "n" : 2015,
+ "combination" : [ "value", "essential" ],
+ "TA" : {
+ "logo_uri" : {
+ "value" : null
+ }
+ },
+ "INT" : {
+ "logo_uri" : {
+ "essential" : true
+ }
+ },
+ "metadata" : {
+ "logo_uri" : "https:\/\/images.example.com\/logo.jpg"
+ },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate logo_uri policy: Illegal value \/ essential operator combination: The value must be non-null when essential is true"
+ },
+ {
+ "n" : 2016,
+ "combination" : [ "value", "essential" ],
+ "TA" : {
+ "logo_uri" : {
+ "value" : null
+ }
+ },
+ "INT" : {
+ "logo_uri" : {
+ "essential" : true
+ }
+ },
+ "metadata" : { },
+ "error" : "invalid_policy",
+ "error_description" : "Subordinate policy merge error: Illegal subordinate logo_uri policy: Illegal value \/ essential operator combination: The value must be non-null when essential is true"
+ },
+ {
+ "n" : 2017,
+ "combination" : [ "value" ],
+ "TA" : {
+ "logo_uri" : {
+ "value" : null
+ }
+ },
+ "INT" : {
+ "logo_uri" : {
+ "essential" : false
+ }
+ },
+ "merged" : {
+ "logo_uri" : {
+ "value" : null,
+ "essential" : false
+ }
+ },
+ "metadata" : {
+ "logo_uri" : "https:\/\/example.com\/logo.png"
+ },
+ "resolved" : { }
+ },
+ {
+ "n" : 2018,
+ "combination" : [ "value" ],
+ "TA" : {
+ "logo_uri" : {
+ "value" : null
+ }
+ },
+ "INT" : {
+ "logo_uri" : {
+ "essential" : false
+ }
+ },
+ "merged" : {
+ "logo_uri" : {
+ "value" : null,
+ "essential" : false
+ }
+ },
+ "metadata" : {
+ "logo_uri" : "https:\/\/images.example.com\/logo.jpg"
+ },
+ "resolved" : { }
+ },
+ {
+ "n" : 2019,
+ "combination" : [ "value" ],
+ "TA" : {
+ "logo_uri" : {
+ "value" : null
+ }
+ },
+ "INT" : {
+ "logo_uri" : {
+ "essential" : false
+ }
+ },
+ "merged" : {
+ "logo_uri" : {
+ "value" : null,
+ "essential" : false
+ }
+ },
+ "metadata" : { },
+ "resolved" : { }
+ }
+]
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..b6ecfb4
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,216 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>net.shibboleth</groupId>
+ <artifactId>parent</artifactId>
+ <version>17.0.2</version>
+ </parent>
+
+ <groupId>net.shibboleth.idp.plugin.oidfed</groupId>
+ <artifactId>idp-plugin-oidfed-op-parent</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <name>Shibboleth IdP :: Plugins :: OpenID Federation plugin for OpenID Connect Provider</name>
+ <packaging>pom</packaging>
+ <description>Java OpenID Federation plugin for the Shibboleth IdP OpenID Connect Provider.</description>
+
+ <properties>
+ <shibboleth.projectName>java-idp-plugin-oidfed-op</shibboleth.projectName>
+ <idp.groupId>net.shibboleth.idp</idp.groupId>
+ <idp.version>5.0.0</idp.version>
+ <opensaml.groupId>org.opensaml</opensaml.groupId>
+ <opensaml.version>5.0.0</opensaml.version>
+ <okhttp3.mockserver.version>4.9.3</okhttp3.mockserver.version>
+ <shib-shared.testing.version>9.0.0</shib-shared.testing.version>
+ <okhttp3.tls.version>4.9.3</okhttp3.tls.version>
+ <oidc-config.groupId>net.shibboleth.idp.plugin.config.oidc</oidc-config.groupId>
+ <oidc-config.version>3.0.0</oidc-config.version>
+ <oidc-common.groupId>net.shibboleth.oidc</oidc-common.groupId>
+ <oidc-common.version>3.3.0</oidc-common.version>
+ <oidc-op.groupId>net.shibboleth.idp.plugin.oidc</oidc-op.groupId>
+ <oidc-op.version>4.4.0-SNAPSHOT</oidc-op.version>
+ <shib-shared.groupId>net.shibboleth</shib-shared.groupId>
+ <shib-shared.version>9.0.0</shib-shared.version>
+ <shib-profile.groupId>net.shibboleth</shib-profile.groupId>
+ <shib-profile.version>5.0.0</shib-profile.version>
+ <shib-attribute.groupId>net.shibboleth</shib-attribute.groupId>
+ <shib-attribute.version>5.0.0</shib-attribute.version>
+ <shib-metadata.groupId>net.shibboleth</shib-metadata.groupId>
+ <shib-metadata.version>5.0.0</shib-metadata.version>
+ <checkstyle.configLocation>${project.basedir}/resources/checkstyle/checkstyle.xml</checkstyle.configLocation>
+ </properties>
+
+ <modules>
+ <module>idp-oidfed-op-api</module>
+ <module>idp-oidfed-op-impl</module>
+ <module>idp-oidfed-op-dist</module>
+ </modules>
+
+ <dependencies>
+ <dependency>
+ <groupId>${slf4j.groupId}</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <!-- Project wide test Dependencies -->
+ <dependency>
+ <groupId>org.testng</groupId>
+ <artifactId>testng</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <dependencyManagement>
+ <!-- java-idp-oidfed-op project dependencies -->
+ <dependencies>
+ <!-- OIDC Shared config, which is a runtime dependency to the whole project -->
+ <dependency>
+ <groupId>${oidc-config.groupId}</groupId>
+ <artifactId>idp-plugin-oidc-config-impl</artifactId>
+ <version>${oidc-config.version}</version>
+ </dependency>
+ <!-- Its own dependencies -->
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>idp-plugin-oidfed-op-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>idp-plugin-oidfed-op-impl</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <!-- OIDC Common BOM when importing OIDC dependencies -->
+ <dependency>
+ <groupId>${oidc-common.groupId}</groupId>
+ <artifactId>oidc-common-bom</artifactId>
+ <version>${oidc-common.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ <!-- Import Dependencies: OP/Shib-Metadata/Attribute/Profile/Shared -->
+ <dependency>
+ <groupId>${oidc-op.groupId}</groupId>
+ <artifactId>idp-plugin-oidc-op-api</artifactId>
+ <version>${oidc-op.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${shib-shared.groupId}</groupId>
+ <artifactId>shib-shared-bom</artifactId>
+ <version>${shib-shared.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ <dependency>
+ <groupId>${shib-profile.groupId}</groupId>
+ <artifactId>shib-profile-bom</artifactId>
+ <version>${shib-profile.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ <dependency>
+ <groupId>${shib-attribute.groupId}</groupId>
+ <artifactId>shib-attribute-bom</artifactId>
+ <version>${shib-attribute.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ <dependency>
+ <groupId>${shib-metadata.groupId}</groupId>
+ <artifactId>shib-metadata-bom</artifactId>
+ <version>${shib-metadata.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ <!-- Shibboleth IdP BOM for importing IdP dependencies -->
+ <dependency>
+ <groupId>${idp.groupId}</groupId>
+ <artifactId>idp-bom</artifactId>
+ <version>${idp.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ <!-- Test dependencies -->
+ <dependency>
+ <groupId>com.squareup.okhttp3</groupId>
+ <artifactId>mockwebserver</artifactId>
+ <version>${okhttp3.mockserver.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.squareup.okhttp3</groupId>
+ <artifactId>okhttp-tls</artifactId>
+ <version>${okhttp3.tls.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${oidc-common.groupId}</groupId>
+ <artifactId>oidc-common-crypto-impl</artifactId>
+ <version>${oidc-common.version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>idp-plugin-oidfed-op-api</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ <type>test-jar</type>
+ </dependency>
+ <dependency>
+ <groupId>org.openjdk.nashorn</groupId>
+ <artifactId>nashorn-core</artifactId>
+ <version>${nashorn.jdk.version}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>net.shibboleth.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <configuration>
+ <links combine.children="append">
+ <link>${javadoc.url}/java-shib-shared/${shib-shared.version}</link>
+ <link>${javadoc.url}/java-opensaml/${opensaml.version}</link>
+ <link>${javadoc.url}/java-shib-metadata/${shib-metadata.version}</link>
+ <link>${javadoc.url}/java-shib-attribute/${shib-attribute.version}</link>
+ <link>${javadoc.url}/java-shib-profile/${shib-profile.version}</link>
+ <link>${javadoc.url}/java-identity-provider/${idp.version}</link>
+ <link>${javadoc.url}/java-oidc-common/${oidc-common.version}</link>
+ <link>${javadoc.url}/java-idp-oidc/${oidc-op.version}</link>
+ </links>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifestEntries>
+ <Automatic-Module-Name>${automatic.module.name}</Automatic-Module-Name>
+ <Implementation-Title>${project.artifactId}</Implementation-Title>
+ <Implementation-Version>${project.version}</Implementation-Version>
+ <Implementation-Vendor>shibboleth.net</Implementation-Vendor>
+ <Sealed>true</Sealed>
+ </manifestEntries>
+ </archive>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/resources/checkstyle/checkstyle.xml b/resources/checkstyle/checkstyle.xml
new file mode 100644
index 0000000..f456c13
--- /dev/null
+++ b/resources/checkstyle/checkstyle.xml
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.3//EN" "http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
+
+<!--
+ This configuration file was written by the eclipse-cs plugin configuration editor
+-->
+<!--
+ Checkstyle-Configuration: Shibboleth Checkstyle
+ Description: none
+-->
+<module name="Checker">
+ <property name="severity" value="warning"/>
+ <module name="SuppressWithPlainTextCommentFilter">
+ <property name="offCommentFormat" value="\bCheck[Ss]tyle:\s*([\w|]+)\s+OFF\b"/>
+ <property name="onCommentFormat" value="\bCheck[Ss]tyle:\s*([\w|]+)\s+ON\b"/>
+ <property name="checkFormat" value="$1"/>
+ </module>
+ <module name="TreeWalker">
+ <property name="tabWidth" value="4"/>
+ <module name="JavadocMethod"/>
+ <module name="JavadocType">
+ <property name="allowUnknownTags" value="true"/>
+ </module>
+ <module name="JavadocVariable"/>
+ <module name="JavadocStyle">
+ <property name="checkEmptyJavadoc" value="true"/>
+ </module>
+ <module name="ConstantName"/>
+ <module name="LocalFinalVariableName"/>
+ <module name="LocalVariableName"/>
+ <module name="MemberName"/>
+ <module name="MethodName"/>
+ <module name="PackageName"/>
+ <module name="ParameterName"/>
+ <module name="StaticVariableName"/>
+ <module name="TypeName"/>
+ <module name="AvoidStarImport"/>
+ <module name="IllegalImport"/>
+ <module name="RedundantImport"/>
+ <module name="UnusedImports"/>
+ <module name="MethodLength">
+ <property name="max" value="70"/>
+ </module>
+ <module name="ParameterNumber">
+ <property name="max" value="5"/>
+ </module>
+ <module name="EmptyForIteratorPad"/>
+ <module name="MethodParamPad"/>
+ <module name="ModifierOrder"/>
+ <module name="AvoidNestedBlocks"/>
+ <module name="LeftCurly"/>
+ <module name="NeedBraces"/>
+ <module name="RightCurly"/>
+ <module name="EmptyStatement"/>
+ <module name="EqualsHashCode"/>
+ <module name="HiddenField"/>
+ <module name="IllegalInstantiation"/>
+ <module name="InnerAssignment"/>
+ <module name="MissingSwitchDefault"/>
+ <module name="SimplifyBooleanExpression"/>
+ <module name="SimplifyBooleanReturn"/>
+ <module name="FinalClass"/>
+ <module name="HideUtilityClassConstructor"/>
+ <module name="VisibilityModifier"/>
+ <module name="ArrayTypeStyle"/>
+ <module name="UpperEll"/>
+ <module name="AnonInnerLength"/>
+ <module name="EmptyForInitializerPad"/>
+ <module name="CovariantEquals"/>
+ <module name="DefaultComesLast"/>
+ <module name="DeclarationOrder"/>
+ <module name="ExplicitInitialization"/>
+ <module name="FallThrough"/>
+ <module name="IllegalThrows"/>
+ <module name="MultipleVariableDeclarations"/>
+ <module name="PackageDeclaration"/>
+ <module name="ParameterAssignment"/>
+ <module name="ReturnCount">
+ <property name="max" value="8"/>
+ <property name="maxForVoid" value="8"/>
+ </module>
+ <module name="StringLiteralEquality"/>
+ <module name="SuperFinalize"/>
+ <module name="ArrayTrailingComma"/>
+ <module name="UnnecessaryParentheses"/>
+ <module name="MutableException"/>
+ <module name="ThrowsCount">
+ <property name="max" value="3"/>
+ </module>
+ <module name="CyclomaticComplexity"/>
+ <module name="TrailingComment"/>
+ <module name="EqualsAvoidNull"/>
+ <module name="ModifiedControlVariable"/>
+ <module name="FinalParameters">
+ <property name="tokens" value="METHOD_DEF,CTOR_DEF,LITERAL_CATCH"/>
+ </module>
+ <module name="FinalLocalVariable">
+ <property name="tokens" value="PARAMETER_DEF,VARIABLE_DEF"/>
+ <property name="validateEnhancedForLoopVariable" value="true"/>
+ </module>
+ <module name="SuppressionCommentFilter">
+ <property name="offCommentFormat" value="\bCheck[Ss]tyle:\s*([\w|]+)\s+OFF\b"/>
+ <property name="onCommentFormat" value="\bCheck[Ss]tyle:\s*([\w|]+)\s+ON\b"/>
+ <property name="checkFormat" value="$1"/>
+ </module>
+ <module name="MissingJavadocMethod"/>
+ <module name="MissingJavadocPackage"/>
+ <module name="MissingJavadocType"/>
+ <module name="InvalidJavadocPosition"/>
+ </module>
+ <module name="FileTabCharacter"/>
+ <module name="FileLength">
+ <property name="max" value="1000"/>
+ </module>
+ <module name="Header">
+ <property name="header" value="/*\n * Licensed under the Apache License, Version 2.0 (the "License");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an "AS IS" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, eit [...]
+ </module>
+ <module name="JavadocPackage"/>
+ <module name="LineLength">
+ <property name="max" value="120"/>
+ </module>
+</module>
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list