[java-idp-plugin-vci] branch dev/REFRESH updated: Bind refresh tokens to client instance (draft-ietf-oauth-attestation-based-client-auth-12 section 10.3)

Codeberg noreply at shibboleth.net
Wed Nov 4 08:35:21 UTC 2026


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

codeberg pushed a commit to branch dev/REFRESH
in repository java-idp-plugin-vci.

View the commit online:
https://codeberg.org/Shibboleth/java-idp-plugin-vci/commit/c5a38c6b50577d0df0a60b7d7c2a01b1af21ba81

The following commit(s) were added to refs/heads/dev/REFRESH by this push:
     new c5a38c6  Bind refresh tokens to client instance (draft-ietf-oauth-attestation-based-client-auth-12 section 10.3)
c5a38c6 is described below

commit c5a38c6b50577d0df0a60b7d7c2a01b1af21ba81
Author: Janne Lauros <janne.lauros at csc.fi>
AuthorDate: Wed Nov 4 10:35:07 2026 +0200

    Bind refresh tokens to client instance (draft-ietf-oauth-attestation-based-client-auth-12 section 10.3)
---
 .../ClientInstanceKeyThumbprintLookupFunction.java | 88 ++++++++++++++++++++++
 .../ClientInstanceKeyRevocationCondition.java      | 74 ++++++++++++++++++
 .../logic/OpenIDVCITokenManipulationStrategy.java  | 26 ++++++-
 .../META-INF/net.shibboleth.idp/postconfig.xml     |  7 +-
 ...entInstanceKeyThumbprintLookupFunctionTest.java | 76 +++++++++++++++++++
 .../ClientInstanceKeyRevocationConditionTest.java  | 65 ++++++++++++++++
 .../OpenIDVCITokenManipulationStrategyTest.java    | 75 ++++++++++++++++++
 7 files changed, 409 insertions(+), 2 deletions(-)

