KEYCLOAK-14919 Dynamic registration - Scope ignored
This commit is contained in:
parent
107a429238
commit
b93a6ed19f
3 changed files with 138 additions and 0 deletions
|
@ -46,9 +46,11 @@ import org.keycloak.util.JWKSUtils;
|
|||
import java.net.URI;
|
||||
import java.security.PublicKey;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
|
@ -63,6 +65,9 @@ public class DescriptionConverter {
|
|||
client.setRedirectUris(clientOIDC.getRedirectUris());
|
||||
client.setBaseUrl(clientOIDC.getClientUri());
|
||||
|
||||
String scopeParam = clientOIDC.getScope();
|
||||
if (scopeParam != null) client.setOptionalClientScopes(new ArrayList<>(Arrays.asList(scopeParam.split(" "))));
|
||||
|
||||
List<String> oidcResponseTypes = clientOIDC.getResponseTypes();
|
||||
if (oidcResponseTypes == null || oidcResponseTypes.isEmpty()) {
|
||||
oidcResponseTypes = Collections.singletonList(OIDCResponseType.CODE);
|
||||
|
@ -216,6 +221,9 @@ public class DescriptionConverter {
|
|||
response.setResponseTypes(getOIDCResponseTypes(client));
|
||||
response.setGrantTypes(getOIDCGrantTypes(client));
|
||||
|
||||
List<String> scopes = client.getOptionalClientScopes();
|
||||
if (scopes != null) response.setScope(scopes.stream().collect(Collectors.joining(" ")));
|
||||
|
||||
OIDCAdvancedConfigWrapper config = OIDCAdvancedConfigWrapper.fromClientRepresentation(client);
|
||||
if (config.isUserInfoSignatureRequired()) {
|
||||
response.setUserinfoSignedResponseAlg(config.getUserInfoSignedResponseAlg().toString());
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
package org.keycloak.testsuite.client;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.client.registration.Auth;
|
||||
import org.keycloak.client.registration.ClientRegistration;
|
||||
|
@ -24,6 +25,7 @@ import org.keycloak.client.registration.ClientRegistrationException;
|
|||
import org.keycloak.client.registration.HttpErrorException;
|
||||
import org.keycloak.models.Constants;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.representations.idm.ClientScopeRepresentation;
|
||||
import org.keycloak.representations.idm.OAuth2ErrorRepresentation;
|
||||
import org.keycloak.representations.idm.ProtocolMapperRepresentation;
|
||||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
|
@ -34,7 +36,12 @@ import org.keycloak.util.JsonSerialization;
|
|||
import javax.ws.rs.NotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
import static org.hamcrest.core.Is.is;
|
||||
|
@ -42,6 +49,7 @@ import static org.junit.Assert.assertEquals;
|
|||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude.AuthServer;
|
||||
|
||||
|
@ -445,4 +453,64 @@ public class ClientRegistrationTest extends AbstractClientRegistrationTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void registerClientAsAdminWithScope() throws ClientRegistrationException {
|
||||
authManageClients();
|
||||
ClientRepresentation client = new ClientRepresentation();
|
||||
client.setClientId(CLIENT_ID);
|
||||
client.setSecret(CLIENT_SECRET);
|
||||
ArrayList<String> optionalClientScopes = new ArrayList<>(Arrays.asList("address","phone"));
|
||||
client.setOptionalClientScopes(optionalClientScopes);
|
||||
|
||||
ClientRepresentation createdClient = reg.create(client);
|
||||
assertEquals(CLIENT_ID, createdClient.getClientId());
|
||||
client = adminClient.realm(REALM_NAME).clients().get(createdClient.getId()).toRepresentation();
|
||||
assertEquals(CLIENT_ID, client.getClientId());
|
||||
// Remove this client after test
|
||||
getCleanup().addClientUuid(createdClient.getId());
|
||||
|
||||
Set<String> requestedClientScopes = new HashSet<>(optionalClientScopes);
|
||||
Set<String> registeredClientScopes = new HashSet<>(client.getOptionalClientScopes());
|
||||
assertTrue(requestedClientScopes.equals(registeredClientScopes));
|
||||
assertTrue(client.getDefaultClientScopes().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void registerClientAsAdminWithoutScope() throws ClientRegistrationException {
|
||||
Set<String> realmDefaultClientScopes = new HashSet<>(adminClient.realm(REALM_NAME).getDefaultDefaultClientScopes()
|
||||
.stream().map(i->i.getName()).collect(Collectors.toList()));
|
||||
Set<String> realmOptionalClientScopes = new HashSet<>(adminClient.realm(REALM_NAME).getDefaultOptionalClientScopes()
|
||||
.stream().map(i->i.getName()).collect(Collectors.toList()));
|
||||
|
||||
authManageClients();
|
||||
ClientRepresentation client = new ClientRepresentation();
|
||||
client.setClientId(CLIENT_ID);
|
||||
client.setSecret(CLIENT_SECRET);
|
||||
|
||||
ClientRepresentation createdClient = reg.create(client);
|
||||
assertEquals(CLIENT_ID, createdClient.getClientId());
|
||||
client = adminClient.realm(REALM_NAME).clients().get(createdClient.getId()).toRepresentation();
|
||||
assertEquals(CLIENT_ID, client.getClientId());
|
||||
// Remove this client after test
|
||||
getCleanup().addClientUuid(createdClient.getId());
|
||||
|
||||
assertTrue(realmDefaultClientScopes.equals(new HashSet<>(client.getDefaultClientScopes())));
|
||||
assertTrue(realmOptionalClientScopes.equals(new HashSet<>(client.getOptionalClientScopes())));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void registerClientAsAdminWithNotDefinedScope() throws ClientRegistrationException {
|
||||
authManageClients();
|
||||
ClientRepresentation client = new ClientRepresentation();
|
||||
client.setClientId(CLIENT_ID);
|
||||
client.setSecret(CLIENT_SECRET);
|
||||
client.setOptionalClientScopes(new ArrayList<>(Arrays.asList("notdefinedscope","phone")));
|
||||
try {
|
||||
registerClient(client);
|
||||
fail("Expected 403");
|
||||
} catch (ClientRegistrationException e) {
|
||||
assertEquals(403, ((HttpErrorException) e.getCause()).getStatusLine().getStatusCode());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ package org.keycloak.testsuite.client;
|
|||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.OAuth2Constants;
|
||||
import org.keycloak.admin.client.resource.ClientResource;
|
||||
import org.keycloak.admin.client.resource.ClientsResource;
|
||||
import org.keycloak.authentication.authenticators.client.X509ClientAuthenticator;
|
||||
import org.keycloak.client.registration.Auth;
|
||||
|
@ -44,9 +45,11 @@ import org.keycloak.testsuite.admin.ApiUtil;
|
|||
import org.keycloak.testsuite.util.KeycloakModelUtils;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.keycloak.testsuite.auth.page.AuthRealm.TEST;
|
||||
|
@ -468,5 +471,64 @@ public class OIDCClientRegistrationTest extends AbstractClientRegistrationTest {
|
|||
return ApiUtil.findClientByClientId(adminClient.realms().realm(REALM_NAME), clientId).toRepresentation();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClientWithScope() throws Exception {
|
||||
OIDCClientRepresentation clientRep = null;
|
||||
OIDCClientRepresentation response = null;
|
||||
String clientScope = "phone address";
|
||||
|
||||
clientRep = createRep();
|
||||
clientRep.setScope(clientScope);
|
||||
response = reg.oidc().create(clientRep);
|
||||
|
||||
Set<String> clientScopes = new HashSet<>(Arrays.asList(clientScope.split(" ")));
|
||||
Set<String> registeredClientScopes = new HashSet<>(Arrays.asList(response.getScope().split(" ")));
|
||||
assertTrue(clientScopes.equals(registeredClientScopes));
|
||||
|
||||
ClientResource clientResource = adminClient.realm(REALM_NAME).clients().get(response.getClientId());
|
||||
assertTrue(clientResource.toRepresentation().getDefaultClientScopes().isEmpty());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClientWithNotDefinedScope() throws Exception {
|
||||
OIDCClientRepresentation clientRep = null;
|
||||
OIDCClientRepresentation response = null;
|
||||
|
||||
String clientScope = "notdefinedscope address";
|
||||
|
||||
clientRep = createRep();
|
||||
clientRep.setScope(clientScope);
|
||||
try {
|
||||
response = reg.oidc().create(clientRep);
|
||||
fail("Expected 403");
|
||||
} catch (ClientRegistrationException e) {
|
||||
assertEquals(403, ((HttpErrorException) e.getCause()).getStatusLine().getStatusCode());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClientWithoutScope() throws ClientRegistrationException {
|
||||
Set<String> realmOptionalClientScopes = new HashSet<>(adminClient.realm(REALM_NAME).getDefaultOptionalClientScopes()
|
||||
.stream().map(i->i.getName()).collect(Collectors.toList()));
|
||||
|
||||
OIDCClientRepresentation clientRep = null;
|
||||
OIDCClientRepresentation response = null;
|
||||
|
||||
clientRep = createRep();
|
||||
response = reg.oidc().create(clientRep);
|
||||
|
||||
Set<String> registeredClientScopes = new HashSet<>(Arrays.asList(response.getScope().split(" ")));
|
||||
assertTrue(realmOptionalClientScopes.equals(new HashSet<>(registeredClientScopes)));
|
||||
|
||||
ClientResource clientResource = adminClient.realm(REALM_NAME).clients().get(response.getClientId());
|
||||
ClientRepresentation rep = clientResource.toRepresentation();
|
||||
|
||||
Set<String> realmDefaultClientScopes = new HashSet<>(adminClient.realm(REALM_NAME).getDefaultDefaultClientScopes()
|
||||
.stream().map(i->i.getName()).collect(Collectors.toList()));
|
||||
|
||||
Set<String> registeredDefaultClientScopes = new HashSet<>(rep.getDefaultClientScopes());
|
||||
assertTrue(realmDefaultClientScopes.equals(new HashSet<>(registeredDefaultClientScopes)));
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue