[java-oidfed-common] branch main updated: Refactor support classes for tests

Codeberg noreply at shibboleth.net
Thu Sep 17 16:41:38 UTC 2026


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

codeberg pushed a commit to branch main
in repository java-oidfed-common.

View the commit online:
https://codeberg.org/Shibboleth/java-oidfed-common/commit/6645c831e627dc2a6777da97f9d6ce3d29bccdbd

The following commit(s) were added to refs/heads/main by this push:
     new 6645c83  Refactor support classes for tests
6645c83 is described below

commit 6645c831e627dc2a6777da97f9d6ce3d29bccdbd
Author: Henri Mikkonen <henri.mikkonen at iki.fi>
AuthorDate: Thu Sep 17 19:41:14 2026 +0300

    Refactor support classes for tests
    
    - FederationJwtSupport builds SignedJWTs instead of EntityStatement object
      - This way oidfed-common-testing is more generic
    - JacksonTestingSupport in oidfed-common-impl contains ObjectMapper helper
---
 .../oidfed/flow/AbstractFederationFlowTest.java    |  63 ++------
 .../oidfed/flow/EntityConfigurationFlowTest.java   |   4 +-
 .../flow/TestTrustChainResolutionFlowTest.java     |  12 +-
 .../EntityConfigurationMetadataCacheTest.java      |  54 +++----
 .../flow/cache/SignedKeysetMetadataCacheTest.java  |  28 ++--
 .../SubordinateStatementMetadataCacheTest.java     |  57 ++++---
 .../flow/cache/TrustChainMetadataCacheTest.java    |  22 +--
 oidfed-common-impl/pom.xml                         |  15 ++
 .../metadata/jackson/JacksonTestingSupport.java    |  55 +++++++
 oidfed-common-testing/pom.xml                      |   9 +-
 .../oidfed/testing/FederationJwtSupport.java       |  83 +++++++++++
 .../oidfed/testing/TrustChainTestUtil.java         | 164 ---------------------
 12 files changed, 264 insertions(+), 302 deletions(-)

diff --git a/oidfed-common-conf-impl/src/test/java/net/shibboleth/oidfed/flow/AbstractFederationFlowTest.java b/oidfed-common-conf-impl/src/test/java/net/shibboleth/oidfed/flow/AbstractFederationFlowTest.java
index faf6519..38b2ed1 100644
--- a/oidfed-common-conf-impl/src/test/java/net/shibboleth/oidfed/flow/AbstractFederationFlowTest.java
+++ b/oidfed-common-conf-impl/src/test/java/net/shibboleth/oidfed/flow/AbstractFederationFlowTest.java
@@ -83,11 +83,8 @@ import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
 import net.minidev.json.JSONObject;
 import net.shibboleth.idp.test.flows.AbstractFlowTest;
-import net.shibboleth.oidc.security.credential.BasicJWKCredential;
-import net.shibboleth.oidc.security.credential.BasicJWKCredentialFactoryBean;
-import net.shibboleth.oidfed.metadata.EntityStatement;
 import net.shibboleth.oidfed.testing.TestFederationCredentials;
-import net.shibboleth.oidfed.testing.TrustChainTestUtil;
+import net.shibboleth.oidfed.testing.FederationJwtSupport;
 import net.shibboleth.shared.logic.Constraint;
 import net.shibboleth.shared.servlet.impl.HttpServletRequestResponseContext;
 