diff --git a/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/profile/context/navigate/ClientInstanceKeyThumbprintLookupFunction.java b/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/profile/context/navigate/ClientInstanceKeyThumbprintLookupFunction.java
new file mode 100644
index 0000000..aea0284
--- /dev/null
+++ b/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/profile/context/navigate/ClientInstanceKeyThumbprintLookupFunction.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2025, GÉANT
+ *
+ * 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 org.geant.shibboleth.plugin.openidvci.profile.context.navigate;
+
+import java.text.ParseException;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.geant.shibboleth.plugin.openidvci.authn.impl.ClientAttestationCredentialValidator;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.slf4j.Logger;
+
+import com.nimbusds.jose.JOSEException;
+import com.nimbusds.jose.jwk.JWK;
+import com.nimbusds.jwt.SignedJWT;
+
+import jakarta.servlet.http.HttpServletRequest;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+/**
+ * Function returning the JWK thumbprint of the client instance key, the 'cnf' key of the client attestation of the
+ * request.
+ */
+public class ClientInstanceKeyThumbprintLookupFunction implements Function<ProfileRequestContext, String> {
+
+    /** Class logger. */
+    @Nonnull
+    private final Logger log = LoggerFactory.getLogger(ClientInstanceKeyThumbprintLookupFunction.class);
+
+    /** Supplier of the servlet request the client attestation is read from. */
+    @Nonnull
+    private final Supplier<HttpServletRequest> httpServletRequestSupplier;
+
+    /**
+     * Constructor.
+     *
+     * @param supplier supplier of the servlet request
+     */
+    public ClientInstanceKeyThumbprintLookupFunction(@Nonnull final Supplier<HttpServletRequest> supplier) {
+        httpServletRequestSupplier = Constraint.isNotNull(supplier, "Servlet request supplier cannot be null");
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    @Nullable
+    public String apply(@Nullable final ProfileRequestContext profileRequestContext) {
+        final HttpServletRequest request = httpServletRequestSupplier.get();
+        if (request == null) {
+            return null;
+        }
+        final String attestation = request.getHeader(ClientAttestationCredentialValidator.ATTESTATION_HEADER);
+        if (attestation == null || attestation.isEmpty()) {
+            return null;
+        }
+        try {
+            final Object confirmation = SignedJWT.parse(attestation).getJWTClaimsSet().getClaim("cnf");
+            if (!(confirmation instanceof Map<?, ?> cnf) || !(cnf.get("jwk") instanceof Map<?, ?> jwk)) {
+                return null;
+            }
+            @SuppressWarnings("unchecked")
+            final Map<String, Object> jwkObject = (Map<String, Object>) jwk;
+            return JWK.parse(jwkObject).computeThumbprint().toString();
+        } catch (final ParseException | JOSEException e) {
+            log.warn("Unable to read the client instance key of the client attestation: {}", e.getMessage());
+            return null;
+        }
+    }
+
+}
diff --git a/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/profile/logic/ClientInstanceKeyRevocationCondition.java b/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/profile/logic/ClientInstanceKeyRevocationCondition.java
new file mode 100644
index 0000000..a4f0218
--- /dev/null
+++ b/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/profile/logic/ClientInstanceKeyRevocationCondition.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2025, GÉANT
+ *
+ * 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 org.geant.shibboleth.plugin.openidvci.profile.logic;
+
+import java.util.function.BiPredicate;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.slf4j.Logger;
+
+import com.nimbusds.jwt.JWTClaimsSet;
+
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+/**
+ * Condition true when a token carries a client instance key thumbprint that differs from the one of the client
+ * attestation of the request.
+ */
+public class ClientInstanceKeyRevocationCondition implements BiPredicate<ProfileRequestContext, JWTClaimsSet> {
+
+    /** Class logger. */
+    @Nonnull
+    private final Logger log = LoggerFactory.getLogger(ClientInstanceKeyRevocationCondition.class);
+
+    /** Strategy used to locate the client instance key thumbprint of the request. */
+    @Nonnull
+    private final Function<ProfileRequestContext, String> thumbprintLookupStrategy;
+
+    /**
+     * Constructor.
+     *
+     * @param strategy lookup strategy for the client instance key thumbprint of the request
+     */
+    public ClientInstanceKeyRevocationCondition(@Nonnull final Function<ProfileRequestContext, String> strategy) {
+        thumbprintLookupStrategy = Constraint.isNotNull(strategy, "Thumbprint lookup strategy cannot be null");
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean test(@Nullable final ProfileRequestContext profileRequestContext,
+            @Nullable final JWTClaimsSet claims) {
+        final Object bound = claims != null
+                ? claims.getClaim(OpenIDVCITokenManipulationStrategy.CLIENT_INSTANCE_KEY)
+                : null;
+        if (bound == null) {
+            return false;
+        }
+        final String current = thumbprintLookupStrategy.apply(profileRequestContext);
+        if (!bound.equals(current)) {
+            log.warn("Token is bound to client instance key {}, request presents {}", bound, current);
+            return true;
+        }
+        return false;
+    }
+
+}
diff --git a/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/profile/logic/OpenIDVCITokenManipulationStrategy.java b/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/profile/logic/OpenIDVCITokenManipulationStrategy.java
index 5926a17..eb63d84 100644
--- a/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/profile/logic/OpenIDVCITokenManipulationStrategy.java
+++ b/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/profile/logic/OpenIDVCITokenManipulationStrategy.java
@@ -22,6 +22,7 @@ import java.util.function.BiFunction;
 import java.util.function.Function;
 
 import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 
 import org.geant.shibboleth.plugin.openidvci.messaging.context.TokenContext;
 import org.geant.shibboleth.plugin.openidvci.messaging.context.navigate.AuthorizationDetailsLookupFunction;
@@ -42,7 +43,8 @@ import net.shibboleth.shared.primitive.LoggerFactory;
  * 
  * 1) authorization_details and stores it to token, usually either authorization
  * code or access token, 2) potential verifiable credentials, stores them to
- * access token, 3) issued credential identifiers, stores them to access token.
+ * access token, 3) issued credential identifiers, stores them to access token, 4) the client instance key
+ * thumbprint of the client attestation of a token request.
  *
  */
 public class OpenIDVCITokenManipulationStrategy
