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 a0f76d6  CXF-8311 - OAuth 2.0: Refresh token redemption unexpectedly 
fails with invalid_grant error
a0f76d6 is described below

commit a0f76d634d9b58a2644bc01532d7dd87b66081de
Author: Colm O hEigeartaigh <[email protected]>
AuthorDate: Thu Jul 9 10:07:40 2020 +0100

    CXF-8311 - OAuth 2.0: Refresh token redemption unexpectedly fails with 
invalid_grant error
---
 .../grants/refresh/RefreshTokenGrantHandler.java   |  2 +-
 .../cxf/rs/security/oauth2/utils/OAuthUtils.java   | 13 +++++-
 .../grants/AuthorizationGrantNegativeTest.java     | 46 ++++++++++++++++++++++
 .../oauth2/grants/AuthorizationGrantTest.java      | 45 +++++++++++++++++++++
 4 files changed, 104 insertions(+), 2 deletions(-)

diff --git 
a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/refresh/RefreshTokenGrantHandler.java
 
b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/refresh/RefreshTokenGrantHandler.java
index ac6714d..7da2135 100644
--- 
a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/refresh/RefreshTokenGrantHandler.java
+++ 
b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/refresh/RefreshTokenGrantHandler.java
@@ -51,7 +51,7 @@ public class RefreshTokenGrantHandler implements 
AccessTokenGrantHandler {
         List<String> requestedScopes = OAuthUtils.getRequestedScopes(client,
                                             
params.getFirst(OAuthConstants.SCOPE),
                                             useAllClientScopes,
-                                            partialMatchScopeValidation);
+                                            partialMatchScopeValidation, 
false);
         final ServerAccessToken st = dataProvider.refreshAccessToken(client, 
refreshToken, requestedScopes);
         st.setGrantType(OAuthConstants.REFRESH_TOKEN_GRANT);
         return st;
diff --git 
a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/OAuthUtils.java
 
b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/OAuthUtils.java
index a2b64c0..712b290 100644
--- 
a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/OAuthUtils.java
+++ 
b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/OAuthUtils.java
@@ -316,10 +316,21 @@ public final class OAuthUtils {
                                                   String scopeParameter,
                                                   boolean useAllClientScopes,
                                                   boolean 
partialMatchScopeValidation) {
+        return getRequestedScopes(client, scopeParameter, useAllClientScopes, 
partialMatchScopeValidation, true);
+    }
+
+    public static List<String> getRequestedScopes(Client client,
+                                                  String scopeParameter,
+                                                  boolean useAllClientScopes,
+                                                  boolean 
partialMatchScopeValidation,
+                                                  boolean 
defaultToRegisteredScopes) {
         List<String> requestScopes = parseScope(scopeParameter);
         List<String> registeredScopes = client.getRegisteredScopes();
         if (requestScopes.isEmpty()) {
-            return registeredScopes;
+            if (defaultToRegisteredScopes) {
+                return registeredScopes;
+            }
+            return requestScopes;
         }
         if (!validateScopes(requestScopes, registeredScopes, 
partialMatchScopeValidation)) {
             throw new OAuthServiceException("Unexpected scope");
diff --git 
a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/grants/AuthorizationGrantNegativeTest.java
 
b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/grants/AuthorizationGrantNegativeTest.java
index 841975f..93cc4bd 100644
--- 
a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/grants/AuthorizationGrantNegativeTest.java
+++ 
b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/grants/AuthorizationGrantNegativeTest.java
@@ -409,6 +409,52 @@ public class AuthorizationGrantNegativeTest extends 
AbstractBusClientServerTestB
         }
     }
 