@@ -133,6 +130,10 @@ public class AbstractFederationFlowTest extends AbstractFlowTest {
     @Qualifier("shibboleth.oidfed.HttpClient")
     protected HttpClient federationHttpClient;
 
+    @Autowired
+    @Qualifier("shibboleth.oidfed.JWTPayloadJSONObjectMapper")
+    protected ObjectMapper payloadObjectMapper;
+
     static {
         trustedAnchorKey = TestFederationCredentials.trustAnchorKey();
         trustedIntermediateKey = TestFederationCredentials.intermediateKey();
@@ -315,9 +316,7 @@ public class AbstractFederationFlowTest extends AbstractFlowTest {
         if (crit != null) {
             builder.claim("crit", crit);
         }
-        final EntityStatement<?> rpConfiguration =
-                TrustChainTestUtil.entityStatement(JWSAlgorithm.RS256, leafKey, builder.build());
-        return rpConfiguration.getJwt().serialize();
+        return FederationJwtSupport.entityStatement(JWSAlgorithm.RS256, leafKey, builder.build()).serialize();
     }
 
     protected String rpEntityConfigurationUnmatchingKey(final String clientId,
@@ -330,9 +329,7 @@ public class AbstractFederationFlowTest extends AbstractFlowTest {
                 .claim("authority_hints", authorityHints == null || authorityHints.length == 0 ?
                         new String[] { anchorId } : authorityHints)
                 .build();
-        final EntityStatement<?> rpConfiguration =
-                TrustChainTestUtil.entityStatement(JWSAlgorithm.RS256, anchorKey, claimsSet);
-        return rpConfiguration.getJwt().serialize();
+        return FederationJwtSupport.entityStatement(JWSAlgorithm.RS256, anchorKey, claimsSet).serialize();
     }
 
     protected String trustMarkIssuerConfiguration(final String entityId, final String... authorityHints) {
@@ -345,9 +342,7 @@ public class AbstractFederationFlowTest extends AbstractFlowTest {
                 .claim("metadata", Map.of("federation_entity", Map.of("federation_trust_mark_endpoint",
                         trustMarkEndpoint, "federation_trust_mark_status_endpoint", trustMarkStatusEndpoint)))
                 .build();
-        final EntityStatement<?> rpConfiguration =
-                TrustChainTestUtil.entityStatement(JWSAlgorithm.RS256, trustMarkIssuerKey, claimsSet);
-        return rpConfiguration.getJwt().serialize();
+        return FederationJwtSupport.entityStatement(JWSAlgorithm.RS256, trustMarkIssuerKey, claimsSet).serialize();
     }
     
     protected String opEntityConfiguration(final String issuer, final String... authorityHints)
@@ -365,9 +360,7 @@ public class AbstractFederationFlowTest extends AbstractFlowTest {
                 .claim("authority_hints", authorityHints == null || authorityHints.length == 0 ?
                         new String[] { anchorId } : authorityHints)
                 .build();
-        final EntityStatement<?> rpConfiguration =
-                TrustChainTestUtil.entityStatement(JWSAlgorithm.RS256, leafKey, claimsSet);
-        return rpConfiguration.getJwt().serialize();
+        return FederationJwtSupport.entityStatement(JWSAlgorithm.RS256, leafKey, claimsSet).serialize();
     }
 
     protected String entityConfiguration(final String entityId, final Map<String, Object> metadata,
@@ -380,9 +373,7 @@ public class AbstractFederationFlowTest extends AbstractFlowTest {
                 .claim("authority_hints", authorityHints == null || authorityHints.length == 0 ?
                         new String[] { anchorId } : authorityHints)
                 .build();
-        final EntityStatement<?> configuration =
-                TrustChainTestUtil.entityStatement(JWSAlgorithm.RS256, leafKey, claimsSet);
-        return configuration.getJwt().serialize();
+        return FederationJwtSupport.entityStatement(JWSAlgorithm.RS256, leafKey, claimsSet).serialize();
     }
 
     protected String trustedAnchorConfiguration() {
@@ -416,9 +407,7 @@ public class AbstractFederationFlowTest extends AbstractFlowTest {
         if (trustMarkIssuers != null) {
             builder.claim("trust_mark_issuers", trustMarkIssuers);
         }
-        final EntityStatement<?> anchorConfiguration =
-                TrustChainTestUtil.entityStatement(JWSAlgorithm.RS256, signerKey, builder.build());
-        return anchorConfiguration.getJwt().serialize();
+        return FederationJwtSupport.entityStatement(JWSAlgorithm.RS256, signerKey, builder.build()).serialize();
     }
 
     protected String intermediateConfiguration(final String intermediateId) {
@@ -434,9 +423,7 @@ public class AbstractFederationFlowTest extends AbstractFlowTest {
                         intermediateId + "/fetch")))
                 .claim("authority_hints", new String[] { anchorId })
                 .build();
-        final EntityStatement<?> intermediateConfiguration =
-                TrustChainTestUtil.entityStatement(JWSAlgorithm.RS256, signerKey, claimsSet);
-        return intermediateConfiguration.getJwt().serialize();
+        return FederationJwtSupport.entityStatement(JWSAlgorithm.RS256, signerKey, claimsSet).serialize();
     }
 
     protected String subordinateStatement(final String issuer, final Map<String, Object> metadata) {
@@ -463,9 +450,7 @@ public class AbstractFederationFlowTest extends AbstractFlowTest {
                 .claim("metadata_policy_crit", metadataPolicyCrit)
                 .claim("crit", crit)
                 .build();
-        final EntityStatement<?> rpConfiguration =
-                TrustChainTestUtil.entityStatement(JWSAlgorithm.RS256, trustedAnchorKey, claimsSet);
-        return rpConfiguration.getJwt().serialize();
+        return FederationJwtSupport.entityStatement(JWSAlgorithm.RS256, trustedAnchorKey, claimsSet).serialize();
     }
 
     protected String rpSubordinateStatement(final String issuer, final JWK issuerKey, final JWK subjetKey,
@@ -477,9 +462,7 @@ public class AbstractFederationFlowTest extends AbstractFlowTest {
                 .claim("metadata", Map.of("openid_relying_party", new OIDCClientMetadata().toJSONObject()))
                 .claim("metadata_policy", rpPolicy)
                 .build();
-        final EntityStatement<?> rpConfiguration =
-                TrustChainTestUtil.entityStatement(JWSAlgorithm.RS256, issuerKey, claimsSet);
-        return rpConfiguration.getJwt().serialize();
+        return FederationJwtSupport.entityStatement(JWSAlgorithm.RS256, issuerKey, claimsSet).serialize();
     }
 
     protected String subordinateStatement(final String issuer, final JWK issuerKey, final JWK subjetKey,
@@ -492,9 +475,7 @@ public class AbstractFederationFlowTest extends AbstractFlowTest {
                 .claim("metadata_policy", rpPolicy)
                 .claim("constraints", constraints)
                 .build();
-        final EntityStatement<?> rpConfiguration =
-                TrustChainTestUtil.entityStatement(JWSAlgorithm.RS256, issuerKey, claimsSet);
-        return rpConfiguration.getJwt().serialize();
+        return FederationJwtSupport.entityStatement(JWSAlgorithm.RS256, issuerKey, claimsSet).serialize();
     }
 
     protected String uniqueClientId() {
@@ -783,22 +764,10 @@ public class AbstractFederationFlowTest extends AbstractFlowTest {
                 .claim("trust_mark", trustMark)
                 .claim("status", status)
                 .build();
-        return TrustChainTestUtil.signedJwt(JWSAlgorithm.RS256, signerKey,
+        return FederationJwtSupport.signedJwt(JWSAlgorithm.RS256, signerKey,
                 "trust-mark-status-response+jwt", claimsSet).serialize();
     }
 
-    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 Response parseResponse(final FlowExecutionResult result) {
         assertFlowExecutionOutcome(result.getOutcome(), END_STATE_ID);
         final ProfileRequestContext prc = retrieveProfileRequestContext(result);
diff --git a/oidfed-common-conf-impl/src/test/java/net/shibboleth/oidfed/flow/EntityConfigurationFlowTest.java b/oidfed-common-conf-impl/src/test/java/net/shibboleth/oidfed/flow/EntityConfigurationFlowTest.java
index 45ee918..2d1a7c1 100644
--- a/oidfed-common-conf-impl/src/test/java/net/shibboleth/oidfed/flow/EntityConfigurationFlowTest.java
+++ b/oidfed-common-conf-impl/src/test/java/net/shibboleth/oidfed/flow/EntityConfigurationFlowTest.java
@@ -43,7 +43,7 @@ import net.shibboleth.oidfed.metadata.cache.trustmark.DefaultTrustMarkFetchingSt
 import net.shibboleth.oidfed.metadata.impl.EntityConfigurationImpl;
 import net.shibboleth.oidfed.metadata.payload.EntityConfigurationPayload;
 import net.shibboleth.oidfed.metadata.payload.claim.Metadata;
-import net.shibboleth.oidfed.testing.TrustChainTestUtil;
+import net.shibboleth.oidfed.testing.FederationJwtSupport;
 import net.shibboleth.shared.collection.CollectionSupport;
 
 /**
@@ -67,7 +67,7 @@ public class EntityConfigurationFlowTest extends AbstractFederationFlowTest {
 
     @Test
     public void testOutputAndCaching() throws ParseException, IOException, InterruptedException {
-        final String trustMark = TrustChainTestUtil.trustMark(JWSAlgorithm.RS256, trustMarkIssuerKey,
+        final String trustMark = FederationJwtSupport.trustMark(JWSAlgorithm.RS256, trustMarkIssuerKey,
                 dynamicTrustMarkIssuerId, issuer, dynamicTrustMarkType, Instant.now().plusSeconds(300)).serialize();
         try {
             mapResponse(entityConfigurationUrl(dynamicTrustMarkIssuerId),
diff --git a/oidfed-common-conf-impl/src/test/java/net/shibboleth/oidfed/flow/TestTrustChainResolutionFlowTest.java b/oidfed-common-conf-impl/src/test/java/net/shibboleth/oidfed/flow/TestTrustChainResolutionFlowTest.java
index 0555504..1d3f9ad 100644
--- a/oidfed-common-conf-impl/src/test/java/net/shibboleth/oidfed/flow/TestTrustChainResolutionFlowTest.java
+++ b/oidfed-common-conf-impl/src/test/java/net/shibboleth/oidfed/flow/TestTrustChainResolutionFlowTest.java
@@ -36,7 +36,7 @@ import com.nimbusds.jose.JWSAlgorithm;
 import com.nimbusds.jose.jwk.JWKSet;
 import com.nimbusds.openid.connect.sdk.rp.OIDCClientMetadata;
 
-import net.shibboleth.oidfed.testing.TrustChainTestUtil;
+import net.shibboleth.oidfed.testing.FederationJwtSupport;
 import net.shibboleth.shared.collection.CollectionSupport;
 
 /**
@@ -62,7 +62,7 @@ public class TestTrustChainResolutionFlowTest extends AbstractFederationFlowTest
         request.setMethod("GET");
         final String entityId = super.uniqueClientId();
 
-        final String trustMark = TrustChainTestUtil.trustMark(JWSAlgorithm.RS256, trustMarkIssuerKey, trustMarkIssuerId,
+        final String trustMark = FederationJwtSupport.trustMark(JWSAlgorithm.RS256, trustMarkIssuerKey, trustMarkIssuerId,
                 entityId, "https://example.org/email-allowing-trust-mark", Instant.now().plusSeconds(300)).serialize();
         final OIDCClientMetadata metadata = new OIDCClientMetadata();
         metadata.setRedirectionURI(new URI(redirectUri));
@@ -98,7 +98,7 @@ public class TestTrustChainResolutionFlowTest extends AbstractFederationFlowTest
         request.addParameter("entityID", entityId);
         request.addParameter("includeTrustMark", "true");
 
-        final String trustMark = TrustChainTestUtil.trustMark(JWSAlgorithm.RS256, trustMarkIssuerKey, trustMarkIssuerId,
+        final String trustMark = FederationJwtSupport.trustMark(JWSAlgorithm.RS256, trustMarkIssuerKey, trustMarkIssuerId,
                 entityId, "https://example.org/email-allowing-trust-mark", Instant.now().plusSeconds(300)).serialize();
         final OIDCClientMetadata metadata = new OIDCClientMetadata();
         metadata.setRedirectionURI(new URI(redirectUri));
@@ -134,7 +134,7 @@ public class TestTrustChainResolutionFlowTest extends AbstractFederationFlowTest
         request.addParameter("entityID", entityId);
         request.addParameter("includeTrustMark", "true");
 
-        final String trustMark = TrustChainTestUtil.trustMark(JWSAlgorithm.RS256, trustMarkIssuerKey, trustMarkIssuerId,
+        final String trustMark = FederationJwtSupport.trustMark(JWSAlgorithm.RS256, trustMarkIssuerKey, trustMarkIssuerId,
                 entityId, "https://example.org/email-allowing-trust-mark", Instant.now().plusSeconds(300)).serialize();
         final OIDCClientMetadata metadata = new OIDCClientMetadata();
         metadata.setRedirectionURI(new URI(redirectUri));
@@ -170,7 +170,7 @@ public class TestTrustChainResolutionFlowTest extends AbstractFederationFlowTest
         request.addParameter("includeTrustMark", "true");
         request.addParameter("remoteTrustMarkValidation", "true");
 
-        final String trustMark = TrustChainTestUtil.trustMark(JWSAlgorithm.RS256, trustMarkIssuerKey, trustMarkIssuerId,
+        final String trustMark = FederationJwtSupport.trustMark(JWSAlgorithm.RS256, trustMarkIssuerKey, trustMarkIssuerId,
                 entityId, "https://example.org/email-allowing-trust-mark", Instant.now().plusSeconds(300)).serialize();
         final OIDCClientMetadata metadata = new OIDCClientMetadata();
         metadata.setRedirectionURI(new URI(redirectUri));
@@ -208,7 +208,7 @@ public class TestTrustChainResolutionFlowTest extends AbstractFederationFlowTest
         request.addParameter("includeTrustMark", "true");
         request.addParameter("remoteTrustMarkValidation", "true");
 
-        final String trustMark = TrustChainTestUtil.trustMark(JWSAlgorithm.RS256, trustMarkIssuerKey, trustMarkIssuerId,
+        final String trustMark = FederationJwtSupport.trustMark(JWSAlgorithm.RS256, trustMarkIssuerKey, trustMarkIssuerId,
                 entityId, "https://example.org/email-allowing-trust-mark", Instant.now().plusSeconds(300)).serialize();
         final OIDCClientMetadata metadata = new OIDCClientMetadata();
         metadata.setRedirectionURI(new URI(redirectUri));
diff --git a/oidfed-common-conf-impl/src/test/java/net/shibboleth/oidfed/flow/cache/EntityConfigurationMetadataCacheTest.java b/oidfed-common-conf-impl/src/test/java/net/shibboleth/oidfed/flow/cache/EntityConfigurationMetadataCacheTest.java
index bd74689..7b85b37 100644
--- a/oidfed-common-conf-impl/src/test/java/net/shibboleth/oidfed/flow/cache/EntityConfigurationMetadataCacheTest.java
+++ b/oidfed-common-conf-impl/src/test/java/net/shibboleth/oidfed/flow/cache/EntityConfigurationMetadataCacheTest.java
@@ -56,7 +56,7 @@ import net.shibboleth.oidfed.metadata.EntityConfiguration;
 import net.shibboleth.oidfed.metadata.cache.ResponseContainerExpirationCriterion;
 import net.shibboleth.oidfed.metadata.cache.SubjectEntityIDCriterion;
 import net.shibboleth.oidfed.metadata.cache.configuration.EntityConfigurationContainer;
-import net.shibboleth.oidfed.testing.TrustChainTestUtil;
+import net.shibboleth.oidfed.testing.FederationJwtSupport;
 import net.shibboleth.shared.collection.CollectionSupport;
 import net.shibboleth.shared.resolver.CriteriaSet;
 
@@ -83,7 +83,7 @@ public class EntityConfigurationMetadataCacheTest extends AbstractFederationFlow
                 .expirationTime(Date.from(Instant.now().plusSeconds(300)))
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
-        final String entityConfiguration = TrustChainTestUtil.signedJwt(
+        final String entityConfiguration = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, leafKey, "entity-statement+jwt", builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(entityId), mockResponse(entityConfiguration));
@@ -113,7 +113,7 @@ public class EntityConfigurationMetadataCacheTest extends AbstractFederationFlow
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("crit", List.of("default_crit"))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
-        final String entityConfiguration = TrustChainTestUtil.signedJwt(
+        final String entityConfiguration = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, leafKey, "entity-statement+jwt", builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(entityId), mockResponse(entityConfiguration));
@@ -158,7 +158,7 @@ public class EntityConfigurationMetadataCacheTest extends AbstractFederationFlow
                 .expirationTime(Date.from(Instant.now().plusSeconds(300)))
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
-        final SignedJWT signedJwt = TrustChainTestUtil.signedJwt(
+        final SignedJWT signedJwt = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, leafKey, "entity-statement+jwt", builder.build());
         final JWEObject jwe = new JWEObject(new JWEHeader.Builder(JWEAlgorithm.RSA_OAEP_256, EncryptionMethod.A256GCM)
                     .contentType("JWT")
@@ -185,7 +185,7 @@ public class EntityConfigurationMetadataCacheTest extends AbstractFederationFlow
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("crit", List.of("subordinate_crit"))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
-        final String entityConfiguration = TrustChainTestUtil.signedJwt(
+        final String entityConfiguration = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, leafKey, "entity-statement+jwt", builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(entityId), mockResponse(entityConfiguration));
@@ -202,7 +202,7 @@ public class EntityConfigurationMetadataCacheTest extends AbstractFederationFlow
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("crit", List.of("jwks"))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
-        final String entityConfiguration = TrustChainTestUtil.signedJwt(
+        final String entityConfiguration = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, leafKey, "entity-statement+jwt", builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(entityId), mockResponse(entityConfiguration));
@@ -218,7 +218,7 @@ public class EntityConfigurationMetadataCacheTest extends AbstractFederationFlow
                 .expirationTime(Date.from(Instant.now().plusSeconds(300)))
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
-        final String entityConfiguration = TrustChainTestUtil.signedJwt(
+        final String entityConfiguration = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, anchorKey, "entity-statement+jwt", builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(entityId), mockResponse(entityConfiguration));
@@ -234,7 +234,7 @@ public class EntityConfigurationMetadataCacheTest extends AbstractFederationFlow
                 .expirationTime(Date.from(Instant.now().plusSeconds(300)))
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
-        final String entityConfiguration = TrustChainTestUtil.signedJwt(
+        final String entityConfiguration = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, leafKey, "entity-statement+jwt", builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(entityId), mockResponse(entityConfiguration));
@@ -251,7 +251,7 @@ public class EntityConfigurationMetadataCacheTest extends AbstractFederationFlow
                 .expirationTime(Date.from(Instant.now().plusSeconds(300)))
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
-        final String entityConfiguration = TrustChainTestUtil.signedJwt(
+        final String entityConfiguration = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, leafKey, "entity-statement+jwt", builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(entityId), mockResponse(entityConfiguration));
@@ -267,7 +267,7 @@ public class EntityConfigurationMetadataCacheTest extends AbstractFederationFlow
                 .expirationTime(Date.from(Instant.now().plusSeconds(300)))
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
-        final String entityConfiguration = TrustChainTestUtil.signedJwt(
+        final String entityConfiguration = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, leafKey, "jwt", builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(entityId), mockResponse(entityConfiguration));
@@ -283,7 +283,7 @@ public class EntityConfigurationMetadataCacheTest extends AbstractFederationFlow
                 .expirationTime(Date.from(Instant.now().plusSeconds(300)))
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
-        final String entityConfiguration = TrustChainTestUtil.signedJwt(
+        final String entityConfiguration = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, leafKey, "entity-statement+jwt", builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(entityId), mockResponse(entityConfiguration));
@@ -299,7 +299,7 @@ public class EntityConfigurationMetadataCacheTest extends AbstractFederationFlow
                 .expirationTime(Date.from(Instant.now().plusSeconds(300)))
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
-        final String entityConfiguration = TrustChainTestUtil.signedJwt(
+        final String entityConfiguration = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, leafKey, "entity-statement+jwt", builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(entityId), mockResponse(entityConfiguration));
@@ -315,7 +315,7 @@ public class EntityConfigurationMetadataCacheTest extends AbstractFederationFlow
                 .expirationTime(Date.from(Instant.now().minusSeconds(300)))
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
-        final String entityConfiguration = TrustChainTestUtil.signedJwt(
+        final String entityConfiguration = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, leafKey, "entity-statement+jwt", builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(entityId), mockResponse(entityConfiguration));
@@ -330,7 +330,7 @@ public class EntityConfigurationMetadataCacheTest extends AbstractFederationFlow
                 .issueTime(Date.from(Instant.now()))
                 .expirationTime(Date.from(Instant.now().plusSeconds(300)))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
-        final String entityConfiguration = TrustChainTestUtil.signedJwt(
+        final String entityConfiguration = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, leafKey, "entity-statement+jwt", builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(entityId), mockResponse(entityConfiguration));
@@ -346,7 +346,7 @@ public class EntityConfigurationMetadataCacheTest extends AbstractFederationFlow
                 .expirationTime(Date.from(Instant.now().plusSeconds(300)))
                 .claim("jwks", Map.of("federation_entity", Collections.emptyMap()))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
-        final String entityConfiguration = TrustChainTestUtil.signedJwt(
+        final String entityConfiguration = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, leafKey, "entity-statement+jwt", builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(entityId), mockResponse(entityConfiguration));
@@ -367,7 +367,7 @@ public class EntityConfigurationMetadataCacheTest extends AbstractFederationFlow
                 .keyID(leafKey.getKeyID())
                 .customParam("trust_chain", "forbidden")
                 .build();
-        final String entityConfiguration = TrustChainTestUtil.signedJwt(
+        final String entityConfiguration = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, leafKey, header, builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(entityId), mockResponse(entityConfiguration));
@@ -388,7 +388,7 @@ public class EntityConfigurationMetadataCacheTest extends AbstractFederationFlow
                 .keyID(leafKey.getKeyID())
                 .customParam("peer_trust_chain", "forbidden")
                 .build();
-        final String entityConfiguration = TrustChainTestUtil.signedJwt(
+        final String entityConfiguration = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, leafKey, header, builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(entityId), mockResponse(entityConfiguration));
@@ -405,7 +405,7 @@ public class EntityConfigurationMetadataCacheTest extends AbstractFederationFlow
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("authority_hints", CollectionSupport.emptyList())
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
-        final String entityConfiguration = TrustChainTestUtil.signedJwt(
+        final String entityConfiguration = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, leafKey, "entity-statement+jwt", builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(entityId), mockResponse(entityConfiguration));
@@ -422,7 +422,7 @@ public class EntityConfigurationMetadataCacheTest extends AbstractFederationFlow
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("trust_anchor_hints", CollectionSupport.emptyList())
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
-        final String entityConfiguration = TrustChainTestUtil.signedJwt(
+        final String entityConfiguration = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, leafKey, "entity-statement+jwt", builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(entityId), mockResponse(entityConfiguration));
@@ -440,7 +440,7 @@ public class EntityConfigurationMetadataCacheTest extends AbstractFederationFlow
                 .expirationTime(Date.from(Instant.now().plusSeconds(300)))
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("metadata", metadata);
-        final String entityConfiguration = TrustChainTestUtil.signedJwt(
+        final String entityConfiguration = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, leafKey, "entity-statement+jwt", builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(entityId), mockResponse(entityConfiguration));
@@ -459,7 +459,7 @@ public class EntityConfigurationMetadataCacheTest extends AbstractFederationFlow
                 .expirationTime(Date.from(Instant.now().plusSeconds(300)))
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("metadata", metadata);
-        final String entityConfiguration = TrustChainTestUtil.signedJwt(
+        final String entityConfiguration = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, leafKey, "entity-statement+jwt", builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(entityId), mockResponse(entityConfiguration));
@@ -487,7 +487,7 @@ public class EntityConfigurationMetadataCacheTest extends AbstractFederationFlow
     public void testInvalidtTrustMark_nonMatchingType()
             throws MetadataCacheException, UnsupportedOperationException, IOException, URISyntaxException {
         final String entityId = uniqueClientId();
-        final String trustMark = TrustChainTestUtil.trustMark(JWSAlgorithm.RS256, trustMarkIssuerKey, trustMarkIssuerId,
+        final String trustMark = FederationJwtSupport.trustMark(JWSAlgorithm.RS256, trustMarkIssuerKey, trustMarkIssuerId,
                 entityId, "https://example.org/email-allowing-trust-mark", Instant.now().plusSeconds(300)).serialize();
         final JWTClaimsSet.Builder builder = new JWTClaimsSet.Builder().issuer(entityId).subject(entityId)
                 .issueTime(Date.from(Instant.now()))
@@ -497,7 +497,7 @@ public class EntityConfigurationMetadataCacheTest extends AbstractFederationFlow
                         "trust_mark_type", "https://example.org/non-matching-type",
                         "trust_mark", trustMark)))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
-        final String entityConfiguration = TrustChainTestUtil.signedJwt(
+        final String entityConfiguration = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, leafKey, "entity-statement+jwt", builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(entityId), mockResponse(entityConfiguration));
@@ -514,7 +514,7 @@ public class EntityConfigurationMetadataCacheTest extends AbstractFederationFlow
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("trust_mark_issuers", List.of(trustMarkIssuerId))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
-        final String entityConfiguration = TrustChainTestUtil.signedJwt(
+        final String entityConfiguration = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, leafKey, "entity-statement+jwt", builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(entityId), mockResponse(entityConfiguration));
@@ -534,7 +534,7 @@ public class EntityConfigurationMetadataCacheTest extends AbstractFederationFlow
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("trust_mark_owners", Map.of("https://example.org/email-allowing-trust-mark", trustMarkOwner))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
-        final String entityConfiguration = TrustChainTestUtil.signedJwt(
+        final String entityConfiguration = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, leafKey, "entity-statement+jwt", builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(entityId), mockResponse(entityConfiguration));
@@ -553,7 +553,7 @@ public class EntityConfigurationMetadataCacheTest extends AbstractFederationFlow
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("trust_mark_owners", Map.of("https://example.org/email-allowing-trust-mark", trustMarkOwner))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
-        final String entityConfiguration = TrustChainTestUtil.signedJwt(
+        final String entityConfiguration = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, leafKey, "entity-statement+jwt", builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(entityId), mockResponse(entityConfiguration));
@@ -572,7 +572,7 @@ public class EntityConfigurationMetadataCacheTest extends AbstractFederationFlow
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("trust_mark_owners", Map.of("https://example.org/email-allowing-trust-mark", trustMarkOwner))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
-        final String entityConfiguration = TrustChainTestUtil.signedJwt(
+        final String entityConfiguration = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, leafKey, "entity-statement+jwt", builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(entityId), mockResponse(entityConfiguration));
diff --git a/oidfed-common-conf-impl/src/test/java/net/shibboleth/oidfed/flow/cache/SignedKeysetMetadataCacheTest.java b/oidfed-common-conf-impl/src/test/java/net/shibboleth/oidfed/flow/cache/SignedKeysetMetadataCacheTest.java
index 10b1a59..624ccdf 100644
--- a/oidfed-common-conf-impl/src/test/java/net/shibboleth/oidfed/flow/cache/SignedKeysetMetadataCacheTest.java
+++ b/oidfed-common-conf-impl/src/test/java/net/shibboleth/oidfed/flow/cache/SignedKeysetMetadataCacheTest.java
@@ -27,6 +27,7 @@ import org.springframework.beans.factory.annotation.Qualifier;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
+import com.fasterxml.jackson.core.JsonProcessingException;
 import com.nimbusds.jose.JWSAlgorithm;
 import com.nimbusds.jose.jwk.JWK;
 import com.nimbusds.jose.jwk.JWKSet;
@@ -38,12 +39,12 @@ import net.shibboleth.oidc.metadata.cache.MetadataCacheException;
 import net.shibboleth.oidfed.flow.AbstractFederationFlowTest;
 import net.shibboleth.oidfed.flow.EntityConfigurationFlowTest;
 import net.shibboleth.oidfed.metadata.EntityConfiguration;
-import net.shibboleth.oidfed.metadata.EntityStatement;
 import net.shibboleth.oidfed.metadata.SignedKeyset;
 import net.shibboleth.oidfed.metadata.cache.SubjectEntityStatementCriterion;
 import net.shibboleth.oidfed.metadata.cache.keyset.SignedKeysetContainer;
 import net.shibboleth.oidfed.metadata.cache.keyset.SubjectSignedKeysetUriCriterion;
-import net.shibboleth.oidfed.testing.TrustChainTestUtil;
+import net.shibboleth.oidfed.metadata.impl.EntityConfigurationImpl;
+import net.shibboleth.oidfed.testing.FederationJwtSupport;
 import net.shibboleth.shared.resolver.CriteriaSet;
 
 /**
@@ -71,7 +72,7 @@ public class SignedKeysetMetadataCacheTest extends AbstractFederationFlowTest {
         final JWTClaimsSet.Builder builder = new JWTClaimsSet.Builder().issuer(entityId).subject(entityId)
                 .issueTime(Date.from(Instant.now()))
                 .claim("keys", new JWKSet(rpKey).toJSONObject(true).get("keys"));
-        final String signedKeyset = TrustChainTestUtil.signedJwt(
+        final String signedKeyset = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, leafKey, "jwk-set+jwt", builder.build()).serialize();
         
         mapResponse(signedJwksUri, mockResponse(200, "application/jwk-set+jwt", signedKeyset));
@@ -106,7 +107,7 @@ public class SignedKeysetMetadataCacheTest extends AbstractFederationFlowTest {
                 .issueTime(Date.from(Instant.now()))
                 .expirationTime(Date.from(Instant.now().plusSeconds(300)))
                 .claim("keys", new JWKSet(rpKey).toJSONObject(true).get("keys"));
-        final String signedKeyset = TrustChainTestUtil.signedJwt(
+        final String signedKeyset = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, leafKey, "jwk-set+jwt", builder.build()).serialize();
         
         mapResponse(signedJwksUri, mockResponse(200, "application/jwk-set+jwt", signedKeyset));
@@ -141,7 +142,7 @@ public class SignedKeysetMetadataCacheTest extends AbstractFederationFlowTest {
                 .issueTime(Date.from(Instant.now()))
                 .expirationTime(Date.from(Instant.now().minusSeconds(300)))
                 .claim("keys", new JWKSet(rpKey).toJSONObject(true).get("keys"));
-        final String signedKeyset = TrustChainTestUtil.signedJwt(
+        final String signedKeyset = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, leafKey, "jwk-set+jwt", builder.build()).serialize();
         
         mapResponse(signedJwksUri, mockResponse(200, "application/jwk-set+jwt", signedKeyset));
@@ -160,7 +161,7 @@ public class SignedKeysetMetadataCacheTest extends AbstractFederationFlowTest {
                 .issueTime(Date.from(Instant.now()))
                 .expirationTime(Date.from(Instant.now().plusSeconds(300)))
                 .claim("keys", new JWKSet(rpKey).toJSONObject(true).get("keys"));
-        final String signedKeyset = TrustChainTestUtil.signedJwt(
+        final String signedKeyset = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, leafKey, "entity-statement+jwt", builder.build()).serialize();
         
         mapResponse(signedJwksUri, mockResponse(200, "application/jwk-set+jwt", signedKeyset));
@@ -179,7 +180,7 @@ public class SignedKeysetMetadataCacheTest extends AbstractFederationFlowTest {
                 .issueTime(Date.from(Instant.now()))
                 .expirationTime(Date.from(Instant.now().plusSeconds(300)))
                 .claim("keys", new JWKSet(rpKey).toJSONObject(true).get("keys"));
-        final String signedKeyset = TrustChainTestUtil.signedJwt(
+        final String signedKeyset = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, leafKey, "jwk-set+jwt", builder.build()).serialize();
         
         mapResponse(signedJwksUri, mockResponse(200, "application/entity-statement+jwt", signedKeyset));
@@ -198,7 +199,7 @@ public class SignedKeysetMetadataCacheTest extends AbstractFederationFlowTest {
                 .issueTime(Date.from(Instant.now()))
                 .expirationTime(Date.from(Instant.now().minusSeconds(300)))
                 .claim("keys", new JWKSet(rpKey).toJSONObject(true).get("keys"));
-        final String signedKeyset = TrustChainTestUtil.signedJwt(
+        final String signedKeyset = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, rpKey, "jwk-set+jwt", builder.build()).serialize();
         
         mapResponse(signedJwksUri, mockResponse(200, "application/jwk-set+jwt", signedKeyset));
@@ -212,9 +213,14 @@ public class SignedKeysetMetadataCacheTest extends AbstractFederationFlowTest {
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("metadata", Map.of("openid_relying_party", metadata.toJSONObject()))
                 .claim("authority_hints", new String[] { anchorId });
-        final EntityStatement<?> rpConfiguration =
-                TrustChainTestUtil.entityStatement(JWSAlgorithm.RS256, leafKey, builder.build());
-        return (EntityConfiguration) rpConfiguration;
+        try {
+            return EntityConfigurationImpl.parse(
+                    FederationJwtSupport.entityStatement(JWSAlgorithm.RS256, leafKey, builder.build()),
+                    payloadObjectMapper);
+        } catch (JsonProcessingException e) {
+            Assert.fail();
+        }
+        return null;
     }
 
     protected void assertNoSignedKeyset(final String signedJwksUri, final EntityConfiguration entityConfiguration) {
diff --git a/oidfed-common-conf-impl/src/test/java/net/shibboleth/oidfed/flow/cache/SubordinateStatementMetadataCacheTest.java b/oidfed-common-conf-impl/src/test/java/net/shibboleth/oidfed/flow/cache/SubordinateStatementMetadataCacheTest.java
index 4f1f0ec..e24eea6 100644
--- a/oidfed-common-conf-impl/src/test/java/net/shibboleth/oidfed/flow/cache/SubordinateStatementMetadataCacheTest.java
+++ b/oidfed-common-conf-impl/src/test/java/net/shibboleth/oidfed/flow/cache/SubordinateStatementMetadataCacheTest.java
@@ -52,13 +52,12 @@ import net.shibboleth.oidc.metadata.cache.MetadataCacheException;
 import net.shibboleth.oidfed.flow.AbstractFederationFlowTest;
 import net.shibboleth.oidfed.flow.EntityConfigurationFlowTest;
 import net.shibboleth.oidfed.flow.support.CustomSubordinateStatementFilterStrategy;
-import net.shibboleth.oidfed.metadata.EntityStatement;
 import net.shibboleth.oidfed.metadata.SubordinateStatement;
 import net.shibboleth.oidfed.metadata.cache.IssuerEntityIDCriterion;
 import net.shibboleth.oidfed.metadata.cache.ResponseContainerExpirationCriterion;
 import net.shibboleth.oidfed.metadata.cache.SubjectEntityIDCriterion;
 import net.shibboleth.oidfed.metadata.cache.subordinate.SubordinateStatementContainer;
-import net.shibboleth.oidfed.testing.TrustChainTestUtil;
+import net.shibboleth.oidfed.testing.FederationJwtSupport;
 import net.shibboleth.shared.resolver.CriteriaSet;
 
 /**
@@ -84,7 +83,7 @@ public class SubordinateStatementMetadataCacheTest extends AbstractFederationFlo
                 .expirationTime(Date.from(Instant.now().plusSeconds(300)))
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
-        final String subordinateStatement = TrustChainTestUtil.signedJwt(
+        final String subordinateStatement = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, trustedAnchorKey, "entity-statement+jwt", builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(anchorId), mockResponse(trustedAnchorConfiguration()));
@@ -117,7 +116,7 @@ public class SubordinateStatementMetadataCacheTest extends AbstractFederationFlo
                 .expirationTime(Date.from(Instant.now().plusSeconds(300)))
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
-        final String subordinateStatement = TrustChainTestUtil.signedJwt(
+        final String subordinateStatement = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, intermediateKey, "entity-statement+jwt", builder.build()).serialize();
 
         final JWTClaimsSet.Builder ecBuilder = new JWTClaimsSet.Builder().issuer(intermediateId).subject(intermediateId)
@@ -128,11 +127,11 @@ public class SubordinateStatementMetadataCacheTest extends AbstractFederationFlo
                         "federation_fetch_endpoint", intermediateId + "/fetch",
                         "federation_fetch_endpoint_auth_methods", List.of("private_key_jwt"),
                         "endpoint_auth_signing_alg_values_supported", List.of("ES512"))));
-        final EntityStatement<?> intermediateConfiguration =
-                TrustChainTestUtil.entityStatement(JWSAlgorithm.RS256, intermediateKey, ecBuilder.build());
+        final SignedJWT intermediateConfiguration =
+                FederationJwtSupport.entityStatement(JWSAlgorithm.RS256, intermediateKey, ecBuilder.build());
 
 
-        mapResponse(entityConfigurationUrl(intermediateId), mockResponse(intermediateConfiguration.getJwt().serialize()));
+        mapResponse(entityConfigurationUrl(intermediateId), mockResponse(intermediateConfiguration.serialize()));
         // raw anchorFetchEndpoint URL as the request is POST
         mapResponse(intermediateId + "/fetch", mockResponse(subordinateStatement));
 
@@ -163,7 +162,7 @@ public class SubordinateStatementMetadataCacheTest extends AbstractFederationFlo
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("crit", List.of("subordinate_crit"))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
-        final String subordinateStatement = TrustChainTestUtil.signedJwt(
+        final String subordinateStatement = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, trustedAnchorKey, "entity-statement+jwt", builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(anchorId), mockResponse(trustedAnchorConfiguration()));
@@ -213,7 +212,7 @@ public class SubordinateStatementMetadataCacheTest extends AbstractFederationFlo
                 .expirationTime(Date.from(Instant.now().plusSeconds(300)))
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
-        final SignedJWT signedJwt = TrustChainTestUtil.signedJwt(
+        final SignedJWT signedJwt = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, leafKey, "entity-statement+jwt", builder.build());
         final JWEObject jwe = new JWEObject(new JWEHeader.Builder(JWEAlgorithm.RSA_OAEP_256, EncryptionMethod.A256GCM)
                     .contentType("JWT")
@@ -242,7 +241,7 @@ public class SubordinateStatementMetadataCacheTest extends AbstractFederationFlo
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("crit", List.of("default_crit"))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
-        final String subordinateStatement = TrustChainTestUtil.signedJwt(
+        final String subordinateStatement = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, trustedAnchorKey, "entity-statement+jwt", builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(anchorId), mockResponse(trustedAnchorConfiguration()));
@@ -261,7 +260,7 @@ public class SubordinateStatementMetadataCacheTest extends AbstractFederationFlo
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("crit", List.of("jwks"))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
-        final String subordinateStatement = TrustChainTestUtil.signedJwt(
+        final String subordinateStatement = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, trustedAnchorKey, "entity-statement+jwt", builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(anchorId), mockResponse(trustedAnchorConfiguration()));
@@ -279,7 +278,7 @@ public class SubordinateStatementMetadataCacheTest extends AbstractFederationFlo
                 .expirationTime(Date.from(Instant.now().plusSeconds(300)))
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
-        final String subordinateStatement = TrustChainTestUtil.signedJwt(
+        final String subordinateStatement = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, leafKey, "entity-statement+jwt", builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(anchorId), mockResponse(trustedAnchorConfiguration()));
@@ -298,7 +297,7 @@ public class SubordinateStatementMetadataCacheTest extends AbstractFederationFlo
                 .expirationTime(Date.from(Instant.now().plusSeconds(300)))
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
-        final String subordinateStatement = TrustChainTestUtil.signedJwt(
+        final String subordinateStatement = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, trustedAnchorKey, "entity-statement+jwt", builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(anchorId), mockResponse(trustedAnchorConfiguration()));
@@ -316,7 +315,7 @@ public class SubordinateStatementMetadataCacheTest extends AbstractFederationFlo
                 .expirationTime(Date.from(Instant.now().plusSeconds(300)))
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
-        final String subordinateStatement = TrustChainTestUtil.signedJwt(
+        final String subordinateStatement = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, trustedAnchorKey, "jwt", builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(anchorId), mockResponse(trustedAnchorConfiguration()));
@@ -340,7 +339,7 @@ public class SubordinateStatementMetadataCacheTest extends AbstractFederationFlo
                 .keyID(trustedAnchorKey.getKeyID())
                 .customParam("trust_chain", "forbidden")
                 .build();
-        final String subordinateStatement = TrustChainTestUtil.signedJwt(
+        final String subordinateStatement = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, trustedAnchorKey, header, builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(anchorId), mockResponse(trustedAnchorConfiguration()));
@@ -364,7 +363,7 @@ public class SubordinateStatementMetadataCacheTest extends AbstractFederationFlo
                 .keyID(trustedAnchorKey.getKeyID())
                 .customParam("peer_trust_chain", "forbidden")
                 .build();
-        final String subordinateStatement = TrustChainTestUtil.signedJwt(
+        final String subordinateStatement = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, trustedAnchorKey, header, builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(anchorId), mockResponse(trustedAnchorConfiguration()));
@@ -383,7 +382,7 @@ public class SubordinateStatementMetadataCacheTest extends AbstractFederationFlo
                 .expirationTime(Date.from(Instant.now().plusSeconds(300)))
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
-        final String subordinateStatement = TrustChainTestUtil.signedJwt(
+        final String subordinateStatement = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, trustedAnchorKey, "entity-statement+jwt", builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(anchorId), mockResponse(trustedAnchorConfiguration()));
@@ -401,7 +400,7 @@ public class SubordinateStatementMetadataCacheTest extends AbstractFederationFlo
                 .expirationTime(Date.from(Instant.now().plusSeconds(300)))
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
-        final String subordinateStatement = TrustChainTestUtil.signedJwt(
+        final String subordinateStatement = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, trustedAnchorKey, "entity-statement+jwt", builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(anchorId), mockResponse(trustedAnchorConfiguration()));
@@ -419,7 +418,7 @@ public class SubordinateStatementMetadataCacheTest extends AbstractFederationFlo
                 .expirationTime(Date.from(Instant.now().minusSeconds(300)))
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
-        final String subordinateStatement = TrustChainTestUtil.signedJwt(
+        final String subordinateStatement = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, trustedAnchorKey, "entity-statement+jwt", builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(anchorId), mockResponse(trustedAnchorConfiguration()));
@@ -436,7 +435,7 @@ public class SubordinateStatementMetadataCacheTest extends AbstractFederationFlo
                 .issueTime(Date.from(Instant.now()))
                 .expirationTime(Date.from(Instant.now().plusSeconds(300)))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
-        final String subordinateStatement = TrustChainTestUtil.signedJwt(
+        final String subordinateStatement = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, trustedAnchorKey, "entity-statement+jwt", builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(anchorId), mockResponse(trustedAnchorConfiguration()));
@@ -455,7 +454,7 @@ public class SubordinateStatementMetadataCacheTest extends AbstractFederationFlo
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("constraints", Map.of("max_path_length", "non_integer"))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
-        final String subordinateStatement = TrustChainTestUtil.signedJwt(
+        final String subordinateStatement = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, trustedAnchorKey, "entity-statement+jwt", builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(anchorId), mockResponse(trustedAnchorConfiguration()));
@@ -474,7 +473,7 @@ public class SubordinateStatementMetadataCacheTest extends AbstractFederationFlo
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("constraints", Map.of("naming_constraints", "not_map"))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
-        final String subordinateStatement = TrustChainTestUtil.signedJwt(
+        final String subordinateStatement = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, trustedAnchorKey, "entity-statement+jwt", builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(anchorId), mockResponse(trustedAnchorConfiguration()));
@@ -493,7 +492,7 @@ public class SubordinateStatementMetadataCacheTest extends AbstractFederationFlo
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("constraints", Map.of("allowed_entity_types", "not_list"))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
-        final String subordinateStatement = TrustChainTestUtil.signedJwt(
+        final String subordinateStatement = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, trustedAnchorKey, "entity-statement+jwt", builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(anchorId), mockResponse(trustedAnchorConfiguration()));
@@ -516,7 +515,7 @@ public class SubordinateStatementMetadataCacheTest extends AbstractFederationFlo
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("constraints", constraints)
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
-        final String subordinateStatement = TrustChainTestUtil.signedJwt(
+        final String subordinateStatement = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, trustedAnchorKey, "entity-statement+jwt", builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(anchorId), mockResponse(trustedAnchorConfiguration()));
@@ -543,7 +542,7 @@ public class SubordinateStatementMetadataCacheTest extends AbstractFederationFlo
     public void testForbiddenClaim_trustMark()
             throws MetadataCacheException, UnsupportedOperationException, IOException, URISyntaxException {
         final String entityId = uniqueClientId();
-        final String trustMark = TrustChainTestUtil.trustMark(JWSAlgorithm.RS256, trustMarkIssuerKey, trustMarkIssuerId,
+        final String trustMark = FederationJwtSupport.trustMark(JWSAlgorithm.RS256, trustMarkIssuerKey, trustMarkIssuerId,
                 entityId, "https://example.org/email-allowing-trust-mark", Instant.now().plusSeconds(300)).serialize();
         final JWTClaimsSet.Builder builder = new JWTClaimsSet.Builder().issuer(anchorId).subject(entityId)
                 .issueTime(Date.from(Instant.now()))
@@ -553,7 +552,7 @@ public class SubordinateStatementMetadataCacheTest extends AbstractFederationFlo
                         "trust_mark_type", "https://example.org/email-allowing-trust-mark",
                         "trust_mark", trustMark)))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
-        final String subordinateStatement = TrustChainTestUtil.signedJwt(
+        final String subordinateStatement = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, trustedAnchorKey, "entity-statement+jwt", builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(anchorId), mockResponse(trustedAnchorConfiguration()));
@@ -572,7 +571,7 @@ public class SubordinateStatementMetadataCacheTest extends AbstractFederationFlo
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("trust_mark_issuers", List.of(trustMarkIssuerId))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
-        final String subordinateStatement = TrustChainTestUtil.signedJwt(
+        final String subordinateStatement = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, trustedAnchorKey, "entity-statement+jwt", builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(anchorId), mockResponse(trustedAnchorConfiguration()));
@@ -594,7 +593,7 @@ public class SubordinateStatementMetadataCacheTest extends AbstractFederationFlo
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("trust_mark_owners", Map.of("https://example.org/email-allowing-trust-mark", trustMarkOwner))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
-        final String subordinateStatement = TrustChainTestUtil.signedJwt(
+        final String subordinateStatement = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, trustedAnchorKey, "entity-statement+jwt", builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(anchorId), mockResponse(trustedAnchorConfiguration()));
@@ -612,7 +611,7 @@ public class SubordinateStatementMetadataCacheTest extends AbstractFederationFlo
                 .expirationTime(Date.from(Instant.now().plusSeconds(300)))
                 .claim("jwks", Map.of("federation_entity", Collections.emptyMap()))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
-        final String subordinateStatement = TrustChainTestUtil.signedJwt(
+        final String subordinateStatement = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, trustedAnchorKey, "entity-statement+jwt", builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(anchorId), mockResponse(trustedAnchorConfiguration()));
diff --git a/oidfed-common-conf-impl/src/test/java/net/shibboleth/oidfed/flow/cache/TrustChainMetadataCacheTest.java b/oidfed-common-conf-impl/src/test/java/net/shibboleth/oidfed/flow/cache/TrustChainMetadataCacheTest.java
index a004bfa..9657164 100644
--- a/oidfed-common-conf-impl/src/test/java/net/shibboleth/oidfed/flow/cache/TrustChainMetadataCacheTest.java
+++ b/oidfed-common-conf-impl/src/test/java/net/shibboleth/oidfed/flow/cache/TrustChainMetadataCacheTest.java
@@ -39,7 +39,7 @@ import net.shibboleth.oidfed.metadata.cache.IssuerEntityIDCriterion;
 import net.shibboleth.oidfed.metadata.cache.ResponseContainerExpirationCriterion;
 import net.shibboleth.oidfed.metadata.cache.SubjectEntityIDCriterion;
 import net.shibboleth.oidfed.metadata.cache.trustchain.TrustChainsContainer;
-import net.shibboleth.oidfed.testing.TrustChainTestUtil;
+import net.shibboleth.oidfed.testing.FederationJwtSupport;
 import net.shibboleth.shared.resolver.CriteriaSet;
 
 /**
@@ -67,7 +67,7 @@ public class TrustChainMetadataCacheTest extends AbstractFederationFlowTest {
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()))
                 .claim("authority_hints", List.of(anchorId));
-        final String entityConfiguration = TrustChainTestUtil.signedJwt(
+        final String entityConfiguration = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, leafKey, "entity-statement+jwt", builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(entityId), mockResponse(entityConfiguration));
@@ -77,7 +77,7 @@ public class TrustChainMetadataCacheTest extends AbstractFederationFlowTest {
                 .expirationTime(Date.from(Instant.now().plusSeconds(300)))
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
-        final String subordinateStatement = TrustChainTestUtil.signedJwt(
+        final String subordinateStatement = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, trustedAnchorKey, "entity-statement+jwt", builder2.build()).serialize();
 
         mapResponse(entityConfigurationUrl(anchorId), mockResponse(trustedAnchorConfiguration()));
@@ -110,7 +110,7 @@ public class TrustChainMetadataCacheTest extends AbstractFederationFlowTest {
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()))
                 .claim("authority_hints", List.of(anchorId));
-        final String entityConfiguration = TrustChainTestUtil.signedJwt(
+        final String entityConfiguration = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, leafKey, "entity-statement+jwt", builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(entityId), mockResponse(entityConfiguration));
@@ -120,7 +120,7 @@ public class TrustChainMetadataCacheTest extends AbstractFederationFlowTest {
                 .expirationTime(Date.from(Instant.now().plusSeconds(300)))
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
-        final String subordinateStatement = TrustChainTestUtil.signedJwt(
+        final String subordinateStatement = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, trustedAnchorKey, "entity-statement+jwt", builder2.build()).serialize();
 
         mapResponse(entityConfigurationUrl(anchorId),
@@ -154,7 +154,7 @@ public class TrustChainMetadataCacheTest extends AbstractFederationFlowTest {
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()))
                 .claim("authority_hints", List.of(anchorId));
-        final String entityConfiguration = TrustChainTestUtil.signedJwt(
+        final String entityConfiguration = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, leafKey, "entity-statement+jwt", builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(entityId), mockResponse(entityConfiguration));
@@ -164,7 +164,7 @@ public class TrustChainMetadataCacheTest extends AbstractFederationFlowTest {
                 .expirationTime(Date.from(Instant.now().plusSeconds(300)))
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
-        final String subordinateStatement = TrustChainTestUtil.signedJwt(
+        final String subordinateStatement = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, anchorKey, "entity-statement+jwt", builder2.build()).serialize();
 
         mapResponse(entityConfigurationUrl(anchorId),
@@ -197,7 +197,7 @@ public class TrustChainMetadataCacheTest extends AbstractFederationFlowTest {
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()))
                 .claim("authority_hints", List.of(trustedIntermediateId));
-        final String entityConfiguration = TrustChainTestUtil.signedJwt(
+        final String entityConfiguration = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, leafKey, "entity-statement+jwt", builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(entityId), mockResponse(entityConfiguration));
@@ -211,7 +211,7 @@ public class TrustChainMetadataCacheTest extends AbstractFederationFlowTest {
                 .expirationTime(Date.from(Instant.now().plusSeconds(300)))
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
-        final String subordinateStatement = TrustChainTestUtil.signedJwt(
+        final String subordinateStatement = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, trustedIntermediateKey, "entity-statement+jwt", builder2.build()).serialize();
 
         mapResponse(subordinateStatementUrl(trustedIntermediateId + "/fetch", entityId),
@@ -243,7 +243,7 @@ public class TrustChainMetadataCacheTest extends AbstractFederationFlowTest {
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()))
                 .claim("crit", List.of("default_crit"))
                 .claim("authority_hints", List.of(anchorId));
-        final String entityConfiguration = TrustChainTestUtil.signedJwt(
+        final String entityConfiguration = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, leafKey, "entity-statement+jwt", builder.build()).serialize();
 
         mapResponse(entityConfigurationUrl(entityId), mockResponse(entityConfiguration));
@@ -253,7 +253,7 @@ public class TrustChainMetadataCacheTest extends AbstractFederationFlowTest {
                 .expirationTime(Date.from(Instant.now().plusSeconds(300)))
                 .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
                 .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
-        final String subordinateStatement = TrustChainTestUtil.signedJwt(
+        final String subordinateStatement = FederationJwtSupport.signedJwt(
                 JWSAlgorithm.RS256, trustedAnchorKey, "entity-statement+jwt", builder2.build()).serialize();
 
         mapResponse(entityConfigurationUrl(anchorId), mockResponse(trustedAnchorConfiguration()));
diff --git a/oidfed-common-impl/pom.xml b/oidfed-common-impl/pom.xml
index ddc22b0..92f3482 100644
--- a/oidfed-common-impl/pom.xml
+++ b/oidfed-common-impl/pom.xml
@@ -161,6 +161,21 @@
             <artifactId>jcommander</artifactId>
             <scope>provided</scope>
         </dependency>
+        <dependency>
+            <groupId>${oidfed-common.groupId}</groupId>
+            <artifactId>oidfed-common-testing</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${spring.groupId}</groupId>
+            <artifactId>spring-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+         <dependency>
+            <groupId>${opensaml.groupId}</groupId>
+            <artifactId>opensaml-spring</artifactId>
+            <scope>test</scope>
+        </dependency>
 	</dependencies>
 	
 </project>
diff --git a/oidfed-common-impl/src/test/java/net/shibboleth/oidfed/metadata/jackson/JacksonTestingSupport.java b/oidfed-common-impl/src/test/java/net/shibboleth/oidfed/metadata/jackson/JacksonTestingSupport.java
new file mode 100644
index 0000000..cb97c88
--- /dev/null
+++ b/oidfed-common-impl/src/test/java/net/shibboleth/oidfed/metadata/jackson/JacksonTestingSupport.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.oidfed.metadata.jackson;
+
+import java.time.Instant;
+
+import javax.annotation.Nonnull;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.module.SimpleAbstractTypeResolver;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.nimbusds.jose.jwk.JWKSet;
+
+import net.shibboleth.oidc.metadata.policy.MetadataPolicy;
+import net.shibboleth.oidfed.metadata.payload.claim.Metadata;
+import net.shibboleth.oidfed.metadata.payload.claim.impl.MetadataImpl;
+import net.shibboleth.oidfed.metadata.policy.FederationMetadataPolicyDeserializer;
+
+/**
+ * Static support methods for testing with Jackson object mapper.
+ */
+public class JacksonTestingSupport {
+
+    /**
+     * Builds a similar default JWT payload mapper that in Spring environment is defined as bean
+     * shibboleth.oidfed.JWTPayloadJSONObjectMapper.
+     * 
+     * @return payload object mapper
+     */
+    @Nonnull public static ObjectMapper payloadObjectMapper() {
+        final SimpleModule jacksonModule = new SimpleModule();
+        jacksonModule.addDeserializer(MetadataPolicy.class, new FederationMetadataPolicyDeserializer("scope"));
+        jacksonModule.addDeserializer(JWKSet.class, new JWKSetDeserializer());
+        jacksonModule.addDeserializer(Instant.class, new InstantDeserializer());
+        final SimpleAbstractTypeResolver jacksonResolver = new SimpleAbstractTypeResolver();
+        jacksonResolver.addMapping(Metadata.class, MetadataImpl.class);
+        jacksonModule.setAbstractTypes(jacksonResolver);
+        final ObjectMapper objectMapper = new ObjectMapper();
+        objectMapper.registerModule(jacksonModule);
+        return objectMapper;
+    }
+
+}
diff --git a/oidfed-common-testing/pom.xml b/oidfed-common-testing/pom.xml
index 7153e1c..c2ee3fe 100644
--- a/oidfed-common-testing/pom.xml
+++ b/oidfed-common-testing/pom.xml
@@ -31,16 +31,15 @@
             <artifactId>spring-test</artifactId>
             <scope>compile</scope>
         </dependency>
-
-		<!-- Provided dependencies -->
         <dependency>
-            <groupId>${oidfed-common.groupId}</groupId>
-            <artifactId>oidfed-common-api</artifactId>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
             <scope>compile</scope>
         </dependency>
+        <!-- Provided dependencies -->
         <dependency>
             <groupId>${oidfed-common.groupId}</groupId>
-            <artifactId>oidfed-common-impl</artifactId>
+            <artifactId>oidfed-common-api</artifactId>
             <scope>compile</scope>
         </dependency>
         <dependency>
diff --git a/oidfed-common-testing/src/main/java/net/shibboleth/oidfed/testing/FederationJwtSupport.java b/oidfed-common-testing/src/main/java/net/shibboleth/oidfed/testing/FederationJwtSupport.java
new file mode 100644
index 0000000..6959e6d
--- /dev/null
+++ b/oidfed-common-testing/src/main/java/net/shibboleth/oidfed/testing/FederationJwtSupport.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.oidfed.testing;
+
+import java.time.Instant;
+import java.util.Date;
+
+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.jwt.JWTClaimsSet;
+import com.nimbusds.jwt.SignedJWT;
+
+/**
+ * Various utility methods for building JWTs related to OpenID Federation.
+ */
+public class FederationJwtSupport {
+
+    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("trust_mark_type", id)
+                .issueTime(new Date())
+                .expirationTime(exp == null ? null : Date.from(exp));
+        return trustMark(algorithm, jwk, builder.build());
+    }
+
+    public static SignedJWT trustMark(final JWSAlgorithm algorithm, final JWK jwk, final JWTClaimsSet claimsSet) {
+        return signedJwt(algorithm, jwk, "trust-mark+jwt", claimsSet);
+    }
+
+    public static SignedJWT entityStatement(final JWSAlgorithm algorithm, final JWK jwk, final JWTClaimsSet claimsSet) {
+        return signedJwt(algorithm, jwk, new JWSHeader.Builder(algorithm)
+                    .type(new JOSEObjectType("entity-statement+jwt"))
+                    .keyID(jwk.getKeyID())
+                    .build(),
+                    claimsSet);
+    }
+    
+    public static SignedJWT signedJwt(final JWSAlgorithm algorithm, final JWK jwk, final String type,
+            final JWTClaimsSet claimsSet) {
+        return signedJwt(algorithm, jwk,
+                new JWSHeader.Builder(algorithm).type(new JOSEObjectType(type)).keyID(jwk.getKeyID()).build(),
+                claimsSet);
+    }
+
+    public static SignedJWT signedJwt(final JWSAlgorithm algorithm, final JWK jwk, final JWSHeader header,
+            final JWTClaimsSet claimsSet) {
+        final SignedJWT signedJwt = new SignedJWT(header, 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/oidfed-common-testing/src/main/java/net/shibboleth/oidfed/testing/TrustChainTestUtil.java b/oidfed-common-testing/src/main/java/net/shibboleth/oidfed/testing/TrustChainTestUtil.java
deleted file mode 100644
index 587fa8b..0000000
--- a/oidfed-common-testing/src/main/java/net/shibboleth/oidfed/testing/TrustChainTestUtil.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * 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.oidfed.testing;
-
-import java.text.ParseException;
-import java.time.Instant;
-import java.util.Date;
-import java.util.List;
-
-import javax.annotation.Nonnull;
-
-import org.testng.Assert;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.module.SimpleAbstractTypeResolver;
-import com.fasterxml.jackson.databind.module.SimpleModule;
-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.JWKSet;
-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 net.shibboleth.oidc.metadata.policy.MetadataPolicy;
-import net.shibboleth.oidfed.metadata.EntityStatement;
-import net.shibboleth.oidfed.metadata.impl.EntityConfigurationImpl;
-import net.shibboleth.oidfed.metadata.impl.SubordinateStatementImpl;
-import net.shibboleth.oidfed.metadata.jackson.InstantDeserializer;
-import net.shibboleth.oidfed.metadata.jackson.JWKSetDeserializer;
-import net.shibboleth.oidfed.metadata.payload.claim.Metadata;
-import net.shibboleth.oidfed.metadata.payload.claim.impl.MetadataImpl;
-import net.shibboleth.oidfed.metadata.policy.FederationMetadataPolicyDeserializer;
-
-/**
- * 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.getJwt().getJWTClaimsSet())
-                    .subject(leaf.getSubject())
-                    .issueTime(new Date())
-                    .issuer(intermediateId)
-                    .build());
-            return List.of(leaf, leafSubordinateStatement, intermediateStatement, trustAnchor);
-        } catch (final  JOSEException | ParseException 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) {
-        return entityStatement(signedJwt(algorithm, jwk, "entity-statement+jwt", claimsSet));
-    }
-
-    public static EntityStatement<?> entityStatement(final SignedJWT jwt) {
-        try {
-            if (jwt.getJWTClaimsSet().getSubject().equals(jwt.getJWTClaimsSet().getIssuer())) {
-                return EntityConfigurationImpl.parse(jwt, payloadObjectMapper());
-            }
-            return SubordinateStatementImpl.parse(jwt, payloadObjectMapper());
-        } catch (JsonProcessingException | ParseException e) {
-            Assert.fail("Could not construct entity configuration", e);
-        }
-        return null;
-        
-    }
-
-    @Nonnull public static ObjectMapper payloadObjectMapper() {
-        final SimpleModule jacksonModule = new SimpleModule();
-        jacksonModule.addDeserializer(MetadataPolicy.class, new FederationMetadataPolicyDeserializer("scope"));
-        jacksonModule.addDeserializer(JWKSet.class, new JWKSetDeserializer());
-        jacksonModule.addDeserializer(Instant.class, new InstantDeserializer());
-        final SimpleAbstractTypeResolver jacksonResolver = new SimpleAbstractTypeResolver();
-        jacksonResolver.addMapping(Metadata.class, MetadataImpl.class);
-        jacksonModule.setAbstractTypes(jacksonResolver);
-        final ObjectMapper objectMapper = new ObjectMapper();
-        objectMapper.registerModule(jacksonModule);
-        return objectMapper;
-    }
-
-    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("trust_mark_type", 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) {
-        return signedJwt(algorithm, jwk,
-                new JWSHeader.Builder(algorithm).type(new JOSEObjectType(type)).keyID(jwk.getKeyID()).build(),
-                claimsSet);
-    }
-
-    public static SignedJWT signedJwt(final JWSAlgorithm algorithm, final JWK jwk, final JWSHeader header,
-            final JWTClaimsSet claimsSet) {
-        final SignedJWT signedJwt = new SignedJWT(header, 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;
-    }
-
-}

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


More information about the commits mailing list