@@ -57,6 +59,9 @@ public class OpenIDVCITokenManipulationStrategy
     /** Claim name carrying the issued credential identifiers. */
     public static final String CREDENTIAL_IDENTIFIERS = "vci.int.credentialIdentifiers";
 
+    /** Claim name carrying the client instance key thumbprint of the client attestation. */
+    public static final String CLIENT_INSTANCE_KEY = "vci.int.clientInstanceKey";
+
     /** Member name of the credential configuration id of an issued credential identifier. */
     public static final String CREDENTIAL_CONFIGURATION_ID = "credential_configuration_id";
 
@@ -68,6 +73,10 @@ public class OpenIDVCITokenManipulationStrategy
     @Nonnull
     private Function<ProfileRequestContext, List<OpenIDVCIAuthorizationDetail>> authorizationDetailsStrategy;
 
+    /** Strategy used to locate the client instance key thumbprint of the client attestation. */
+    @Nullable
+    private Function<ProfileRequestContext, String> clientInstanceKeyLookupStrategy;
+
     /**
      * Constructor.
      */
@@ -87,6 +96,15 @@ public class OpenIDVCITokenManipulationStrategy
                 "AuthorizationDetailsLookupStrategy lookup strategy cannot be null");
     }
 
+    /**
+     * Set the strategy used to locate the client instance key thumbprint of the client attestation.
+     *
+     * @param strategy lookup strategy
+     */
+    public void setClientInstanceKeyLookupStrategy(@Nullable final Function<ProfileRequestContext, String> strategy) {
+        clientInstanceKeyLookupStrategy = strategy;
+    }
+
     /** {@inheritDoc} */
     @Override
     public Map<String, Object> apply(final ProfileRequestContext profileRequestContext,
@@ -112,6 +130,12 @@ public class OpenIDVCITokenManipulationStrategy
                 claims.put(CREDENTIAL_IDENTIFIERS, tokenContext.getIssuedCredentialIdentifiers());
             }
         }
+        if (message instanceof OpenIDVCITokenRequest && clientInstanceKeyLookupStrategy != null) {
+            final String thumbprint = clientInstanceKeyLookupStrategy.apply(profileRequestContext);
+            if (thumbprint != null) {
+                claims.put(CLIENT_INSTANCE_KEY, thumbprint);
+            }
+        }
         return claims;
     }
 
diff --git a/openid-vci-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml b/openid-vci-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
index d6fa8df..a17535d 100644
--- a/openid-vci-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
+++ b/openid-vci-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
@@ -80,7 +80,12 @@
         p:proofLifetime="%{openidvci.attestation.proofLifetime:PT5M}" />
         
     <bean id="openidvci.TokenManipulationStrategy"
-        class="org.geant.shibboleth.plugin.openidvci.profile.logic.OpenIDVCITokenManipulationStrategy" />
+        class="org.geant.shibboleth.plugin.openidvci.profile.logic.OpenIDVCITokenManipulationStrategy"
+        p:clientInstanceKeyLookupStrategy-ref="openidvci.ClientInstanceKeyThumbprintLookup" />
+
+    <bean id="openidvci.ClientInstanceKeyThumbprintLookup"
+        class="org.geant.shibboleth.plugin.openidvci.profile.context.navigate.ClientInstanceKeyThumbprintLookupFunction"
+        c:supplier-ref="shibboleth.HttpServletRequestSupplier" />
 
     <bean id="openidvci.PushedAuthorizationDPoPJktManipulationStrategy"
         class="org.geant.shibboleth.plugin.openidvci.profile.logic.PushedAuthorizationDPoPJktManipulationStrategy" />
