mirror of
https://github.com/keycloak/keycloak.git
synced 2026-01-10 15:32:05 -03:30
Move ServiceAccountClientTest.java to the new testsuite
Part of: #34494 Signed-off-by: Simon Vacek <simonvacky@email.cz>
This commit is contained in:
parent
e8d3d142df
commit
e1fdd1dab6
@ -70,8 +70,8 @@ public class ClientConfigBuilder {
|
||||
}
|
||||
|
||||
|
||||
public ClientConfigBuilder serviceAccount() {
|
||||
rep.setServiceAccountsEnabled(true);
|
||||
public ClientConfigBuilder serviceAccountsEnabled(boolean enabled) {
|
||||
rep.setServiceAccountsEnabled(enabled);
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -85,6 +85,11 @@ public class ClientConfigBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientConfigBuilder authenticatorType(String authenticatorType) {
|
||||
rep.setClientAuthenticatorType(authenticatorType);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientConfigBuilder attribute(String key, String value) {
|
||||
if (rep.getAttributes() == null) {
|
||||
rep.setAttributes(new HashMap<>());
|
||||
|
||||
@ -8,7 +8,7 @@ public class DefaultOAuthClientConfiguration implements ClientConfig {
|
||||
@Override
|
||||
public ClientConfigBuilder configure(ClientConfigBuilder client) {
|
||||
return client.clientId("test-app")
|
||||
.serviceAccount()
|
||||
.serviceAccountsEnabled(true)
|
||||
.directAccessGrants()
|
||||
.secret("test-secret");
|
||||
}
|
||||
|
||||
@ -23,7 +23,7 @@ public class AuthzClientConfig implements ClientConfig {
|
||||
|
||||
@Override
|
||||
public ClientConfigBuilder configure(ClientConfigBuilder client) {
|
||||
return client.serviceAccount()
|
||||
return client.serviceAccountsEnabled(true)
|
||||
.authorizationServices();
|
||||
}
|
||||
|
||||
|
||||
@ -32,11 +32,8 @@ import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
import jakarta.ws.rs.NotFoundException;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.keycloak.admin.client.Keycloak;
|
||||
import org.keycloak.admin.client.resource.ClientResource;
|
||||
import org.keycloak.events.admin.OperationType;
|
||||
import org.keycloak.events.admin.ResourceType;
|
||||
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
|
||||
@ -45,11 +42,9 @@ import org.keycloak.protocol.oidc.mappers.OIDCAttributeMapperHelper;
|
||||
import org.keycloak.protocol.saml.SamlConfigAttributes;
|
||||
import org.keycloak.protocol.saml.SamlProtocol;
|
||||
import org.keycloak.protocol.saml.installation.SamlSPDescriptorClientInstallation;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.representations.idm.ClientScopeRepresentation;
|
||||
import org.keycloak.representations.idm.ProtocolMapperRepresentation;
|
||||
import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
|
||||
import org.keycloak.testframework.annotations.InjectAdminClient;
|
||||
import org.keycloak.testframework.annotations.InjectAdminEvents;
|
||||
import org.keycloak.testframework.annotations.InjectClient;
|
||||
import org.keycloak.testframework.annotations.InjectKeycloakUrls;
|
||||
@ -61,8 +56,6 @@ import org.keycloak.testframework.realm.ClientConfig;
|
||||
import org.keycloak.testframework.realm.ClientConfigBuilder;
|
||||
import org.keycloak.testframework.realm.ManagedClient;
|
||||
import org.keycloak.testframework.realm.ManagedRealm;
|
||||
import org.keycloak.testframework.realm.RealmConfig;
|
||||
import org.keycloak.testframework.realm.RealmConfigBuilder;
|
||||
import org.keycloak.testframework.server.KeycloakServerConfig;
|
||||
import org.keycloak.testframework.server.KeycloakServerConfigBuilder;
|
||||
import org.keycloak.testframework.server.KeycloakUrls;
|
||||
@ -449,7 +442,7 @@ public class InstallationTest {
|
||||
.bearerOnly(false)
|
||||
.publicClient(false)
|
||||
.authorizationServices()
|
||||
.serviceAccount();
|
||||
.serviceAccountsEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -15,94 +15,131 @@
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.testsuite.admin.client;
|
||||
package org.keycloak.tests.admin.client;
|
||||
|
||||
import java.util.stream.Collectors;
|
||||
import org.hamcrest.MatcherAssert;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.admin.client.resource.ClientResource;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.keycloak.admin.client.resource.ClientScopeResource;
|
||||
import org.keycloak.common.constants.ServiceAccountConstants;
|
||||
import org.keycloak.representations.AccessToken;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.representations.idm.ClientScopeRepresentation;
|
||||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
import org.keycloak.testsuite.admin.ApiUtil;
|
||||
import org.keycloak.testframework.annotations.InjectClient;
|
||||
import org.keycloak.testframework.annotations.InjectRealm;
|
||||
import org.keycloak.testframework.annotations.KeycloakIntegrationTest;
|
||||
import org.keycloak.testframework.oauth.OAuthClient;
|
||||
import org.keycloak.testframework.oauth.annotations.InjectOAuthClient;
|
||||
import org.keycloak.testframework.realm.ClientConfig;
|
||||
import org.keycloak.testframework.realm.ClientConfigBuilder;
|
||||
import org.keycloak.testframework.realm.ManagedClient;
|
||||
import org.keycloak.testframework.realm.ManagedRealm;
|
||||
import org.keycloak.tests.utils.admin.ApiUtil;
|
||||
import org.keycloak.testsuite.util.oauth.AccessTokenResponse;
|
||||
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author rmartinc
|
||||
*/
|
||||
public class ServiceAccountClientTest extends AbstractClientTest {
|
||||
@KeycloakIntegrationTest
|
||||
public class ServiceAccountClientTest {
|
||||
|
||||
@InjectRealm
|
||||
ManagedRealm managedRealm;
|
||||
|
||||
@InjectClient(config = ServiceAccountClientConfig.class)
|
||||
ManagedClient managedClient;
|
||||
|
||||
@InjectOAuthClient
|
||||
OAuthClient oAuthClient;
|
||||
|
||||
private static final String clientId = "service-account-client";
|
||||
|
||||
@Test
|
||||
public void testServiceAccountEnableDisable() throws Exception {
|
||||
ClientScopeRepresentation serviceAccountScope = ApiUtil.findClientScopeByName(
|
||||
testRealmResource(), ServiceAccountConstants.SERVICE_ACCOUNT_SCOPE).toRepresentation();
|
||||
public void testServiceAccountEnableDisable() {
|
||||
ClientScopeResource serviceAccountScopeRsc = ApiUtil.findClientScopeByName(
|
||||
managedRealm.admin(), ServiceAccountConstants.SERVICE_ACCOUNT_SCOPE);
|
||||
Assertions.assertNotNull(serviceAccountScopeRsc);
|
||||
ClientScopeRepresentation serviceAccountScope = serviceAccountScopeRsc.toRepresentation();
|
||||
|
||||
// Create a client with service account enabled
|
||||
ClientRepresentation clientRep = new ClientRepresentation();
|
||||
clientRep.setClientId("service-account-client");
|
||||
clientRep.setProtocol("openid-connect");
|
||||
clientRep.setSecret("password");
|
||||
clientRep.setServiceAccountsEnabled(Boolean.TRUE);
|
||||
clientRep.setClientAuthenticatorType("client-secret");
|
||||
clientRep.setPublicClient(Boolean.FALSE);
|
||||
String clientUuid = createClient(clientRep);
|
||||
ClientResource client = testRealmResource().clients().get(clientUuid);
|
||||
getCleanup().addClientUuid(clientUuid);
|
||||
MatcherAssert.assertThat(client.getDefaultClientScopes().stream().map(ClientScopeRepresentation::getName).collect(Collectors.toList()),
|
||||
Matchers.hasItem("service_account"));
|
||||
MatcherAssert.assertThat(
|
||||
managedClient.admin().getDefaultClientScopes().stream()
|
||||
.map(ClientScopeRepresentation::getName)
|
||||
.collect(Collectors.toList()),
|
||||
Matchers.hasItem("service_account")
|
||||
);
|
||||
|
||||
// perform a login and check the claims are there
|
||||
oauth.client("service-account-client", "password");
|
||||
AccessTokenResponse response = oauth.doClientCredentialsGrantAccessTokenRequest();
|
||||
AccessToken accessToken = oauth.verifyToken(response.getAccessToken());
|
||||
Assert.assertEquals("service-account-client", accessToken.getOtherClaims().get(ServiceAccountConstants.CLIENT_ID));
|
||||
Assert.assertNotNull(accessToken.getOtherClaims().get(ServiceAccountConstants.CLIENT_HOST));
|
||||
Assert.assertNotNull(accessToken.getOtherClaims().get(ServiceAccountConstants.CLIENT_ADDRESS));
|
||||
oAuthClient.client(clientId, "password");
|
||||
AccessTokenResponse response = oAuthClient.doClientCredentialsGrantAccessTokenRequest();
|
||||
AccessToken accessToken = oAuthClient.verifyToken(response.getAccessToken());
|
||||
Assertions.assertEquals(clientId, accessToken.getOtherClaims().get(ServiceAccountConstants.CLIENT_ID));
|
||||
Assertions.assertNotNull(accessToken.getOtherClaims().get(ServiceAccountConstants.CLIENT_HOST));
|
||||
Assertions.assertNotNull(accessToken.getOtherClaims().get(ServiceAccountConstants.CLIENT_ADDRESS));
|
||||
|
||||
// update the client to remove service account
|
||||
clientRep.setServiceAccountsEnabled(Boolean.FALSE);
|
||||
client.update(clientRep);
|
||||
MatcherAssert.assertThat(client.getDefaultClientScopes().stream().map(ClientScopeRepresentation::getName).collect(Collectors.toList()),
|
||||
Matchers.not(Matchers.hasItem(ServiceAccountConstants.SERVICE_ACCOUNT_SCOPE)));
|
||||
response = oauth.doClientCredentialsGrantAccessTokenRequest();
|
||||
Assert.assertEquals("unauthorized_client", response.getError());
|
||||
managedClient.updateWithCleanup(c -> c.serviceAccountsEnabled(false));
|
||||
MatcherAssert.assertThat(
|
||||
managedClient.admin().getDefaultClientScopes().stream()
|
||||
.map(ClientScopeRepresentation::getName)
|
||||
.collect(Collectors.toList()),
|
||||
Matchers.not(Matchers.hasItem(ServiceAccountConstants.SERVICE_ACCOUNT_SCOPE))
|
||||
);
|
||||
response = oAuthClient.doClientCredentialsGrantAccessTokenRequest();
|
||||
Assertions.assertEquals("unauthorized_client", response.getError());
|
||||
|
||||
// re-enable sevice accounts
|
||||
clientRep.setServiceAccountsEnabled(Boolean.TRUE);
|
||||
client.update(clientRep);
|
||||
MatcherAssert.assertThat(client.getDefaultClientScopes().stream().map(ClientScopeRepresentation::getName).collect(Collectors.toList()),
|
||||
Matchers.hasItem(ServiceAccountConstants.SERVICE_ACCOUNT_SCOPE));
|
||||
response = oauth.doClientCredentialsGrantAccessTokenRequest();
|
||||
accessToken = oauth.verifyToken(response.getAccessToken());
|
||||
Assert.assertEquals("service-account-client", accessToken.getOtherClaims().get(ServiceAccountConstants.CLIENT_ID));
|
||||
Assert.assertNotNull(accessToken.getOtherClaims().get(ServiceAccountConstants.CLIENT_HOST));
|
||||
Assert.assertNotNull(accessToken.getOtherClaims().get(ServiceAccountConstants.CLIENT_ADDRESS));
|
||||
managedClient.updateWithCleanup(c -> c.serviceAccountsEnabled(true));
|
||||
MatcherAssert.assertThat(
|
||||
managedClient.admin().getDefaultClientScopes().stream()
|
||||
.map(ClientScopeRepresentation::getName)
|
||||
.collect(Collectors.toList()),
|
||||
Matchers.hasItem(ServiceAccountConstants.SERVICE_ACCOUNT_SCOPE)
|
||||
);
|
||||
response = oAuthClient.doClientCredentialsGrantAccessTokenRequest();
|
||||
accessToken = oAuthClient.verifyToken(response.getAccessToken());
|
||||
Assertions.assertEquals("service-account-client", accessToken.getOtherClaims().get(ServiceAccountConstants.CLIENT_ID));
|
||||
Assertions.assertNotNull(accessToken.getOtherClaims().get(ServiceAccountConstants.CLIENT_HOST));
|
||||
Assertions.assertNotNull(accessToken.getOtherClaims().get(ServiceAccountConstants.CLIENT_ADDRESS));
|
||||
|
||||
// assign the scope as optional
|
||||
client.removeDefaultClientScope(serviceAccountScope.getId());
|
||||
client.addOptionalClientScope(serviceAccountScope.getId());
|
||||
managedClient.admin().removeDefaultClientScope(serviceAccountScope.getId());
|
||||
managedClient.admin().addOptionalClientScope(serviceAccountScope.getId());
|
||||
|
||||
// re-enable service accounts, should assign the scope again as default
|
||||
clientRep.setServiceAccountsEnabled(Boolean.TRUE);
|
||||
client.update(clientRep);
|
||||
MatcherAssert.assertThat(client.getDefaultClientScopes().stream().map(ClientScopeRepresentation::getName).collect(Collectors.toList()),
|
||||
Matchers.hasItem(ServiceAccountConstants.SERVICE_ACCOUNT_SCOPE));
|
||||
response = oauth.doClientCredentialsGrantAccessTokenRequest();
|
||||
accessToken = oauth.verifyToken(response.getAccessToken());
|
||||
Assert.assertEquals("service-account-client", accessToken.getOtherClaims().get(ServiceAccountConstants.CLIENT_ID));
|
||||
Assert.assertNotNull(accessToken.getOtherClaims().get(ServiceAccountConstants.CLIENT_HOST));
|
||||
Assert.assertNotNull(accessToken.getOtherClaims().get(ServiceAccountConstants.CLIENT_ADDRESS));
|
||||
managedClient.updateWithCleanup(c -> c.serviceAccountsEnabled(true));
|
||||
MatcherAssert.assertThat(
|
||||
managedClient.admin().getDefaultClientScopes().stream()
|
||||
.map(ClientScopeRepresentation::getName)
|
||||
.collect(Collectors.toList()),
|
||||
Matchers.hasItem(ServiceAccountConstants.SERVICE_ACCOUNT_SCOPE)
|
||||
);
|
||||
response = oAuthClient.doClientCredentialsGrantAccessTokenRequest();
|
||||
accessToken = oAuthClient.verifyToken(response.getAccessToken());
|
||||
Assertions.assertEquals("service-account-client", accessToken.getOtherClaims().get(ServiceAccountConstants.CLIENT_ID));
|
||||
Assertions.assertNotNull(accessToken.getOtherClaims().get(ServiceAccountConstants.CLIENT_HOST));
|
||||
Assertions.assertNotNull(accessToken.getOtherClaims().get(ServiceAccountConstants.CLIENT_ADDRESS));
|
||||
|
||||
// remove the service account and client credentials should fail
|
||||
UserRepresentation serviceAccountUser = client.getServiceAccountUser();
|
||||
testRealmResource().users().delete(serviceAccountUser.getId());
|
||||
response = oauth.doClientCredentialsGrantAccessTokenRequest();
|
||||
Assert.assertEquals("invalid_request", response.getError());
|
||||
UserRepresentation serviceAccountUser = managedClient.admin().getServiceAccountUser();
|
||||
managedRealm.admin().users().delete(serviceAccountUser.getId()).close();
|
||||
response = oAuthClient.doClientCredentialsGrantAccessTokenRequest();
|
||||
Assertions.assertEquals("invalid_request", response.getError());
|
||||
}
|
||||
|
||||
private static class ServiceAccountClientConfig implements ClientConfig {
|
||||
|
||||
@Override
|
||||
public ClientConfigBuilder configure(ClientConfigBuilder client) {
|
||||
return client
|
||||
.clientId(clientId)
|
||||
.protocol("openid-connect")
|
||||
.secret("password")
|
||||
.serviceAccountsEnabled(true)
|
||||
.authenticatorType("client-secret")
|
||||
.publicClient(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -67,15 +67,6 @@ public class ApiUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ClientResource findClientResourceByClientId(RealmResource realm, String clientId) {
|
||||
for (ClientRepresentation c : realm.clients().findAll()) {
|
||||
if (c.getClientId().equals(clientId)) {
|
||||
return realm.clients().get(c.getId());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ClientResource findClientResourceByName(RealmResource realm, String name) {
|
||||
for (ClientRepresentation c : realm.clients().findAll()) {
|
||||
if (name.equals(c.getName())) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user