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

coheigea pushed a commit to branch coheigea/CXF-9222
in repository https://gitbox.apache.org/repos/asf/cxf.git

commit 88e351cae31e5a7ef40fd8eba1b1c3aed611f3ad
Author: Colm O hEigeartaigh <[email protected]>
AuthorDate: Fri Jun 26 10:02:11 2026 +0100

    CXF-9222 - Remove partialMatchScopeValidation for OAuth
---
 .../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 0267ed33080..ec64a26f1ed 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));
     }
 
 }

Reply via email to