From 1b1bff7c4998d8a28f12ec03d0259bf0eaaba85b Mon Sep 17 00:00:00 2001 From: d036670 Date: Wed, 25 Oct 2023 08:17:46 +0200 Subject: [PATCH] Validate secrets only with text This fixes client creation rest call with empty secret. Empty client secret is allowed via YAML setting already, but in a REST call there is an error: Client Secret must be at least 1 characters in length. Why this occurs: There is a policy validator for user and client policy validation. For users, a minimum of 1 char for a password might be ok, for a client not. A secret can be empty. Before 76.22.0 a missing secret in a client creation call was defaulted to an empty secret, but with https://github.com/cloudfoundry/uaa/pull/2455 this was fixed. The fix prevented the creation with an empty secret. Therefore, this here is a fix for a regression introduced with 76.22.0. It simply prevents the policy validation if the secret is without text (null or empty). --- .../ZoneAwareClientSecretPolicyValidator.java | 3 ++- ...oneAwareClientSecretPolicyValidatorTests.java | 2 +- .../ClientAdminEndpointsIntegrationTests.java | 16 ++++++++++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/zone/ZoneAwareClientSecretPolicyValidator.java b/server/src/main/java/org/cloudfoundry/identity/uaa/zone/ZoneAwareClientSecretPolicyValidator.java index 2e68e7506d1..18c53b1c0de 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/zone/ZoneAwareClientSecretPolicyValidator.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/zone/ZoneAwareClientSecretPolicyValidator.java @@ -18,6 +18,7 @@ import org.passay.PasswordValidator; import org.passay.PropertiesMessageResolver; import org.passay.RuleResult; +import org.springframework.util.StringUtils; import java.util.LinkedList; import java.util.List; @@ -71,7 +72,7 @@ public ZoneAwareClientSecretPolicyValidator(ClientSecretPolicy globalDefaultClie @Override public void validate(String clientSecret) throws InvalidClientSecretException { - if(clientSecret == null) { + if(!StringUtils.hasText(clientSecret)) { return; } diff --git a/server/src/test/java/org/cloudfoundry/identity/uaa/zone/ZoneAwareClientSecretPolicyValidatorTests.java b/server/src/test/java/org/cloudfoundry/identity/uaa/zone/ZoneAwareClientSecretPolicyValidatorTests.java index 19fc9c9db49..d5be2e8ae04 100644 --- a/server/src/test/java/org/cloudfoundry/identity/uaa/zone/ZoneAwareClientSecretPolicyValidatorTests.java +++ b/server/src/test/java/org/cloudfoundry/identity/uaa/zone/ZoneAwareClientSecretPolicyValidatorTests.java @@ -39,7 +39,7 @@ void setUp() { @Test void testEmptyClientSecret() { zone.getConfig().setClientSecretPolicy(defaultPolicy); - assertThrows(InvalidClientSecretException.class, () -> validator.validate(TEST_SECRET_1)); + validator.validate(TEST_SECRET_1); } @Test diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/ClientAdminEndpointsIntegrationTests.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/ClientAdminEndpointsIntegrationTests.java index 744025d25e4..795bc02290d 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/ClientAdminEndpointsIntegrationTests.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/ClientAdminEndpointsIntegrationTests.java @@ -25,6 +25,7 @@ import org.cloudfoundry.identity.uaa.resources.SearchResults; import org.cloudfoundry.identity.uaa.test.TestAccountSetup; import org.cloudfoundry.identity.uaa.test.UaaTestAccounts; +import org.cloudfoundry.identity.uaa.util.UaaStringUtils; import org.cloudfoundry.identity.uaa.zone.ClientSecretPolicy; import org.cloudfoundry.identity.uaa.zone.IdentityZone; import org.cloudfoundry.identity.uaa.zone.IdentityZoneConfiguration; @@ -170,6 +171,21 @@ public void createClientWithSecondarySecret() { assertEquals(HttpStatus.CREATED, result.getStatusCode()); } + @Test + public void createClientWithEmptySecret() { + OAuth2AccessToken token = getClientCredentialsAccessToken("clients.admin"); + HttpHeaders headers = getAuthenticatedHeaders(token); + var client = new ClientDetailsCreation(); + client.setClientId(new RandomValueStringGenerator().generate()); + client.setClientSecret(UaaStringUtils.EMPTY_STRING); + client.setAuthorizedGrantTypes(List.of("password")); + + ResponseEntity result = serverRunning.getRestTemplate() + .exchange(serverRunning.getUrl("/oauth/clients"), HttpMethod.POST, + new HttpEntity<>(client, headers), Void.class); + assertEquals(HttpStatus.CREATED, result.getStatusCode()); + } + @Test public void testCreateClients() throws Exception { doCreateClients();