RHSSO-108: Client signed token authentication
This commit is contained in:
parent
9edc2000e7
commit
2f3b5e9b88
5 changed files with 122 additions and 57 deletions
|
@ -19,65 +19,86 @@ package org.keycloak.testsuite.oauth;
|
|||
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.junit.Assert;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.authentication.authenticators.client.ClientIdAndSecretAuthenticator;
|
||||
import org.keycloak.common.constants.ServiceAccountConstants;
|
||||
import org.keycloak.events.Details;
|
||||
import org.keycloak.events.Errors;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.representations.AccessToken;
|
||||
import org.keycloak.representations.RefreshToken;
|
||||
import org.keycloak.services.managers.ClientManager;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.testsuite.AbstractKeycloakTest;
|
||||
import org.keycloak.testsuite.AssertEvents;
|
||||
import org.keycloak.testsuite.OAuthClient;
|
||||
import org.keycloak.testsuite.rule.KeycloakRule;
|
||||
import org.keycloak.testsuite.rule.WebResource;
|
||||
import org.keycloak.testsuite.rule.WebRule;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
import org.keycloak.testsuite.util.ClientBuilder;
|
||||
import org.keycloak.testsuite.util.ClientManager;
|
||||
import org.keycloak.testsuite.util.OAuthClient;
|
||||
import org.keycloak.testsuite.util.RealmBuilder;
|
||||
import org.keycloak.testsuite.util.UserBuilder;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class ServiceAccountTest {
|
||||
|
||||
@ClassRule
|
||||
public static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakRule.KeycloakSetup() {
|
||||
@Override
|
||||
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
||||
ClientModel app = KeycloakModelUtils.createClient(appRealm, "service-account-cl");
|
||||
app.setSecret("secret1");
|
||||
new ClientManager(manager).enableServiceAccount(app);
|
||||
|
||||
ClientModel disabledApp = KeycloakModelUtils.createClient(appRealm, "service-account-disabled");
|
||||
disabledApp.setSecret("secret1");
|
||||
|
||||
UserModel serviceAccountUser = session.users().getUserByUsername(ServiceAccountConstants.SERVICE_ACCOUNT_USER_PREFIX + "service-account-cl", appRealm);
|
||||
userId = serviceAccountUser.getId();
|
||||
}
|
||||
});
|
||||
|
||||
@Rule
|
||||
public AssertEvents events = new AssertEvents(keycloakRule);
|
||||
|
||||
@Rule
|
||||
public WebRule webRule = new WebRule(this);
|
||||
|
||||
@WebResource
|
||||
protected WebDriver driver;
|
||||
|
||||
@WebResource
|
||||
protected OAuthClient oauth;
|
||||
public class ServiceAccountTest extends AbstractKeycloakTest {
|
||||
|
||||
private static String userId;
|
||||
|
||||
@Rule
|
||||
public AssertEvents events = new AssertEvents(this);
|
||||
|
||||
|
||||
@Override
|
||||
public void beforeAbstractKeycloakTest() throws Exception {
|
||||
super.beforeAbstractKeycloakTest();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTestRealms(List<RealmRepresentation> testRealms) {
|
||||
|
||||
RealmBuilder realm = RealmBuilder.create().name("test")
|
||||
.privateKey("MIICXAIBAAKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQABAoGAfmO8gVhyBxdqlxmIuglbz8bcjQbhXJLR2EoS8ngTXmN1bo2L90M0mUKSdc7qF10LgETBzqL8jYlQIbt+e6TH8fcEpKCjUlyq0Mf/vVbfZSNaVycY13nTzo27iPyWQHK5NLuJzn1xvxxrUeXI6A2WFpGEBLbHjwpx5WQG9A+2scECQQDvdn9NE75HPTVPxBqsEd2z10TKkl9CZxu10Qby3iQQmWLEJ9LNmy3acvKrE3gMiYNWb6xHPKiIqOR1as7L24aTAkEAtyvQOlCvr5kAjVqrEKXalj0Tzewjweuxc0pskvArTI2Oo070h65GpoIKLc9jf+UA69cRtquwP93aZKtW06U8dQJAF2Y44ks/mK5+eyDqik3koCI08qaC8HYq2wVl7G2QkJ6sbAaILtcvD92ToOvyGyeE0flvmDZxMYlvaZnaQ0lcSQJBAKZU6umJi3/xeEbkJqMfeLclD27XGEFoPeNrmdx0q10Azp4NfJAY+Z8KRyQCR2BEG+oNitBOZ+YXF9KCpH3cdmECQHEigJhYg+ykOvr1aiZUMFT72HU0jnmQe2FVekuG+LJUt2Tm7GtMjTFoGpf0JwrVuZN39fOYAlo+nTixgeW7X8Y=")
|
||||
.publicKey("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB")
|
||||
.testEventListener();
|
||||
|
||||
ClientRepresentation enabledApp = ClientBuilder.create()
|
||||
.id(KeycloakModelUtils.generateId())
|
||||
.clientId("service-account-cl")
|
||||
.secret("secret1")
|
||||
.serviceAccountsEnabled(true)
|
||||
.build();
|
||||
|
||||
realm.client(enabledApp);
|
||||
|
||||
ClientRepresentation disabledApp = ClientBuilder.create()
|
||||
.id(KeycloakModelUtils.generateId())
|
||||
.clientId("service-account-disabled")
|
||||
.secret("secret1")
|
||||
.build();
|
||||
|
||||
realm.client(disabledApp);
|
||||
|
||||
UserBuilder defaultUser = UserBuilder.create()
|
||||
.id(KeycloakModelUtils.generateId())
|
||||
.username("test-user@localhost");
|
||||
realm.user(defaultUser);
|
||||
|
||||
userId = KeycloakModelUtils.generateId();
|
||||
|
||||
UserBuilder serviceAccountUser = UserBuilder.create()
|
||||
.id(userId)
|
||||
.username(ServiceAccountConstants.SERVICE_ACCOUNT_USER_PREFIX + enabledApp.getClientId())
|
||||
.serviceAccountId(enabledApp.getClientId());
|
||||
realm.user(serviceAccountUser);
|
||||
|
||||
testRealms.add(realm.build());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clientCredentialsAuthSuccess() throws Exception {
|
||||
oauth.clientId("service-account-cl");
|
||||
|
@ -193,19 +214,13 @@ public class ServiceAccountTest {
|
|||
.removeDetail(Details.RESPONSE_TYPE)
|
||||
.error(Errors.INVALID_CLIENT)
|
||||
.assertEvent();
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changeClientIdTest() throws Exception {
|
||||
keycloakRule.update(new KeycloakRule.KeycloakSetup() {
|
||||
|
||||
@Override
|
||||
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
||||
ClientModel app = appRealm.getClientByClientId("service-account-cl");
|
||||
app.setClientId("updated-client");
|
||||
}
|
||||
|
||||
});
|
||||
ClientManager.realm(adminClient.realm("test")).rename("service-account-cl", "updated-client");
|
||||
|
||||
oauth.clientId("updated-client");
|
||||
|
||||
|
@ -227,16 +242,8 @@ public class ServiceAccountTest {
|
|||
.detail(Details.USERNAME, ServiceAccountConstants.SERVICE_ACCOUNT_USER_PREFIX + "service-account-cl")
|
||||
.assertEvent();
|
||||
|
||||
// Revert change
|
||||
keycloakRule.update(new KeycloakRule.KeycloakSetup() {
|
||||
|
||||
@Override
|
||||
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
||||
ClientModel app = appRealm.getClientByClientId("updated-client");
|
||||
app.setClientId("service-account-cl");
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
ClientManager.realm(adminClient.realm("test")).rename("updated-client", "service-account-cl");
|
||||
|
||||
}
|
||||
}
|
|
@ -20,6 +20,7 @@ package org.keycloak.testsuite.util;
|
|||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
|
||||
import javax.ws.rs.client.Client;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
@ -59,6 +60,16 @@ public class ClientBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
public ClientBuilder secret(String secret) {
|
||||
rep.setSecret(secret);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientBuilder serviceAccountsEnabled(Boolean serviceAccountsEnabled) {
|
||||
rep.setServiceAccountsEnabled(serviceAccountsEnabled);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientRepresentation build() {
|
||||
return rep;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
package org.keycloak.testsuite.util;
|
||||
|
||||
import org.keycloak.admin.client.resource.ClientResource;
|
||||
import org.keycloak.admin.client.resource.RealmResource;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bruno@abstractj.org">Bruno Oliveira</a>.
|
||||
*/
|
||||
public class ClientManager {
|
||||
|
||||
private static RealmResource realm;
|
||||
|
||||
private ClientManager(){}
|
||||
|
||||
public static ClientManager realm(RealmResource realm) {
|
||||
ClientManager.realm = realm;
|
||||
return new ClientManager();
|
||||
}
|
||||
|
||||
public void rename(String oldName, String newName) {
|
||||
List<ClientRepresentation> client = realm.clients().findByClientId(oldName);
|
||||
if (!client.isEmpty()) {
|
||||
ClientResource clientResource = realm.clients().get(client.get(0).getId());
|
||||
ClientRepresentation app = clientResource.toRepresentation();
|
||||
app.setClientId(newName);
|
||||
clientResource.update(app);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -43,6 +43,16 @@ public class RealmBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
public RealmBuilder publicKey(String publicKey) {
|
||||
rep.setPublicKey(publicKey);
|
||||
return this;
|
||||
}
|
||||
|
||||
public RealmBuilder privateKey(String privateKey) {
|
||||
rep.setPrivateKey(privateKey);
|
||||
return this;
|
||||
}
|
||||
|
||||
public RealmBuilder testEventListener() {
|
||||
if (rep.getEventsListeners() == null) {
|
||||
rep.setEventsListeners(new LinkedList<String>());
|
||||
|
|
|
@ -80,6 +80,11 @@ public class UserBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
public UserBuilder serviceAccountId(String serviceAccountId) {
|
||||
rep.setServiceAccountClientId(serviceAccountId);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserRepresentation build() {
|
||||
return rep;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue