You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by bu...@apache.org on 2020/02/13 08:08:39 UTC

[cxf] branch master updated: cxf-systests-rs-security: add testAuthorizationCodeFlowWithPKCE

This is an automated email from the ASF dual-hosted git repository.

buhhunyx pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cxf.git


The following commit(s) were added to refs/heads/master by this push:
     new a44960c  cxf-systests-rs-security: add testAuthorizationCodeFlowWithPKCE
a44960c is described below

commit a44960c899ed754f2192fcc62b4320b6bbb4b184
Author: Alexey Markevich <bu...@gmail.com>
AuthorDate: Thu Feb 13 11:07:51 2020 +0300

    cxf-systests-rs-security: add testAuthorizationCodeFlowWithPKCE
---
 .../security/oauth2/grants/PublicClientTest.java   | 159 +++++----------------
 .../systest/jaxrs/security/oidc/OIDCFlowTest.java  |  44 ++++++
 .../oidc/oidc-server-jcache-jwt-non-persist.xml    |  11 +-
 .../jaxrs/security/oidc/oidc-server-jcache-jwt.xml |  11 +-
 .../jaxrs/security/oidc/oidc-server-jcache.xml     |  11 +-
 .../jaxrs/security/oidc/oidc-server-jpa.xml        |  11 +-
 6 files changed, 118 insertions(+), 129 deletions(-)

diff --git a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/grants/PublicClientTest.java b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/grants/PublicClientTest.java
index 5aa55d7..7608fd6 100644
--- a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/grants/PublicClientTest.java
+++ b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/grants/PublicClientTest.java
@@ -27,7 +27,9 @@ import org.apache.cxf.jaxrs.client.WebClient;
 import org.apache.cxf.rs.security.oauth2.common.ClientAccessToken;
 import org.apache.cxf.rs.security.oauth2.grants.code.CodeVerifierTransformer;
 import org.apache.cxf.rs.security.oauth2.grants.code.DigestCodeVerifier;
+import org.apache.cxf.rs.security.oauth2.grants.code.PlainCodeVerifier;
 import org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException;
+import org.apache.cxf.rs.security.oauth2.utils.OAuthConstants;
 import org.apache.cxf.rt.security.crypto.CryptoUtils;
 import org.apache.cxf.systest.jaxrs.security.SecurityTestUtil;
 import org.apache.cxf.systest.jaxrs.security.oauth2.common.OAuth2TestUtils;
