You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by co...@apache.org on 2022/02/04 11:05:58 UTC

[cxf] branch master updated: CXF-8653 - Provide an easy way to require PKCE for the AuthorizationCodeGrantHandler

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

coheigea 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 9eaf9c4  CXF-8653 - Provide an easy way to require PKCE for the AuthorizationCodeGrantHandler
9eaf9c4 is described below

commit 9eaf9c462f97402f5a7356db03d949f445f0b8ec
Author: Colm O hEigeartaigh <co...@apache.org>
AuthorDate: Fri Feb 4 11:05:36 2022 +0000

    CXF-8653 - Provide an easy way to require PKCE for the AuthorizationCodeGrantHandler
---
 .../grants/code/AuthorizationCodeGrantHandler.java | 21 +++++++++++--
 .../security/oauth2/grants/PublicClientTest.java   | 36 +++++++---------------
 .../oauth2/grants/grants-server-public.xml         |  1 +
 3 files changed, 30 insertions(+), 28 deletions(-)

diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/code/AuthorizationCodeGrantHandler.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/code/AuthorizationCodeGrantHandler.java
index b7d787b..933a942 100644
--- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/code/AuthorizationCodeGrantHandler.java
+++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/code/AuthorizationCodeGrantHandler.java
@@ -42,6 +42,7 @@ public class AuthorizationCodeGrantHandler extends AbstractGrantHandler {
 
     private List<CodeVerifierTransformer> codeVerifierTransformers = Collections.emptyList();
     private boolean expectCodeVerifierForPublicClients;
+    private boolean requireCodeVerifier;
 
     public AuthorizationCodeGrantHandler() {
         super(OAuthConstants.AUTHORIZATION_CODE_GRANT);
@@ -153,9 +154,11 @@ public class AuthorizationCodeGrantHandler extends AbstractGrantHandler {
 
     private boolean compareCodeVerifierWithChallenge(Client c, String clientCodeVerifier,
                                                      String clientCodeChallenge, String clientCodeChallengeMethod) {
-        if (clientCodeChallenge == null && clientCodeVerifier == null
-            && (c.isConfidential() || !expectCodeVerifierForPublicClients)) {
-            return true;
+        if (clientCodeChallenge == null && clientCodeVerifier == null) {
+            if (requireCodeVerifier) {
+                return false;
+            }
+            return c.isConfidential() || !expectCodeVerifierForPublicClients;
         } else if (clientCodeChallenge != null && clientCodeVerifier == null
             || clientCodeChallenge == null && clientCodeVerifier != null) {
             return false;
@@ -191,7 +194,19 @@ public class AuthorizationCodeGrantHandler extends AbstractGrantHandler {
         this.codeVerifierTransformers = new ArrayList<>(codeVerifierTransformers);
     }
 
+    /**
+     * Require a code verifier for public clients only.
+     * @param expectCodeVerifierForPublicClients require a code verifier for public clients only.
+     */
     public void setExpectCodeVerifierForPublicClients(boolean expectCodeVerifierForPublicClients) {
         this.expectCodeVerifierForPublicClients = expectCodeVerifierForPublicClients;
     }
+
+    /**
+     * Require a code verifier (PKCE). This will override any value set for expectCodeVerifierForPublicClients
+     * @param requireCodeVerifier require a code verifier
+     */
+    public void setRequireCodeVerifier(boolean requireCodeVerifier) {
+        this.requireCodeVerifier = requireCodeVerifier;
+    }
 }
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 e687ccc..b65ef72 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
@@ -85,30 +85,6 @@ public class PublicClientTest extends AbstractClientServerTestBase {
     }
 
     @org.junit.Test
-    public void testAuthorizationCodeGrant() throws Exception {
-        URL busFile = PublicClientTest.class.getResource("publicclient.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
-        String code = OAuth2TestUtils.getAuthorizationCode(client);
-        assertNotNull(code);
-
-        // Now get the access token - note services2 doesn't require basic auth
-        String address2 = "https://localhost:" + port + "/services2/";
-        client = WebClient.create(address2, busFile.toString());
-
-        ClientAccessToken accessToken =
-            OAuth2TestUtils.getAccessTokenWithAuthorizationCode(client, code);
-        assertNotNull(accessToken.getTokenKey());
-    }
-
-    @org.junit.Test
     public void testAuthorizationCodeGrantNoRedirectURI() throws Exception {
         URL busFile = PublicClientTest.class.getResource("publicclient.xml");
 
@@ -121,7 +97,17 @@ public class PublicClientTest extends AbstractClientServerTestBase {
 
         // Get Authorization Code
         try {
-            OAuth2TestUtils.getAuthorizationCode(client, null, "fredPublic");
+            // Get Authorization Code
+            AuthorizationCodeParameters parameters = new AuthorizationCodeParameters();
+            parameters.setConsumerId("fredPublic");
+            String codeVerifier = Base64UrlUtility.encode(CryptoUtils.generateSecureRandomBytes(32));
+            CodeVerifierTransformer transformer = new PlainCodeVerifier();
+            parameters.setCodeChallenge(transformer.transformCodeVerifier(codeVerifier));
+            parameters.setCodeChallengeMethod(transformer.getChallengeMethod());
+            parameters.setResponseType(OAuthConstants.CODE_RESPONSE_TYPE);
+            parameters.setPath("authorize/");
+
+            OAuth2TestUtils.getLocation(client, parameters);
             fail("Failure expected on a missing (registered) redirectURI");
         } catch (Exception ex) {
             // expected
diff --git a/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/oauth2/grants/grants-server-public.xml b/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/oauth2/grants/grants-server-public.xml
index 188bca5..48a38ab 100644
--- a/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/oauth2/grants/grants-server-public.xml
+++ b/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/oauth2/grants/grants-server-public.xml
@@ -130,6 +130,7 @@ under the License.
    <bean id="plainVerifier" class="org.apache.cxf.rs.security.oauth2.grants.code.PlainCodeVerifier" />
    <bean id="codeGrantHandler" class="org.apache.cxf.rs.security.oauth2.grants.code.AuthorizationCodeGrantHandler">
       <property name="dataProvider" ref="oauthProvider"/>
+       <property name="requireCodeVerifier" value="true"/>
       <property name="codeVerifierTransformers">
           <list>
               <ref bean="digestVerifier"/>