From ed2d392a3dc4ff334b4d263759a9dd416f250f08 Mon Sep 17 00:00:00 2001 From: Pedro Igor Date: Mon, 30 Dec 2019 15:53:08 -0300 Subject: [PATCH] [KEYCLOAK-9666] - Entitlement request with service account results in server error --- .../resource/AuthorizationResource.java | 4 +- .../AuthorizationTokenService.java | 8 ++- .../testsuite/authz/EntitlementAPITest.java | 54 +++++++++++++++++++ 3 files changed, 64 insertions(+), 2 deletions(-) diff --git a/authz/client/src/main/java/org/keycloak/authorization/client/resource/AuthorizationResource.java b/authz/client/src/main/java/org/keycloak/authorization/client/resource/AuthorizationResource.java index 6b30b0d355..84abc2d7db 100644 --- a/authz/client/src/main/java/org/keycloak/authorization/client/resource/AuthorizationResource.java +++ b/authz/client/src/main/java/org/keycloak/authorization/client/resource/AuthorizationResource.java @@ -74,7 +74,9 @@ public class AuthorizationResource { Callable callable = new Callable() { @Override public AuthorizationResponse call() throws Exception { - request.setAudience(configuration.getResource()); + if (request.getAudience() == null) { + request.setAudience(configuration.getResource()); + } HttpMethod method = http.post(serverConfiguration.getTokenEndpoint()); diff --git a/services/src/main/java/org/keycloak/authorization/authorization/AuthorizationTokenService.java b/services/src/main/java/org/keycloak/authorization/authorization/AuthorizationTokenService.java index b0ad83e3ce..684defa1a6 100644 --- a/services/src/main/java/org/keycloak/authorization/authorization/AuthorizationTokenService.java +++ b/services/src/main/java/org/keycloak/authorization/authorization/AuthorizationTokenService.java @@ -81,6 +81,7 @@ import org.keycloak.services.CorsErrorResponseException; import org.keycloak.services.ErrorResponseException; import org.keycloak.services.Urls; import org.keycloak.services.managers.AuthenticationManager; +import org.keycloak.services.managers.AuthenticationSessionManager; import org.keycloak.services.resources.Cors; import org.keycloak.sessions.AuthenticationSessionModel; import org.keycloak.sessions.RootAuthenticationSessionModel; @@ -283,7 +284,12 @@ public class AuthorizationTokenService { RootAuthenticationSessionModel rootAuthSession = keycloakSession.authenticationSessions().getRootAuthenticationSession(realm, userSessionModel.getId()); if (rootAuthSession == null) { - rootAuthSession = keycloakSession.authenticationSessions().createRootAuthenticationSession(userSessionModel.getId(), realm); + if (userSessionModel.getUser().getServiceAccountClientLink() == null) { + rootAuthSession = keycloakSession.authenticationSessions().createRootAuthenticationSession(userSessionModel.getId(), realm); + } else { + // if the user session is associated with a service account + rootAuthSession = new AuthenticationSessionManager(keycloakSession).createAuthenticationSession(realm, false); + } } AuthenticationSessionModel authSession = rootAuthSession.createAuthenticationSession(targetClient); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/EntitlementAPITest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/EntitlementAPITest.java index a758bd8a67..a484ebdfdf 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/EntitlementAPITest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/EntitlementAPITest.java @@ -2038,6 +2038,60 @@ public class EntitlementAPITest extends AbstractAuthzTest { assertEquals("Resource A", permissions.iterator().next().getResourceName()); } + @Test + public void testClientToClientPermissionRequest() throws Exception { + ClientResource client = getClient(getRealm(), RESOURCE_SERVER_TEST); + AuthorizationResource authorization = client.authorization(); + + JSPolicyRepresentation policy = new JSPolicyRepresentation(); + + policy.setName(KeycloakModelUtils.generateId()); + policy.setCode("$evaluation.grant();"); + + authorization.policies().js().create(policy).close(); + + ResourceRepresentation resource = new ResourceRepresentation(); + + resource.setName("Sensors"); + + try (Response response = authorization.resources().create(resource)) { + response.readEntity(ResourceRepresentation.class); + } + + ResourcePermissionRepresentation permission = new ResourcePermissionRepresentation(); + + permission.setName("View Sensor"); + permission.addPolicy(policy.getName()); + + authorization.permissions().resource().create(permission).close(); + + ClientRepresentation otherClient = new ClientRepresentation(); + + otherClient.setClientId("serviceB"); + otherClient.setServiceAccountsEnabled(true); + otherClient.setSecret("secret"); + otherClient.setPublicClient(false); + + getRealm().clients().create(otherClient); + + Map credentials = new HashMap<>(); + + credentials.put("secret", "secret"); + + AuthzClient authzClient = AuthzClient + .create(new Configuration(suiteContext.getAuthServerInfo().getContextRoot().toString() + "/auth", + getRealm().toRepresentation().getRealm(), otherClient.getClientId(), + credentials, getAuthzClient(AUTHZ_CLIENT_CONFIG).getConfiguration().getHttpClient())); + + AuthorizationRequest request = new AuthorizationRequest(); + + request.setAudience(RESOURCE_SERVER_TEST); + + AuthorizationResponse response = authzClient.authorization().authorize(request); + + assertNotNull(response.getToken()); + } + private void testRptRequestWithResourceName(String configFile) { Metadata metadata = new Metadata();