diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/DynamicRegistrationService.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/DynamicRegistrationService.java index ecb4847e8ad..5bf67cae103 100644 --- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/DynamicRegistrationService.java +++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/DynamicRegistrationService.java @@ -20,6 +20,7 @@ import java.net.URI; import java.security.cert.X509Certificate; +import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; @@ -270,6 +271,9 @@ protected Client createNewClient(ClientRegistration request) { String appType = request.getApplicationType(); if (appType == null) { appType = DEFAULT_APPLICATION_TYPE; + } else if (!WEB_APPLICATION_TYPE.equalsIgnoreCase(appType) + && !NATIVE_APPLICATION_TYPE.equalsIgnoreCase(appType)) { + reportInvalidRequestError(new OAuthError(INVALID_CLIENT_METADATA, "Unsupported application type")); } boolean isConfidential = DEFAULT_APPLICATION_TYPE.equals(appType) && (passwordRequired @@ -394,6 +398,10 @@ protected void fromClientRegistrationToClient(ClientRegistration request, Client List requestedScopes = OAuthUtils.parseScope(scope); validateClientScopes(requestedScopes); client.setRegisteredScopes(requestedScopes); + } else if (allowedClientScopes != null && client.getRegisteredScopes().isEmpty()) { + // An empty list of registered scopes allows any scope to be requested later on, + // so restrict the client to the configured scopes instead + client.setRegisteredScopes(new ArrayList<>(allowedClientScopes)); } // Client Application URI String clientUri = request.getClientUri(); @@ -466,6 +474,9 @@ protected void validateRequestUri(String uri, String appType, List grant reportInvalidRequestError(new OAuthError(INVALID_CLIENT_METADATA, "Unsupported redirect URI hostname for scheme")); } + } else { + reportInvalidRequestError(new OAuthError(INVALID_CLIENT_METADATA, + "Unsupported application type")); } } @@ -533,7 +544,7 @@ protected void validateClientScopes(List requestedScopes) { List allowedScopes = allowedClientScopes; if (allowedScopes == null && clientProvider instanceof AbstractOAuthDataProvider) { - allowedScopes = new java.util.ArrayList<>( + allowedScopes = new ArrayList<>( ((AbstractOAuthDataProvider)clientProvider).getPermissionMap().keySet()); } diff --git a/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/services/DynamicRegistrationServiceTest.java b/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/services/DynamicRegistrationServiceTest.java index 3bfaceafffa..1b5593ad74f 100644 --- a/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/services/DynamicRegistrationServiceTest.java +++ b/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/services/DynamicRegistrationServiceTest.java @@ -90,6 +90,39 @@ public void testAcceptsRegisteredScopesWhenAllowlistNotConfigured() { assertEquals(Collections.singletonList("openid"), client.getRegisteredScopes()); } + @Test + public void testDefaultsToAllowedScopesWhenNoScopeRegistered() { + TestDynamicRegistrationService service = new TestDynamicRegistrationService(); + service.setAllowedClientScopes(Collections.singletonList("read")); + + Client client = createClient(); + service.applyClientRegistration(new ClientRegistration(), client); + + assertEquals(Collections.singletonList("read"), client.getRegisteredScopes()); + } + + @Test + public void testRejectsUnknownApplicationTypeRedirectUrl() { + TestDynamicRegistrationService service = new TestDynamicRegistrationService(); + + ClientRegistration request = new ClientRegistration(); + request.setApplicationType("x"); + request.setRedirectUris(List.of("http://evil.example/cb")); + + Client client = createClient(); + client.setAllowedGrantTypes(Collections.singletonList(OAuthConstants.IMPLICIT_GRANT)); + assertThrows(BadRequestException.class, () -> service.applyClientRegistration(request, client)); + } + + @Test + public void testRejectsUnknownApplicationType() { + TestDynamicRegistrationService service = new TestDynamicRegistrationService(); + + ClientRegistration request = new ClientRegistration(); + request.setApplicationType("x"); + assertThrows(BadRequestException.class, () -> service.createClient(request)); + } + @Test public void testAcceptsAllowedRedirectUrlsWebApp() { TestDynamicRegistrationService service = new TestDynamicRegistrationService();