diff --git a/services/src/main/java/org/keycloak/protocol/oidc/installation/KeycloakOIDCClientInstallation.java b/services/src/main/java/org/keycloak/protocol/oidc/installation/KeycloakOIDCClientInstallation.java index 79a3919be5..dfae5653f9 100755 --- a/services/src/main/java/org/keycloak/protocol/oidc/installation/KeycloakOIDCClientInstallation.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/installation/KeycloakOIDCClientInstallation.java @@ -87,7 +87,7 @@ public class KeycloakOIDCClientInstallation implements ClientInstallationProvide return false; } - if (client.isBearerOnly() && client.getNodeReRegistrationTimeout() <= 0) { + if (client.isBearerOnly() && !client.isServiceAccountsEnabled() && client.getNodeReRegistrationTimeout() <= 0) { return false; } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/AbstractClientTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/AbstractClientTest.java index 02a2cdb3d4..eed784ba9f 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/AbstractClientTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/AbstractClientTest.java @@ -84,12 +84,32 @@ public abstract class AbstractClientTest extends AbstractAuthTest { } protected String createOidcClient(String name) { + return createClient(createOidcClientRep(name)); + } + + protected String createOidcBearerOnlyClient(String name) { + ClientRepresentation clientRep = createOidcClientRep(name); + clientRep.setBearerOnly(Boolean.TRUE); + clientRep.setPublicClient(Boolean.FALSE); + return createClient(clientRep); + } + + protected String createOidcBearerOnlyClientWithAuthz(String name) { + ClientRepresentation clientRep = createOidcClientRep(name); + clientRep.setBearerOnly(Boolean.TRUE); + clientRep.setPublicClient(Boolean.FALSE); + clientRep.setAuthorizationServicesEnabled(Boolean.TRUE); + clientRep.setServiceAccountsEnabled(Boolean.TRUE); + return createClient(clientRep); + } + + protected ClientRepresentation createOidcClientRep(String name) { ClientRepresentation clientRep = new ClientRepresentation(); clientRep.setClientId(name); clientRep.setName(name); clientRep.setRootUrl("foo"); - clientRep.setProtocol("openid-connect"); - return createClient(clientRep); + clientRep.setProtocol("openid-connect"); + return clientRep; } protected String createSamlClient(String name) { diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/InstallationTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/InstallationTest.java index 4328c8f999..a33b2a11b2 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/InstallationTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/InstallationTest.java @@ -35,17 +35,28 @@ import static org.hamcrest.Matchers.*; public class InstallationTest extends AbstractClientTest { private static final String OIDC_NAME = "oidcInstallationClient"; + private static final String OIDC_NAME_BEARER_ONLY_NAME = "oidcInstallationClientBearerOnly"; + private static final String OIDC_NAME_BEARER_ONLY_WITH_AUTHZ_NAME = "oidcInstallationClientBearerOnlyWithAuthz"; private static final String SAML_NAME = "samlInstallationClient"; private ClientResource oidcClient; private String oidcClientId; + private ClientResource oidcBearerOnlyClient; + private String oidcBearerOnlyClientId; + private ClientResource oidcBearerOnlyClientWithAuthz; + private String oidcBearerOnlyClientWithAuthzId; private ClientResource samlClient; private String samlClientId; @Before public void createClients() { oidcClientId = createOidcClient(OIDC_NAME); + oidcBearerOnlyClientId = createOidcBearerOnlyClient(OIDC_NAME_BEARER_ONLY_NAME); + oidcBearerOnlyClientWithAuthzId = createOidcBearerOnlyClientWithAuthz(OIDC_NAME_BEARER_ONLY_WITH_AUTHZ_NAME); + oidcClient = findClientResource(OIDC_NAME); + oidcBearerOnlyClient = findClientResource(OIDC_NAME_BEARER_ONLY_NAME); + oidcBearerOnlyClientWithAuthz = findClientResource(OIDC_NAME_BEARER_ONLY_WITH_AUTHZ_NAME); samlClientId = createSamlClient(SAML_NAME); samlClient = findClientResource(SAML_NAME); @@ -54,6 +65,8 @@ public class InstallationTest extends AbstractClientTest { @After public void tearDown() { removeClient(oidcClientId); + removeClient(oidcBearerOnlyClientId); + removeClient(oidcBearerOnlyClientWithAuthzId); removeClient(samlClientId); } @@ -78,6 +91,25 @@ public class InstallationTest extends AbstractClientTest { assertOidcInstallationConfig(json); } + @Test + public void testOidcBearerOnlyJson() { + String json = oidcBearerOnlyClient.getInstallationProvider("keycloak-oidc-keycloak-json"); + assertOidcInstallationConfig(json); + assertThat(json, containsString("bearer-only")); + assertThat(json, not(containsString("public-client"))); + assertThat(json, not(containsString("credentials"))); + } + + @Test + public void testOidcBearerOnlyWithAuthzJson() { + String json = oidcBearerOnlyClientWithAuthz.getInstallationProvider("keycloak-oidc-keycloak-json"); + assertOidcInstallationConfig(json); + assertThat(json, containsString("bearer-only")); + assertThat(json, not(containsString("public-client"))); + assertThat(json, containsString("credentials")); + assertThat(json, containsString("secret")); + } + private void assertOidcInstallationConfig(String config) { assertThat(config, containsString("master")); assertThat(config, not(containsString(ApiUtil.findActiveKey(testRealmResource()).getPublicKey()))); diff --git a/themes/src/main/resources/theme/base/admin/resources/js/controllers/clients.js b/themes/src/main/resources/theme/base/admin/resources/js/controllers/clients.js index 3997ce1d67..39744628af 100755 --- a/themes/src/main/resources/theme/base/admin/resources/js/controllers/clients.js +++ b/themes/src/main/resources/theme/base/admin/resources/js/controllers/clients.js @@ -1096,6 +1096,8 @@ module.controller('ClientDetailCtrl', function($scope, realm, client, templates, } $scope.client.publicClient = false; $scope.client.serviceAccountsEnabled = true; + } else if ($scope.client.bearerOnly) { + $scope.client.serviceAccountsEnabled = false; } }