@@ -51,6 +53,11 @@ public class PublicClientTest extends AbstractClientServerTestBase {
     public static final String JCACHE_PORT = TestUtil.getPortNumber("jaxrs-oauth2-grants-jcache-public");
     public static final String JCACHE_PORT2 = TestUtil.getPortNumber("jaxrs-oauth2-grants2-jcache-public");
 
+    // services2 doesn't require basic auth
+    private static final String TOKEN_SERVICE_ADDRESS_PLAIN = "https://localhost:" + JCACHE_PORT + "/services2/";
+    // services3 doesn't require basic auth
+    private static final String TOKEN_SERVICE_ADDRESS_DIGEST = "https://localhost:" + JCACHE_PORT + "/services3/";
+
     @BeforeClass
     public static void startServers() throws Exception {
         assertTrue("server did not launch correctly",
@@ -108,112 +115,35 @@ public class PublicClientTest extends AbstractClientServerTestBase {
 
     @org.junit.Test
     public void testPKCEPlain() throws Exception {
-        URL busFile = PublicClientTest.class.getResource("publicclient.xml");
-
-        String address = "https://localhost:" + JCACHE_PORT + "/services/";
-        WebClient client = WebClient.create(address, OAuth2TestUtils.setupProviders(),
-                                            "alice", "security", busFile.toString());
-        // Save the Cookie for the second request...
-        WebClient.getConfig(client).getRequestContext().put(
-            org.apache.cxf.message.Message.MAINTAIN_SESSION, Boolean.TRUE);
-
-        // Get Authorization Code
-        AuthorizationCodeParameters parameters = new AuthorizationCodeParameters();
-        parameters.setConsumerId("consumer-id");
-        String codeVerifier = Base64UrlUtility.encode(CryptoUtils.generateSecureRandomBytes(32));
-        parameters.setCodeChallenge(codeVerifier);
-        parameters.setCodeChallengeMethod("plain");
-        parameters.setResponseType("code");
-        parameters.setPath("authorize/");
-
-        String location = OAuth2TestUtils.getLocation(client, parameters);
-        String code = OAuth2TestUtils.getSubstring(location, "code");
-        assertNotNull(code);
-
-        // Now get the access token - note services2 doesn't require basic auth
-        String address2 = "https://localhost:" + JCACHE_PORT + "/services2/";
-        client = WebClient.create(address2, busFile.toString());
-
-        ClientAccessToken accessToken =
-            OAuth2TestUtils.getAccessTokenWithAuthorizationCode(client, code, "consumer-id", null, codeVerifier);
-        assertNotNull(accessToken.getTokenKey());
+        testPKCE(new PlainCodeVerifier(), TOKEN_SERVICE_ADDRESS_PLAIN);
     }
 
     @org.junit.Test
     public void testPKCEPlainMissingVerifier() throws Exception {
-        URL busFile = PublicClientTest.class.getResource("publicclient.xml");
-
-        String address = "https://localhost:" + JCACHE_PORT + "/services/";
-        WebClient client = WebClient.create(address, OAuth2TestUtils.setupProviders(),
-                                            "alice", "security", busFile.toString());
-        // Save the Cookie for the second request...
-        WebClient.getConfig(client).getRequestContext().put(
-            org.apache.cxf.message.Message.MAINTAIN_SESSION, Boolean.TRUE);
-
-        // Get Authorization Code
-        AuthorizationCodeParameters parameters = new AuthorizationCodeParameters();
-        parameters.setConsumerId("consumer-id");
-        String codeVerifier = Base64UrlUtility.encode(CryptoUtils.generateSecureRandomBytes(32));
-        parameters.setCodeChallenge(codeVerifier);
-        parameters.setCodeChallengeMethod("plain");
-        parameters.setResponseType("code");
-        parameters.setPath("authorize/");
-
-        String location = OAuth2TestUtils.getLocation(client, parameters);
-        String code = OAuth2TestUtils.getSubstring(location, "code");
-        assertNotNull(code);
-
-        // Now get the access token - note services2 doesn't require basic auth
-        String address2 = "https://localhost:" + JCACHE_PORT + "/services2/";
-        client = WebClient.create(address2, busFile.toString());
-
-        try {
-            OAuth2TestUtils.getAccessTokenWithAuthorizationCode(client, code, "consumer-id", null);
-            fail("Failure expected on a missing verifier");
-        } catch (OAuthServiceException ex) {
-            assertFalse(ex.getError().getError().isEmpty());
-        }
+        testPKCEMissingVerifier(new PlainCodeVerifier(), TOKEN_SERVICE_ADDRESS_PLAIN);
     }
 
     @org.junit.Test
     public void testPKCEPlainDifferentVerifier() throws Exception {
-        URL busFile = PublicClientTest.class.getResource("publicclient.xml");
-
-        String address = "https://localhost:" + JCACHE_PORT + "/services/";
-        WebClient client = WebClient.create(address, OAuth2TestUtils.setupProviders(),
-                                            "alice", "security", busFile.toString());
-        // Save the Cookie for the second request...
-        WebClient.getConfig(client).getRequestContext().put(
-            org.apache.cxf.message.Message.MAINTAIN_SESSION, Boolean.TRUE);
-
-        // Get Authorization Code
-        AuthorizationCodeParameters parameters = new AuthorizationCodeParameters();
-        parameters.setConsumerId("consumer-id");
-        String codeVerifier = Base64UrlUtility.encode(CryptoUtils.generateSecureRandomBytes(32));
-        parameters.setCodeChallenge(codeVerifier);
-        parameters.setCodeChallengeMethod("plain");
-        parameters.setResponseType("code");
-        parameters.setPath("authorize/");
-
-        String location = OAuth2TestUtils.getLocation(client, parameters);
-        String code = OAuth2TestUtils.getSubstring(location, "code");
-        assertNotNull(code);
+        testPKCEDifferentVerifier(new PlainCodeVerifier(), TOKEN_SERVICE_ADDRESS_PLAIN);
+    }
 
-        // Now get the access token - note services2 doesn't require basic auth
-        String address2 = "https://localhost:" + JCACHE_PORT + "/services2/";
-        client = WebClient.create(address2, busFile.toString());
+    @org.junit.Test
+    public void testPKCEDigest() {
+        testPKCE(new DigestCodeVerifier(), TOKEN_SERVICE_ADDRESS_DIGEST);
+    }
 
-        try {
-            codeVerifier = Base64UrlUtility.encode(CryptoUtils.generateSecureRandomBytes(32));
-            OAuth2TestUtils.getAccessTokenWithAuthorizationCode(client, code, "consumer-id", null, codeVerifier);
-            fail("Failure expected on a different verifier");
-        } catch (OAuthServiceException ex) {
-            assertFalse(ex.getError().getError().isEmpty());
-        }
+    @org.junit.Test
+    public void testPKCEDigestMissingVerifier() {
+        testPKCEMissingVerifier(new DigestCodeVerifier(), TOKEN_SERVICE_ADDRESS_DIGEST);
     }
 
     @org.junit.Test
-    public void testPKCEDigest() throws Exception {
+    public void testPKCEDigestDifferentVerifier() {
+        testPKCEDifferentVerifier(new DigestCodeVerifier(), TOKEN_SERVICE_ADDRESS_DIGEST);
+    }
+
+    private void testPKCE(CodeVerifierTransformer transformer, String tokenServiceAddress) {
         URL busFile = PublicClientTest.class.getResource("publicclient.xml");
 
         String address = "https://localhost:" + JCACHE_PORT + "/services/";
@@ -227,28 +157,23 @@ public class PublicClientTest extends AbstractClientServerTestBase {
         AuthorizationCodeParameters parameters = new AuthorizationCodeParameters();
         parameters.setConsumerId("consumer-id");
         String codeVerifier = Base64UrlUtility.encode(CryptoUtils.generateSecureRandomBytes(32));
-        CodeVerifierTransformer transformer = new DigestCodeVerifier();
-        String codeChallenge = transformer.transformCodeVerifier(codeVerifier);
-        parameters.setCodeChallenge(codeChallenge);
+        parameters.setCodeChallenge(transformer.transformCodeVerifier(codeVerifier));
         parameters.setCodeChallengeMethod(transformer.getChallengeMethod());
-        parameters.setResponseType("code");
+        parameters.setResponseType(OAuthConstants.CODE_RESPONSE_TYPE);
         parameters.setPath("authorize/");
 
         String location = OAuth2TestUtils.getLocation(client, parameters);
         String code = OAuth2TestUtils.getSubstring(location, "code");
         assertNotNull(code);
 
-        // Now get the access token - note services3 doesn't require basic auth
-        String address2 = "https://localhost:" + JCACHE_PORT + "/services3/";
-        client = WebClient.create(address2, busFile.toString());
-
+        // Now get the access token
+        client = WebClient.create(tokenServiceAddress, busFile.toString());
         ClientAccessToken accessToken =
             OAuth2TestUtils.getAccessTokenWithAuthorizationCode(client, code, "consumer-id", null, codeVerifier);
         assertNotNull(accessToken.getTokenKey());
     }
 
-    @org.junit.Test
-    public void testPKCEDigestMissingVerifier() throws Exception {
+    private void testPKCEMissingVerifier(CodeVerifierTransformer transformer, String tokenServiceAddress) {
         URL busFile = PublicClientTest.class.getResource("publicclient.xml");
 
         String address = "https://localhost:" + JCACHE_PORT + "/services/";
@@ -262,21 +187,17 @@ public class PublicClientTest extends AbstractClientServerTestBase {
         AuthorizationCodeParameters parameters = new AuthorizationCodeParameters();
         parameters.setConsumerId("consumer-id");
         String codeVerifier = Base64UrlUtility.encode(CryptoUtils.generateSecureRandomBytes(32));
-        CodeVerifierTransformer transformer = new DigestCodeVerifier();
-        String codeChallenge = transformer.transformCodeVerifier(codeVerifier);
-        parameters.setCodeChallenge(codeChallenge);
+        parameters.setCodeChallenge(transformer.transformCodeVerifier(codeVerifier));
         parameters.setCodeChallengeMethod(transformer.getChallengeMethod());
-        parameters.setResponseType("code");
+        parameters.setResponseType(OAuthConstants.CODE_RESPONSE_TYPE);
         parameters.setPath("authorize/");
 
         String location = OAuth2TestUtils.getLocation(client, parameters);
         String code = OAuth2TestUtils.getSubstring(location, "code");
         assertNotNull(code);
 
-        // Now get the access token - note services3 doesn't require basic auth
-        String address2 = "https://localhost:" + JCACHE_PORT + "/services3/";
-        client = WebClient.create(address2, OAuth2TestUtils.setupProviders(), busFile.toString());
-
+        // Now get the access token
+        client = WebClient.create(tokenServiceAddress, busFile.toString());
         try {
             OAuth2TestUtils.getAccessTokenWithAuthorizationCode(client, code, "consumer-id", null);
             fail("Failure expected on a missing verifier");
@@ -285,8 +206,7 @@ public class PublicClientTest extends AbstractClientServerTestBase {
         }
     }
 
-    @org.junit.Test
-    public void testPKCEDigestDifferentVerifier() throws Exception {
+    private void testPKCEDifferentVerifier(CodeVerifierTransformer transformer, String tokenServiceAddress) {
         URL busFile = PublicClientTest.class.getResource("publicclient.xml");
 
         String address = "https://localhost:" + JCACHE_PORT + "/services/";
@@ -300,23 +220,20 @@ public class PublicClientTest extends AbstractClientServerTestBase {
         AuthorizationCodeParameters parameters = new AuthorizationCodeParameters();
         parameters.setConsumerId("consumer-id");
         String codeVerifier = Base64UrlUtility.encode(CryptoUtils.generateSecureRandomBytes(32));
-        CodeVerifierTransformer transformer = new DigestCodeVerifier();
-        String codeChallenge = transformer.transformCodeVerifier(codeVerifier);
-        parameters.setCodeChallenge(codeChallenge);
+        parameters.setCodeChallenge(transformer.transformCodeVerifier(codeVerifier));
         parameters.setCodeChallengeMethod(transformer.getChallengeMethod());
-        parameters.setResponseType("code");
+        parameters.setResponseType(OAuthConstants.CODE_RESPONSE_TYPE);
         parameters.setPath("authorize/");
 
         String location = OAuth2TestUtils.getLocation(client, parameters);
         String code = OAuth2TestUtils.getSubstring(location, "code");
         assertNotNull(code);
 
-        // Now get the access token - note services3 doesn't require basic auth
-        String address2 = "https://localhost:" + JCACHE_PORT + "/services3/";
-        client = WebClient.create(address2, busFile.toString());
+        // Now get the access token
+        client = WebClient.create(tokenServiceAddress, busFile.toString());
 
+        codeVerifier = Base64UrlUtility.encode(CryptoUtils.generateSecureRandomBytes(32));
         try {
-            codeVerifier = Base64UrlUtility.encode(CryptoUtils.generateSecureRandomBytes(32));
             OAuth2TestUtils.getAccessTokenWithAuthorizationCode(client, code, "consumer-id", null, codeVerifier);
             fail("Failure expected on a different verifier");
         } catch (OAuthServiceException ex) {
diff --git a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oidc/OIDCFlowTest.java b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oidc/OIDCFlowTest.java
index c6441d2..4d8223e 100644
--- a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oidc/OIDCFlowTest.java
+++ b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oidc/OIDCFlowTest.java
@@ -32,6 +32,7 @@ import java.util.Collections;
 import javax.ws.rs.core.Form;
 import javax.ws.rs.core.Response;
 
+import org.apache.cxf.common.util.Base64UrlUtility;
 import org.apache.cxf.jaxrs.client.WebClient;
 import org.apache.cxf.rs.security.jose.jwa.SignatureAlgorithm;
 import org.apache.cxf.rs.security.jose.jwk.JsonWebKeys;
@@ -43,8 +44,12 @@ import org.apache.cxf.rs.security.jose.jwt.JwtConstants;
 import org.apache.cxf.rs.security.jose.jwt.JwtToken;
 import org.apache.cxf.rs.security.oauth2.common.ClientAccessToken;
 import org.apache.cxf.rs.security.oauth2.common.OAuthAuthorizationData;
+import org.apache.cxf.rs.security.oauth2.grants.code.CodeVerifierTransformer;
+import org.apache.cxf.rs.security.oauth2.grants.code.DigestCodeVerifier;
+import org.apache.cxf.rs.security.oauth2.utils.OAuthConstants;
 import org.apache.cxf.rs.security.oidc.common.IdToken;
 import org.apache.cxf.rs.security.oidc.utils.OidcUtils;
+import org.apache.cxf.rt.security.crypto.CryptoUtils;
 import org.apache.cxf.systest.jaxrs.security.SecurityTestUtil;
 import org.apache.cxf.systest.jaxrs.security.oauth2.common.OAuth2TestUtils;
 import org.apache.cxf.systest.jaxrs.security.oauth2.common.OAuth2TestUtils.AuthorizationCodeParameters;
@@ -401,6 +406,45 @@ public class OIDCFlowTest extends AbstractBusClientServerTestBase {
     }
 
     @org.junit.Test
+    public void testAuthorizationCodeFlowWithPKCE() throws Exception {
+        URL busFile = OIDCFlowTest.class.getResource("client.xml");
+
+        String address = "https://localhost:" + port + "/services/";
+        WebClient client = WebClient.create(address,  OAuth2TestUtils.setupProviders(),
+                                            "alice", "security", busFile.toString());
+        // Save the Cookie for the second request...
+        WebClient.getConfig(client).getRequestContext().put(
+            org.apache.cxf.message.Message.MAINTAIN_SESSION, Boolean.TRUE);
+
+        // Get Authorization Code
+        AuthorizationCodeParameters parameters = new AuthorizationCodeParameters();
+        parameters.setConsumerId("consumer-id");
+        parameters.setScope(OidcUtils.OPENID_SCOPE);
+        parameters.setResponseType(OAuthConstants.CODE_RESPONSE_TYPE);
+        parameters.setPath("authorize/");
+        String codeVerifier = Base64UrlUtility.encode(CryptoUtils.generateSecureRandomBytes(32));
+        CodeVerifierTransformer transformer = new DigestCodeVerifier();
+        parameters.setCodeChallenge(transformer.transformCodeVerifier(codeVerifier));
+        parameters.setCodeChallengeMethod(transformer.getChallengeMethod());
+
+        String location = OAuth2TestUtils.getLocation(client, parameters);
+        String code = OAuth2TestUtils.getSubstring(location, "code");
+
+        assertNotNull(code);
+
+        // Now get the access token
+        client = WebClient.create(address, "consumer-id", "this-is-a-secret", busFile.toString());
+
+        ClientAccessToken accessToken =
+            OAuth2TestUtils.getAccessTokenWithAuthorizationCode(client, code, "consumer-id", null, codeVerifier);
+        assertNotNull(accessToken.getTokenKey());
+
+        if (isAccessTokenInJWTFormat()) {
+            validateAccessToken(accessToken.getTokenKey());
+        }
+    }
+
+    @org.junit.Test
     public void testImplicitFlow() throws Exception {
         URL busFile = OIDCFlowTest.class.getResource("client.xml");
 
diff --git a/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/oidc/oidc-server-jcache-jwt-non-persist.xml b/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/oidc/oidc-server-jcache-jwt-non-persist.xml
index 8ed129a..6a8fc07 100644
--- a/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/oidc/oidc-server-jcache-jwt-non-persist.xml
+++ b/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/oidc/oidc-server-jcache-jwt-non-persist.xml
@@ -77,11 +77,17 @@ under the License.
       <property name="responseFilter" ref="idTokenFilter"/>
       <property name="idTokenProvider" ref="idTokenProviderImpl"/>
    </bean>
-   
+
    <bean id="refreshGrantHandler" class="org.apache.cxf.rs.security.oauth2.grants.refresh.RefreshTokenGrantHandler">
       <property name="dataProvider" ref="oauthProvider"/>
    </bean>
-   
+
+   <bean id="digestVerifier" class="org.apache.cxf.rs.security.oauth2.grants.code.DigestCodeVerifier" />
+   <bean id="codeGrantHandler" class="org.apache.cxf.rs.security.oauth2.grants.code.AuthorizationCodeGrantHandler">
+      <property name="dataProvider" ref="oauthProvider"/>
+      <property name="codeVerifierTransformer" ref="digestVerifier"/>
+   </bean>
+
    <bean id="idTokenProviderImpl" class="org.apache.cxf.systest.jaxrs.security.oidc.IdTokenProviderImpl"/>
 
    <bean id="idTokenFilter" class="org.apache.cxf.rs.security.oidc.idp.IdTokenResponseFilter">
@@ -93,6 +99,7 @@ under the License.
       <property name="grantHandlers">
          <list>
              <ref bean="refreshGrantHandler"/>
+             <ref bean="codeGrantHandler"/>
          </list>
       </property>
       <property name="responseFilter" ref="idTokenFilter"/>
diff --git a/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/oidc/oidc-server-jcache-jwt.xml b/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/oidc/oidc-server-jcache-jwt.xml
index 7ee1a62..99cfa9b 100644
--- a/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/oidc/oidc-server-jcache-jwt.xml
+++ b/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/oidc/oidc-server-jcache-jwt.xml
@@ -76,11 +76,17 @@ under the License.
       <property name="responseFilter" ref="idTokenFilter"/>
       <property name="idTokenProvider" ref="idTokenProviderImpl"/>
    </bean>
-   
+
    <bean id="refreshGrantHandler" class="org.apache.cxf.rs.security.oauth2.grants.refresh.RefreshTokenGrantHandler">
       <property name="dataProvider" ref="oauthProvider"/>
    </bean>
-   
+
+   <bean id="digestVerifier" class="org.apache.cxf.rs.security.oauth2.grants.code.DigestCodeVerifier" />
+   <bean id="codeGrantHandler" class="org.apache.cxf.rs.security.oauth2.grants.code.AuthorizationCodeGrantHandler">
+      <property name="dataProvider" ref="oauthProvider"/>
+      <property name="codeVerifierTransformer" ref="digestVerifier"/>
+   </bean>
+
    <bean id="idTokenProviderImpl" class="org.apache.cxf.systest.jaxrs.security.oidc.IdTokenProviderImpl"/>
 
    <bean id="idTokenFilter" class="org.apache.cxf.rs.security.oidc.idp.IdTokenResponseFilter">
@@ -92,6 +98,7 @@ under the License.
       <property name="grantHandlers">
          <list>
              <ref bean="refreshGrantHandler"/>
+             <ref bean="codeGrantHandler"/>
          </list>
       </property>
       <property name="responseFilter" ref="idTokenFilter"/>
diff --git a/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/oidc/oidc-server-jcache.xml b/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/oidc/oidc-server-jcache.xml
index 4655f1b..fa97063 100644
--- a/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/oidc/oidc-server-jcache.xml
+++ b/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/oidc/oidc-server-jcache.xml
@@ -75,11 +75,17 @@ under the License.
       <property name="responseFilter" ref="idTokenFilter"/>
       <property name="idTokenProvider" ref="idTokenProviderImpl"/>
    </bean>
-   
+
    <bean id="refreshGrantHandler" class="org.apache.cxf.rs.security.oauth2.grants.refresh.RefreshTokenGrantHandler">
       <property name="dataProvider" ref="oauthProvider"/>
    </bean>
-   
+
+   <bean id="digestVerifier" class="org.apache.cxf.rs.security.oauth2.grants.code.DigestCodeVerifier" />
+   <bean id="codeGrantHandler" class="org.apache.cxf.rs.security.oauth2.grants.code.AuthorizationCodeGrantHandler">
+      <property name="dataProvider" ref="oauthProvider"/>
+      <property name="codeVerifierTransformer" ref="digestVerifier"/>
+   </bean>
+
    <bean id="idTokenProviderImpl" class="org.apache.cxf.systest.jaxrs.security.oidc.IdTokenProviderImpl"/>
 
    <bean id="idTokenFilter" class="org.apache.cxf.rs.security.oidc.idp.IdTokenResponseFilter">
@@ -91,6 +97,7 @@ under the License.
       <property name="grantHandlers">
          <list>
              <ref bean="refreshGrantHandler"/>
+             <ref bean="codeGrantHandler"/>
          </list>
       </property>
       <property name="responseFilter" ref="idTokenFilter"/>
diff --git a/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/oidc/oidc-server-jpa.xml b/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/oidc/oidc-server-jpa.xml
index cc14c61..4e0d9db 100644
--- a/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/oidc/oidc-server-jpa.xml
+++ b/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/oidc/oidc-server-jpa.xml
@@ -88,11 +88,17 @@ under the License.
       <property name="responseFilter" ref="idTokenFilter"/>
       <property name="idTokenProvider" ref="idTokenProviderImpl"/>
    </bean>
-   
+
    <bean id="refreshGrantHandler" class="org.apache.cxf.rs.security.oauth2.grants.refresh.RefreshTokenGrantHandler">
       <property name="dataProvider" ref="oauthProvider"/>
    </bean>
-   
+
+   <bean id="digestVerifier" class="org.apache.cxf.rs.security.oauth2.grants.code.DigestCodeVerifier" />
+   <bean id="codeGrantHandler" class="org.apache.cxf.rs.security.oauth2.grants.code.AuthorizationCodeGrantHandler">
+      <property name="dataProvider" ref="oauthProvider"/>
+      <property name="codeVerifierTransformer" ref="digestVerifier"/>
+   </bean>
+
    <bean id="idTokenProviderImpl" class="org.apache.cxf.systest.jaxrs.security.oidc.IdTokenProviderImpl"/>
 
    <bean id="idTokenFilter" class="org.apache.cxf.rs.security.oidc.idp.IdTokenResponseFilter">
@@ -104,6 +110,7 @@ under the License.
       <property name="grantHandlers">
          <list>
              <ref bean="refreshGrantHandler"/>
+             <ref bean="codeGrantHandler"/>
          </list>
       </property>
       <property name="responseFilter" ref="idTokenFilter"/>