diff --git a/openid-vci-impl/src/test/java/org/geant/shibboleth/plugin/openidvci/profile/context/navigate/ClientInstanceKeyThumbprintLookupFunctionTest.java b/openid-vci-impl/src/test/java/org/geant/shibboleth/plugin/openidvci/profile/context/navigate/ClientInstanceKeyThumbprintLookupFunctionTest.java
new file mode 100644
index 0000000..d0313df
--- /dev/null
+++ b/openid-vci-impl/src/test/java/org/geant/shibboleth/plugin/openidvci/profile/context/navigate/ClientInstanceKeyThumbprintLookupFunctionTest.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2025, GÉANT
+ *
+ * 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 org.geant.shibboleth.plugin.openidvci.profile.context.navigate;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.nimbusds.jose.JOSEException;
+import com.nimbusds.jose.jwk.Curve;
+import com.nimbusds.jose.jwk.ECKey;
+import com.nimbusds.jose.jwk.gen.ECKeyGenerator;
+import com.nimbusds.jose.util.Base64URL;
+
+/**
+ * Tests for {@link ClientInstanceKeyThumbprintLookupFunction}.
+ */
+public class ClientInstanceKeyThumbprintLookupFunctionTest {
+
+    private MockHttpServletRequest request;
+
+    private ClientInstanceKeyThumbprintLookupFunction lookup;
+
+    @BeforeMethod
+    public void setUp() {
+        request = new MockHttpServletRequest();
+        lookup = new ClientInstanceKeyThumbprintLookupFunction(() -> request);
+    }
+
+    private static String attestation(final String payload) {
+        return Base64URL.encode("{\"alg\":\"ES256\",\"typ\":\"oauth-client-attestation+jwt\"}") + "."
+                + Base64URL.encode(payload) + "." + Base64URL.encode("signature");
+    }
+
+    @Test
+    public void thumbprintOfCnfKey() throws JOSEException {
+        final ECKey key = new ECKeyGenerator(Curve.P_256).generate();
+        request.addHeader("OAuth-Client-Attestation", attestation(
+                "{\"sub\":\"wallet\",\"cnf\":{\"jwk\":" + key.toPublicJWK().toJSONString() + "}}"));
+        Assert.assertEquals(lookup.apply(new ProfileRequestContext()), key.computeThumbprint().toString());
+    }
+
+    @Test
+    public void noAttestation() {
+        Assert.assertNull(lookup.apply(new ProfileRequestContext()));
+    }
+
+    @Test
+    public void noCnf() {
+        request.addHeader("OAuth-Client-Attestation", attestation("{\"sub\":\"wallet\"}"));
+        Assert.assertNull(lookup.apply(new ProfileRequestContext()));
+    }
+
+    @Test
+    public void unparseable() {
+        request.addHeader("OAuth-Client-Attestation", "not a jwt");
+        Assert.assertNull(lookup.apply(new ProfileRequestContext()));
+    }
+
+}
diff --git a/openid-vci-impl/src/test/java/org/geant/shibboleth/plugin/openidvci/profile/logic/ClientInstanceKeyRevocationConditionTest.java b/openid-vci-impl/src/test/java/org/geant/shibboleth/plugin/openidvci/profile/logic/ClientInstanceKeyRevocationConditionTest.java
new file mode 100644
index 0000000..640ed17
--- /dev/null
+++ b/openid-vci-impl/src/test/java/org/geant/shibboleth/plugin/openidvci/profile/logic/ClientInstanceKeyRevocationConditionTest.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2025, GÉANT
+ *
+ * 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 org.geant.shibboleth.plugin.openidvci.profile.logic;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.nimbusds.jwt.JWTClaimsSet;
+
+/**
+ * Tests for {@link ClientInstanceKeyRevocationCondition}.
+ */
+public class ClientInstanceKeyRevocationConditionTest {
+
+    private static JWTClaimsSet bound(final String thumbprint) {
+        return new JWTClaimsSet.Builder().subject("user")
+                .claim(OpenIDVCITokenManipulationStrategy.CLIENT_INSTANCE_KEY, thumbprint).build();
+    }
+
+    @Test
+    public void sameKey() {
+        Assert.assertFalse(new ClientInstanceKeyRevocationCondition(prc -> "abc")
+                .test(new ProfileRequestContext(), bound("abc")));
+    }
+
+    @Test
+    public void otherKey() {
+        Assert.assertTrue(new ClientInstanceKeyRevocationCondition(prc -> "def")
+                .test(new ProfileRequestContext(), bound("abc")));
+    }
+
+    @Test
+    public void noAttestation() {
+        Assert.assertTrue(new ClientInstanceKeyRevocationCondition(prc -> null)
+                .test(new ProfileRequestContext(), bound("abc")));
+    }
+
+    @Test
+    public void notBound() {
+        Assert.assertFalse(new ClientInstanceKeyRevocationCondition(prc -> "def")
+                .test(new ProfileRequestContext(), new JWTClaimsSet.Builder().subject("user").build()));
+    }
+
+    @Test
+    public void noClaims() {
+        Assert.assertFalse(new ClientInstanceKeyRevocationCondition(prc -> "def")
+                .test(new ProfileRequestContext(), null));
+    }
+
+}
diff --git a/openid-vci-impl/src/test/java/org/geant/shibboleth/plugin/openidvci/profile/logic/OpenIDVCITokenManipulationStrategyTest.java b/openid-vci-impl/src/test/java/org/geant/shibboleth/plugin/openidvci/profile/logic/OpenIDVCITokenManipulationStrategyTest.java
new file mode 100644
index 0000000..13ed978
--- /dev/null
+++ b/openid-vci-impl/src/test/java/org/geant/shibboleth/plugin/openidvci/profile/logic/OpenIDVCITokenManipulationStrategyTest.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2025, GÉANT
+ *
+ * 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 org.geant.shibboleth.plugin.openidvci.profile.logic;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.geant.shibboleth.plugin.openidvci.messaging.impl.OpenIDVCITokenRequest;
+import org.opensaml.messaging.context.MessageContext;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.nimbusds.common.contenttype.ContentType;
+import com.nimbusds.oauth2.sdk.ParseException;
+import com.nimbusds.oauth2.sdk.http.HTTPRequest;
+
+/**
+ * Tests for the client instance key of {@link OpenIDVCITokenManipulationStrategy}.
+ */
+public class OpenIDVCITokenManipulationStrategyTest {
+
+    private ProfileRequestContext prc;
+
+    @BeforeMethod
+    public void setUp() throws ParseException, URISyntaxException {
+        final HTTPRequest httpRequest = new HTTPRequest(HTTPRequest.Method.POST, new URI("http://example.com"));
+        httpRequest.setContentType(ContentType.APPLICATION_URLENCODED.toString());
+        httpRequest.setBody("client_id=wallet&grant_type=refresh_token&refresh_token=abc");
+        final MessageContext inbound = new MessageContext();
+        inbound.setMessage(OpenIDVCITokenRequest.parse(httpRequest));
+        prc = new ProfileRequestContext();
+        prc.setInboundMessageContext(inbound);
+    }
+
+    @Test
+    public void clientInstanceKeyAdded() {
+        final OpenIDVCITokenManipulationStrategy strategy = new OpenIDVCITokenManipulationStrategy();
+        strategy.setClientInstanceKeyLookupStrategy(context -> "thumbprint");
+        final Map<String, Object> claims = strategy.apply(prc, new HashMap<>());
+        Assert.assertEquals(claims.get(OpenIDVCITokenManipulationStrategy.CLIENT_INSTANCE_KEY), "thumbprint");
+    }
+
+    @Test
+    public void noAttestation() {
+        final OpenIDVCITokenManipulationStrategy strategy = new OpenIDVCITokenManipulationStrategy();
+        strategy.setClientInstanceKeyLookupStrategy(context -> null);
+        Assert.assertFalse(strategy.apply(prc, new HashMap<>())
+                .containsKey(OpenIDVCITokenManipulationStrategy.CLIENT_INSTANCE_KEY));
+    }
+
+    @Test
+    public void noStrategy() {
+        Assert.assertFalse(new OpenIDVCITokenManipulationStrategy().apply(prc, new HashMap<>())
+                .containsKey(OpenIDVCITokenManipulationStrategy.CLIENT_INSTANCE_KEY));
+    }
+
+}

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


More information about the commits mailing list