Validate client scopes registration policy configuration

Closes #40187

Signed-off-by: Giuseppe Graziano <g.graziano94@gmail.com>
This commit is contained in:
Giuseppe Graziano 2025-06-04 16:42:44 +02:00 committed by Bruno Oliveira da Silva
parent 3ed9fae26d
commit aaf905aa84
2 changed files with 36 additions and 0 deletions

View File

@ -23,6 +23,7 @@ import java.util.List;
import java.util.stream.Collectors;
import org.keycloak.component.ComponentModel;
import org.keycloak.component.ComponentValidationException;
import org.keycloak.models.ClientScopeModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
@ -96,6 +97,14 @@ public class ClientScopesClientRegistrationPolicyFactory extends AbstractClientR
return getConfigProperties(null);
}
@Override
public void validateConfiguration(KeycloakSession session, RealmModel realm, ComponentModel config) throws ComponentValidationException {
List<String> allowedScopesConfig = config.getConfig().getList(ClientScopesClientRegistrationPolicyFactory.ALLOWED_CLIENT_SCOPES);
if (!getClientScopes(session).containsAll(allowedScopesConfig)) {
throw new ComponentValidationException("Client scopes not allowed: " + allowedScopesConfig);
}
}
@Override
public String getId() {
return PROVIDER_ID;

View File

@ -24,6 +24,7 @@ import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;
import jakarta.ws.rs.BadRequestException;
import org.junit.After;
import org.junit.Test;
import org.keycloak.OAuth2Constants;
@ -32,6 +33,7 @@ import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.client.registration.Auth;
import org.keycloak.client.registration.ClientRegistrationException;
import org.keycloak.client.registration.HttpErrorException;
import org.keycloak.common.util.MultivaluedHashMap;
import org.keycloak.jose.jws.JWSInput;
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
import org.keycloak.protocol.oidc.mappers.FullNameMapper;
@ -47,6 +49,7 @@ import org.keycloak.representations.idm.ClientScopeRepresentation;
import org.keycloak.representations.idm.ComponentRepresentation;
import org.keycloak.representations.idm.ComponentTypeRepresentation;
import org.keycloak.representations.idm.ConfigPropertyRepresentation;
import org.keycloak.representations.idm.ErrorRepresentation;
import org.keycloak.representations.idm.ProtocolMapperRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.oidc.OIDCClientRepresentation;
@ -715,6 +718,30 @@ public class ClientRegistrationPoliciesTest extends AbstractClientRegistrationTe
realmResource().components().component(protocolMapperPolicyRep.getId()).update(protocolMapperPolicyRep);
}
@Test
public void testRegisterFakeClientScope() {
//create
ComponentRepresentation rep = new ComponentRepresentation();
rep.setName("Clients scopes not allowed");
rep.setParentId(adminClient.realm(REALM_NAME).toRepresentation().getId());
rep.setProviderId(ClientScopesClientRegistrationPolicyFactory.PROVIDER_ID);
rep.setProviderType(ClientRegistrationPolicy.class.getName());
rep.setSubType(getPolicyAnon());
rep.setConfig(new MultivaluedHashMap<>());
rep.getConfig().putSingle(ClientScopesClientRegistrationPolicyFactory.ALLOWED_CLIENT_SCOPES, "foo1");
Response response = realmResource().components().add(rep);
ErrorRepresentation error = response.readEntity(ErrorRepresentation.class);
Assert.assertEquals("Client scopes not allowed: [foo1]", error.getErrorMessage());
//update
ComponentRepresentation clientScopesPolicyRep = findPolicyByProviderAndAuth(ClientScopesClientRegistrationPolicyFactory.PROVIDER_ID, getPolicyAnon());
clientScopesPolicyRep.getConfig().putSingle(ClientScopesClientRegistrationPolicyFactory.ALLOWED_CLIENT_SCOPES, "foo2");
BadRequestException e = Assert.assertThrows(BadRequestException.class,
() -> realmResource().components().component(clientScopesPolicyRep.getId()).update(clientScopesPolicyRep));
error = e.getResponse().readEntity(ErrorRepresentation.class);
Assert.assertEquals("Client scopes not allowed: [foo2]", error.getErrorMessage());
}
// HELPER METHODS