+    // Try to refresh the access token specifying an additional scope
+    @org.junit.Test
+    public void testRefreshWithScopeUpgrade() throws Exception {
+        URL busFile = AuthorizationGrantTest.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
+        String code = OAuth2TestUtils.getAuthorizationCode(client, 
"read_balance");
+        assertNotNull(code);
+
+        // Now get the access token
+        client = WebClient.create(address, OAuth2TestUtils.setupProviders(),
+                "consumer-id", "this-is-a-secret", busFile.toString());
+        // Save the Cookie for the second request...
+        WebClient.getConfig(client).getRequestContext().put(
+                org.apache.cxf.message.Message.MAINTAIN_SESSION, Boolean.TRUE);
+
+        ClientAccessToken accessToken =
+                OAuth2TestUtils.getAccessTokenWithAuthorizationCode(client, 
code);
+        assertNotNull(accessToken.getTokenKey());
+        assertNotNull(accessToken.getRefreshToken());
+
+        // Refresh the access token
+        
client.type("application/x-www-form-urlencoded").accept("application/json");
+
+        Form form = new Form();
+        form.param("grant_type", "refresh_token");
+        form.param("refresh_token", accessToken.getRefreshToken());
+        form.param("client_id", "consumer-id");
+        form.param("scope", "read_balance create_balance");
+
+        try {
+            Response response = client.post(form);
+            response.readEntity(ClientAccessToken.class);
+            fail("Failure expected on trying to upgrade scopes");
+        } catch (ResponseProcessingException ex) {
+            //expected
+        }
+    }
+
     @org.junit.Test
     public void testAccessTokenBadCode() throws Exception {
         URL busFile = AuthorizationGrantTest.class.getResource("client.xml");
diff --git 
a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/grants/AuthorizationGrantTest.java
 
b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/grants/AuthorizationGrantTest.java
index 6f0a843..426574b 100644
--- 
a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/grants/AuthorizationGrantTest.java
+++ 
b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/grants/AuthorizationGrantTest.java
@@ -252,6 +252,51 @@ public class AuthorizationGrantTest extends 
AbstractBusClientServerTestBase {
         accessToken = client.post(form, ClientAccessToken.class);
         assertNotNull(accessToken.getTokenKey());
         assertNotNull(accessToken.getRefreshToken());
+        assertEquals("read_balance", accessToken.getApprovedScope());
+
+        if (isAccessTokenInJWTFormat()) {
+            validateAccessToken(accessToken.getTokenKey());
+        }
+    }
+
+    // Here we don't specify a scope in the refresh token call
+    @org.junit.Test
+    public void testAuthorizationCodeGrantRefreshWithoutScope() throws 
Exception {
+        String address = "https://localhost:"; + port + "/services/";
+        WebClient client = WebClient.create(address, 
OAuth2TestUtils.setupProviders(),
+                "alice", "security", null);
+        // 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, 
"read_balance");
+        assertNotNull(code);
+
+        // Now get the access token
+        client = WebClient.create(address, OAuth2TestUtils.setupProviders(),
+                "consumer-id", "this-is-a-secret", null);
+        // Save the Cookie for the second request...
+        WebClient.getConfig(client).getRequestContext().put(
+                org.apache.cxf.message.Message.MAINTAIN_SESSION, Boolean.TRUE);
+
+        ClientAccessToken accessToken =
+                OAuth2TestUtils.getAccessTokenWithAuthorizationCode(client, 
code);
+        assertNotNull(accessToken.getTokenKey());
+        assertNotNull(accessToken.getRefreshToken());
+
+        // Refresh the access token
+        
client.type("application/x-www-form-urlencoded").accept("application/json");
+
+        Form form = new Form();
+        form.param("grant_type", "refresh_token");
+        form.param("refresh_token", accessToken.getRefreshToken());
+        form.param("client_id", "consumer-id");
+
+        accessToken = client.post(form, ClientAccessToken.class);
+        assertNotNull(accessToken.getTokenKey());
+        assertNotNull(accessToken.getRefreshToken());
+//        assertEquals("read_balance", accessToken.getApprovedScope());
 
         if (isAccessTokenInJWTFormat()) {
             validateAccessToken(accessToken.getTokenKey());

Reply via email to