This is an automated email from the ASF dual-hosted git repository. reta pushed a commit to branch 4.1.x-fixes in repository https://gitbox.apache.org/repos/asf/cxf.git
commit 631c3b175b1d7984e9ee324e506066f1bbc457d8 Author: Colm O hEigeartaigh <[email protected]> AuthorDate: Fri Jun 26 16:16:59 2026 +0100 CXF-9222 - Remove partialMatchScopeValidation for OAuth (#3254) (cherry picked from commit d60925c1d2b270c10b6bc4638132976dd50f1589) --- .../oauth2/grants/AbstractGrantHandler.java | 3 +- .../grants/refresh/RefreshTokenGrantHandler.java | 7 +--- .../services/RedirectionBasedGrantService.java | 11 +----- .../cxf/rs/security/oauth2/utils/OAuthUtils.java | 30 +++------------ .../rs/security/oauth2/utils/OAuthUtilsTest.java | 43 +++++++++------------- 5 files changed, 28 insertions(+), 66 deletions(-) diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/AbstractGrantHandler.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/AbstractGrantHandler.java index 25071b31f0a..6ff15913bf8 100644 --- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/AbstractGrantHandler.java +++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/AbstractGrantHandler.java @@ -144,8 +144,7 @@ public abstract class AbstractGrantHandler implements AccessTokenGrantHandler { String requestedGrant, List<String> requestedScopes, List<String> audiences) { - if (!OAuthUtils.validateScopes(requestedScopes, client.getRegisteredScopes(), - partialMatchScopeValidation)) { + if (!OAuthUtils.validateScopes(requestedScopes, client.getRegisteredScopes())) { throw new OAuthServiceException(new OAuthError(OAuthConstants.INVALID_SCOPE)); } if (!OAuthUtils.validateAudiences(audiences, client.getRegisteredAudiences())) { 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 67e77e3d6ca..153f9882d59 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 @@ -33,7 +33,6 @@ import org.apache.cxf.rs.security.oauth2.utils.OAuthUtils; public class RefreshTokenGrantHandler implements AccessTokenGrantHandler { private OAuthDataProvider dataProvider; - private boolean partialMatchScopeValidation; private boolean useAllClientScopes; public void setDataProvider(OAuthDataProvider dataProvider) { @@ -50,16 +49,12 @@ public class RefreshTokenGrantHandler implements AccessTokenGrantHandler { List<String> requestedScopes = OAuthUtils.getRequestedScopes(client, params.getFirst(OAuthConstants.SCOPE), useAllClientScopes, - partialMatchScopeValidation, false); + false); final ServerAccessToken st = dataProvider.refreshAccessToken(client, refreshToken, requestedScopes); st.setGrantType(OAuthConstants.REFRESH_TOKEN_GRANT); return st; } - public void setPartialMatchScopeValidation(boolean partialMatchScopeValidation) { - this.partialMatchScopeValidation = partialMatchScopeValidation; - } - public void setUseAllClientScopes(boolean useAllClientScopes) { this.useAllClientScopes = useAllClientScopes; } diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/RedirectionBasedGrantService.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/RedirectionBasedGrantService.java index b856d7c92e0..0e82a1e244a 100644 --- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/RedirectionBasedGrantService.java +++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/RedirectionBasedGrantService.java @@ -61,7 +61,6 @@ public abstract class RedirectionBasedGrantService extends AbstractOAuthService private Set<String> supportedResponseTypes; private String supportedGrantType; private boolean useAllClientScopes; - private boolean partialMatchScopeValidation; private boolean useRegisteredRedirectUriIfPossible = true; private SessionAuthenticityTokenProvider sessionAuthenticityTokenProvider; private SubjectCreator subjectCreator; @@ -180,8 +179,7 @@ public abstract class RedirectionBasedGrantService extends AbstractOAuthService try { requestedScope = OAuthUtils.getRequestedScopes(client, providedScope, - useAllClientScopes, - partialMatchScopeValidation); + useAllClientScopes); requestedPermissions = getDataProvider().convertScopeToPermissions(client, requestedScope); } catch (OAuthServiceException ex) { LOG.log(Level.FINE, "Error processing scopes", ex); @@ -401,8 +399,7 @@ public abstract class RedirectionBasedGrantService extends AbstractOAuthService approvedScope.add(rScope); } } - if (!OAuthUtils.validateScopes(requestedScope, client.getRegisteredScopes(), - partialMatchScopeValidation)) { + if (!OAuthUtils.validateScopes(requestedScope, client.getRegisteredScopes())) { return createErrorResponse(params, redirectUri, OAuthConstants.INVALID_SCOPE); } getMessageContext().put(AUTHORIZATION_REQUEST_PARAMETERS, params); @@ -571,10 +568,6 @@ public abstract class RedirectionBasedGrantService extends AbstractOAuthService this.resourceOwnerNameProvider = resourceOwnerNameProvider; } - public void setPartialMatchScopeValidation(boolean partialMatchScopeValidation) { - this.partialMatchScopeValidation = partialMatchScopeValidation; - } - public void setUseAllClientScopes(boolean useAllClientScopes) { this.useAllClientScopes = useAllClientScopes; } 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 cee0893b95d..2c0b54ce2d9 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 @@ -321,15 +321,13 @@ public final class OAuthUtils { public static List<String> getRequestedScopes(Client client, String scopeParameter, - boolean useAllClientScopes, - boolean partialMatchScopeValidation) { - return getRequestedScopes(client, scopeParameter, useAllClientScopes, partialMatchScopeValidation, true); + boolean useAllClientScopes) { + return getRequestedScopes(client, scopeParameter, useAllClientScopes, 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(); @@ -339,7 +337,7 @@ public final class OAuthUtils { } return requestScopes; } - if (!validateScopes(requestScopes, registeredScopes, partialMatchScopeValidation)) { + if (!validateScopes(requestScopes, registeredScopes)) { throw new OAuthServiceException("Unexpected scope"); } if (useAllClientScopes) { @@ -353,26 +351,10 @@ public final class OAuthUtils { return requestScopes; } - public static boolean validateScopes(List<String> requestScopes, List<String> registeredScopes, - boolean partialMatchScopeValidation) { + public static boolean validateScopes(List<String> requestScopes, List<String> registeredScopes) { if (!registeredScopes.isEmpty()) { - // if it is a strict validation then pre-registered scopes have to contains all - // the current request scopes - if (!partialMatchScopeValidation) { - return registeredScopes.containsAll(requestScopes); - } - for (String requestScope : requestScopes) { - boolean match = false; - for (String registeredScope : registeredScopes) { - if (requestScope.startsWith(registeredScope)) { - match = true; - break; - } - } - if (!match) { - return false; - } - } + // pre-registered scopes have to contains all the current request scopes + return registeredScopes.containsAll(requestScopes); } return true; } diff --git a/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/utils/OAuthUtilsTest.java b/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/utils/OAuthUtilsTest.java index 72520960ce8..d0072a34e31 100644 --- a/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/utils/OAuthUtilsTest.java +++ b/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/utils/OAuthUtilsTest.java @@ -18,11 +18,8 @@ */ package org.apache.cxf.rs.security.oauth2.utils; -import java.util.Collections; import java.util.List; -import org.apache.cxf.rs.security.oauth2.common.Client; - import org.junit.Test; import static org.junit.Assert.assertEquals; @@ -35,42 +32,38 @@ public class OAuthUtilsTest { public void testValidateScopesStrict() { List<String> requestScopes = OAuthUtils.parseScope("a c b"); List<String> registeredScopes = OAuthUtils.parseScope("a b c d"); - assertTrue(OAuthUtils.validateScopes(requestScopes, registeredScopes, false)); + assertTrue(OAuthUtils.validateScopes(requestScopes, registeredScopes)); } @Test public void testValidateScopesStrictFail() { List<String> requestScopes = OAuthUtils.parseScope("a b c d"); List<String> registeredScopes = OAuthUtils.parseScope("a b d"); - assertFalse(OAuthUtils.validateScopes(requestScopes, registeredScopes, false)); - } - - @Test - public void testValidateScopesPartial() { - List<String> requestScopes = OAuthUtils.parseScope("a b c-1"); - List<String> registeredScopes = OAuthUtils.parseScope("a b c"); - assertTrue(OAuthUtils.validateScopes(requestScopes, registeredScopes, true)); + assertFalse(OAuthUtils.validateScopes(requestScopes, registeredScopes)); } @Test - public void testValidateScopesPartialFail() { - List<String> requestScopes = OAuthUtils.parseScope("a b c"); - List<String> registeredScopes = OAuthUtils.parseScope("a b"); - assertFalse(OAuthUtils.validateScopes(requestScopes, registeredScopes, true)); + public void testParseScopeEmpty() { + assertTrue(OAuthUtils.parseScope(null).isEmpty()); + assertTrue(OAuthUtils.parseScope("").isEmpty()); + assertTrue(OAuthUtils.parseScope(" ").isEmpty()); } @Test - public void testGetRequestedScopesRegistered() { - Client c = new Client(); - List<String> scopes = Collections.singletonList("a"); - c.setRegisteredScopes(scopes); - assertEquals(scopes, OAuthUtils.getRequestedScopes(c, "", false, false)); + public void testParseScopeWithExtraSpaces() { + List<String> scopes = OAuthUtils.parseScope(" read write admin "); + assertEquals(3, scopes.size()); + assertEquals("read", scopes.get(0)); + assertEquals("write", scopes.get(1)); + assertEquals("admin", scopes.get(2)); } @Test - public void testParseScopeEmpty() { - assertTrue(OAuthUtils.parseScope(null).isEmpty()); - assertTrue(OAuthUtils.parseScope("").isEmpty()); - assertTrue(OAuthUtils.parseScope(" ").isEmpty()); + public void testParseScopeWithDuplicates() { + List<String> scopes = OAuthUtils.parseScope("a a b"); + assertEquals(3, scopes.size()); + assertEquals("a", scopes.get(0)); + assertEquals("a", scopes.get(1)); + assertEquals("b", scopes.get(2)); } }
