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 2020/07/09 09:25:34 UTC
[cxf] 01/02: CXF-8311 - OAuth 2.0: Refresh token redemption
unexpectedly fails with invalid_grant error
This is an automated email from the ASF dual-hosted git repository.
coheigea pushed a commit to branch 3.3.x-fixes
in repository https://gitbox.apache.org/repos/asf/cxf.git
commit 8fade1b4eca6f2b38d520ce68c16651ae9ff9575
Author: Colm O hEigeartaigh <co...@apache.org>
AuthorDate: Thu Jul 9 10:07:40 2020 +0100
CXF-8311 - OAuth 2.0: Refresh token redemption unexpectedly fails with invalid_grant error
(cherry picked from commit a0f76d634d9b58a2644bc01532d7dd87b66081de)
# Conflicts:
# rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/OAuthUtils.java
---
.../grants/refresh/RefreshTokenGrantHandler.java | 2 +-
.../cxf/rs/security/oauth2/utils/OAuthUtils.java | 12 +++++-
.../grants/AuthorizationGrantNegativeTest.java | 46 ++++++++++++++++++++++
.../oauth2/grants/AuthorizationGrantTest.java | 45 +++++++++++++++++++++
4 files changed, 103 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 f311661..2683122 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
@@ -329,10 +329,20 @@ 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()) {
- requestScopes.addAll(registeredScopes);
+ if (defaultToRegisteredScopes) {
+ return registeredScopes;
+ }
return requestScopes;
}
if (!validateScopes(requestScopes, registeredScopes, partialMatchScopeValidation)) {
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 10eee52..5baa313 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
@@ -416,6 +416,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 161da2f..f6b11e3 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
@@ -272,6 +272,51 @@ public class AuthorizationGrantTest extends AbstractBusClientServerTestBase {
accessToken = response.readEntity(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());