Details
diff --git a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ResourcesResource.java b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ResourcesResource.java
index 1aaaa23..07438d0 100644
--- a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ResourcesResource.java
+++ b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ResourcesResource.java
@@ -25,6 +25,7 @@ import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.List;
@@ -45,5 +46,16 @@ public interface ResourcesResource {
@GET
@NoCache
@Produces(MediaType.APPLICATION_JSON)
+ List<ResourceRepresentation> find(@QueryParam("name") String name,
+ @QueryParam("uri") String uri,
+ @QueryParam("owner") String owner,
+ @QueryParam("type") String type,
+ @QueryParam("scope") String scope,
+ @QueryParam("first") Integer firstResult,
+ @QueryParam("max") Integer maxResult);
+
+ @GET
+ @NoCache
+ @Produces(MediaType.APPLICATION_JSON)
List<ResourceRepresentation> resources();
}
diff --git a/services/src/main/java/org/keycloak/authorization/admin/PolicyEvaluationService.java b/services/src/main/java/org/keycloak/authorization/admin/PolicyEvaluationService.java
index 4af34ad..884f2e1 100644
--- a/services/src/main/java/org/keycloak/authorization/admin/PolicyEvaluationService.java
+++ b/services/src/main/java/org/keycloak/authorization/admin/PolicyEvaluationService.java
@@ -47,6 +47,7 @@ import org.keycloak.protocol.ProtocolMapper;
import org.keycloak.protocol.oidc.mappers.OIDCAccessTokenMapper;
import org.keycloak.representations.AccessToken;
import org.keycloak.services.Urls;
+import org.keycloak.services.resources.admin.RealmAuth;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
@@ -74,20 +75,23 @@ import static java.util.Arrays.asList;
public class PolicyEvaluationService {
private final AuthorizationProvider authorization;
+ private final RealmAuth auth;
@Context
private HttpRequest httpRequest;
private final ResourceServer resourceServer;
- PolicyEvaluationService(ResourceServer resourceServer, AuthorizationProvider authorization) {
+ PolicyEvaluationService(ResourceServer resourceServer, AuthorizationProvider authorization, RealmAuth auth) {
this.resourceServer = resourceServer;
this.authorization = authorization;
+ this.auth = auth;
}
@POST
@Consumes("application/json")
@Produces("application/json")
public void evaluate(PolicyEvaluationRequest evaluationRequest, @Suspended AsyncResponse asyncResponse) {
+ this.auth.requireView();
KeycloakIdentity identity = createIdentity(evaluationRequest);
EvaluationContext evaluationContext = createEvaluationContext(evaluationRequest, identity);
authorization.evaluators().from(createPermissions(evaluationRequest, evaluationContext, authorization), evaluationContext).evaluate(createDecisionCollector(authorization, identity, asyncResponse));
diff --git a/services/src/main/java/org/keycloak/authorization/admin/PolicyService.java b/services/src/main/java/org/keycloak/authorization/admin/PolicyService.java
index 3b9c194..b179378 100644
--- a/services/src/main/java/org/keycloak/authorization/admin/PolicyService.java
+++ b/services/src/main/java/org/keycloak/authorization/admin/PolicyService.java
@@ -273,7 +273,7 @@ public class PolicyService {
@Path("evaluate")
public PolicyEvaluationService getPolicyEvaluateResource() {
this.auth.requireView();
- PolicyEvaluationService resource = new PolicyEvaluationService(this.resourceServer, this.authorization);
+ PolicyEvaluationService resource = new PolicyEvaluationService(this.resourceServer, this.authorization, this.auth);
ResteasyProviderFactory.getInstance().injectProperties(resource);
diff --git a/services/src/main/java/org/keycloak/authorization/admin/ResourceSetService.java b/services/src/main/java/org/keycloak/authorization/admin/ResourceSetService.java
index d31146f..64ef061 100644
--- a/services/src/main/java/org/keycloak/authorization/admin/ResourceSetService.java
+++ b/services/src/main/java/org/keycloak/authorization/admin/ResourceSetService.java
@@ -177,7 +177,7 @@ public class ResourceSetService {
@GET
@NoCache
@Produces("application/json")
- public Response findAll(@QueryParam("name") String name,
+ public Response find(@QueryParam("name") String name,
@QueryParam("uri") String uri,
@QueryParam("owner") String owner,
@QueryParam("type") String type,
diff --git a/services/src/main/java/org/keycloak/authorization/admin/ScopeService.java b/services/src/main/java/org/keycloak/authorization/admin/ScopeService.java
index 44464b4..f050f32 100644
--- a/services/src/main/java/org/keycloak/authorization/admin/ScopeService.java
+++ b/services/src/main/java/org/keycloak/authorization/admin/ScopeService.java
@@ -107,6 +107,11 @@ public class ScopeService {
}
Scope scope = storeFactory.getScopeStore().findById(id);
+
+ if (scope == null) {
+ return Response.status(Status.NOT_FOUND).build();
+ }
+
PolicyStore policyStore = storeFactory.getPolicyStore();
List<Policy> policies = policyStore.findByScopeIds(Arrays.asList(scope.getId()), resourceServer.getId());
diff --git a/services/src/main/java/org/keycloak/authorization/protection/resource/ResourceService.java b/services/src/main/java/org/keycloak/authorization/protection/resource/ResourceService.java
index b02a935..fdaa12f 100644
--- a/services/src/main/java/org/keycloak/authorization/protection/resource/ResourceService.java
+++ b/services/src/main/java/org/keycloak/authorization/protection/resource/ResourceService.java
@@ -109,7 +109,7 @@ public class ResourceService {
}
private Set<String> findAll() {
- Response response = this.resourceManager.findAll(null, null, null, null, null, -1, -1);
+ Response response = this.resourceManager.find(null, null, null, null, null, -1, -1);
List<ResourceRepresentation> resources = (List<ResourceRepresentation>) response.getEntity();
return resources.stream().map(ResourceRepresentation::getId).collect(Collectors.toSet());
}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/PermissionsTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/PermissionsTest.java
index 81de894..b6fca90 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/PermissionsTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/PermissionsTest.java
@@ -17,10 +17,12 @@
package org.keycloak.testsuite.admin;
+import org.apache.bcel.generic.RETURN;
import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataOutput;
import org.junit.Rule;
import org.junit.Test;
import org.keycloak.admin.client.Keycloak;
+import org.keycloak.admin.client.resource.AuthorizationResource;
import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.models.AdminRoles;
import org.keycloak.models.Constants;
@@ -45,6 +47,10 @@ import org.keycloak.representations.idm.RoleRepresentation;
import org.keycloak.representations.idm.UserFederationMapperRepresentation;
import org.keycloak.representations.idm.UserFederationProviderRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
+import org.keycloak.representations.idm.authorization.PolicyRepresentation;
+import org.keycloak.representations.idm.authorization.ResourceRepresentation;
+import org.keycloak.representations.idm.authorization.ResourceServerRepresentation;
+import org.keycloak.representations.idm.authorization.ScopeRepresentation;
import org.keycloak.services.resources.admin.RealmAuth.Resource;
import org.keycloak.testsuite.AbstractKeycloakTest;
import org.keycloak.testsuite.Assert;
@@ -68,6 +74,8 @@ import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import static org.junit.Assert.*;
+import static org.keycloak.services.resources.admin.RealmAuth.Resource.AUTHORIZATION;
+import static org.keycloak.services.resources.admin.RealmAuth.Resource.CLIENT;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
@@ -771,6 +779,123 @@ public class PermissionsTest extends AbstractKeycloakTest {
}
@Test
+ public void clientAuthorization() {
+ invoke(new InvocationWithResponse() {
+ public void invoke(RealmResource realm, AtomicReference<Response> response) {
+ realm.clients().create(ClientBuilder.create().clientId("foo-authz").build());
+ org.keycloak.representations.idm.ClientRepresentation foo = realm.clients().findByClientId("foo-authz").get(0);
+ foo.setServiceAccountsEnabled(true);
+ foo.setAuthorizationServicesEnabled(true);
+ realm.clients().get(foo.getId()).update(foo);
+ }
+ }, CLIENT, true);
+ invoke(new Invocation() {
+ public void invoke(RealmResource realm) {
+ org.keycloak.representations.idm.ClientRepresentation foo = realm.clients().findByClientId("foo-authz").get(0);
+ realm.clients().get(foo.getId()).authorization().getSettings();
+ }
+ }, AUTHORIZATION, false);
+ invoke(new Invocation() {
+ public void invoke(RealmResource realm) {
+ org.keycloak.representations.idm.ClientRepresentation foo = realm.clients().findByClientId("foo-authz").get(0);
+ AuthorizationResource authorization = realm.clients().get(foo.getId()).authorization();
+ ResourceServerRepresentation settings = authorization.getSettings();
+ authorization.update(settings);
+ }
+ }, AUTHORIZATION, true);
+ invoke(new Invocation() {
+ public void invoke(RealmResource realm) {
+ org.keycloak.representations.idm.ClientRepresentation foo = realm.clients().findByClientId("foo-authz").get(0);
+ AuthorizationResource authorization = realm.clients().get(foo.getId()).authorization();
+ authorization.resources().resources();
+ }
+ }, AUTHORIZATION, false);
+ invoke(new Invocation() {
+ public void invoke(RealmResource realm) {
+ org.keycloak.representations.idm.ClientRepresentation foo = realm.clients().findByClientId("foo-authz").get(0);
+ AuthorizationResource authorization = realm.clients().get(foo.getId()).authorization();
+ authorization.scopes().scopes();
+ }
+ }, AUTHORIZATION, false);
+ invoke(new Invocation() {
+ public void invoke(RealmResource realm) {
+ org.keycloak.representations.idm.ClientRepresentation foo = realm.clients().findByClientId("foo-authz").get(0);
+ AuthorizationResource authorization = realm.clients().get(foo.getId()).authorization();
+ authorization.policies().policies();
+ }
+ }, AUTHORIZATION, false);
+ invoke(new InvocationWithResponse() {
+ public void invoke(RealmResource realm, AtomicReference<Response> response) {
+ org.keycloak.representations.idm.ClientRepresentation foo = realm.clients().findByClientId("foo-authz").get(0);
+ AuthorizationResource authorization = realm.clients().get(foo.getId()).authorization();
+ response.set(authorization.resources().create(new ResourceRepresentation("Test", Collections.emptySet())));
+ }
+ }, AUTHORIZATION, true);
+ invoke(new InvocationWithResponse() {
+ public void invoke(RealmResource realm, AtomicReference<Response> response) {
+ org.keycloak.representations.idm.ClientRepresentation foo = realm.clients().findByClientId("foo-authz").get(0);
+ AuthorizationResource authorization = realm.clients().get(foo.getId()).authorization();
+ response.set(authorization.scopes().create(new ScopeRepresentation("Test")));
+ }
+ }, AUTHORIZATION, true);
+ invoke(new InvocationWithResponse() {
+ public void invoke(RealmResource realm, AtomicReference<Response> response) {
+ org.keycloak.representations.idm.ClientRepresentation foo = realm.clients().findByClientId("foo-authz").get(0);
+ AuthorizationResource authorization = realm.clients().get(foo.getId()).authorization();
+ PolicyRepresentation representation = new PolicyRepresentation();
+ representation.setName("Test PermissionsTest");
+ representation.setType("js");
+ HashMap<String, String> config = new HashMap<>();
+ config.put("code", "");
+ representation.setConfig(config);
+ response.set(authorization.policies().create(representation));
+ }
+ }, AUTHORIZATION, true);
+ invoke(new Invocation() {
+ public void invoke(RealmResource realm) {
+ org.keycloak.representations.idm.ClientRepresentation foo = realm.clients().findByClientId("foo-authz").get(0);
+ AuthorizationResource authorization = realm.clients().get(foo.getId()).authorization();
+ authorization.resources().resource("nosuch").update(new ResourceRepresentation());
+ }
+ }, AUTHORIZATION, true);
+ invoke(new Invocation() {
+ public void invoke(RealmResource realm) {
+ org.keycloak.representations.idm.ClientRepresentation foo = realm.clients().findByClientId("foo-authz").get(0);
+ AuthorizationResource authorization = realm.clients().get(foo.getId()).authorization();
+ authorization.scopes().scope("nosuch").update(new ScopeRepresentation());
+ }
+ }, AUTHORIZATION, true);
+ invoke(new Invocation() {
+ public void invoke(RealmResource realm) {
+ org.keycloak.representations.idm.ClientRepresentation foo = realm.clients().findByClientId("foo-authz").get(0);
+ AuthorizationResource authorization = realm.clients().get(foo.getId()).authorization();
+ authorization.policies().policy("nosuch").update(new PolicyRepresentation());
+ }
+ }, AUTHORIZATION, true);
+ invoke(new Invocation() {
+ public void invoke(RealmResource realm) {
+ org.keycloak.representations.idm.ClientRepresentation foo = realm.clients().findByClientId("foo-authz").get(0);
+ AuthorizationResource authorization = realm.clients().get(foo.getId()).authorization();
+ authorization.resources().resource("nosuch").remove();
+ }
+ }, AUTHORIZATION, true);
+ invoke(new Invocation() {
+ public void invoke(RealmResource realm) {
+ org.keycloak.representations.idm.ClientRepresentation foo = realm.clients().findByClientId("foo-authz").get(0);
+ AuthorizationResource authorization = realm.clients().get(foo.getId()).authorization();
+ authorization.scopes().scope("nosuch").remove();
+ }
+ }, AUTHORIZATION, true);
+ invoke(new Invocation() {
+ public void invoke(RealmResource realm) {
+ org.keycloak.representations.idm.ClientRepresentation foo = realm.clients().findByClientId("foo-authz").get(0);
+ AuthorizationResource authorization = realm.clients().get(foo.getId()).authorization();
+ authorization.policies().policy("nosuch").remove();
+ }
+ }, AUTHORIZATION, true);
+ }
+
+ @Test
public void roles() {
invoke(new Invocation() {
public void invoke(RealmResource realm) {
@@ -1543,6 +1668,8 @@ public class PermissionsTest extends AbstractKeycloakTest {
return AdminRoles.VIEW_EVENTS;
case IDENTITY_PROVIDER:
return AdminRoles.VIEW_IDENTITY_PROVIDERS;
+ case AUTHORIZATION:
+ return AdminRoles.VIEW_AUTHORIZATION;
default:
throw new RuntimeException("Unexpected resouce");
}
@@ -1560,6 +1687,8 @@ public class PermissionsTest extends AbstractKeycloakTest {
return AdminRoles.MANAGE_EVENTS;
case IDENTITY_PROVIDER:
return AdminRoles.MANAGE_IDENTITY_PROVIDERS;
+ case AUTHORIZATION:
+ return AdminRoles.MANAGE_AUTHORIZATION;
default:
throw new RuntimeException("Unexpected resouce");
}
@@ -1577,6 +1706,8 @@ public class PermissionsTest extends AbstractKeycloakTest {
return AdminRoles.VIEW_IDENTITY_PROVIDERS;
case IDENTITY_PROVIDER:
return AdminRoles.VIEW_REALM;
+ case AUTHORIZATION:
+ return AdminRoles.VIEW_IDENTITY_PROVIDERS;
default:
throw new RuntimeException("Unexpected resouce");
}
@@ -1594,6 +1725,8 @@ public class PermissionsTest extends AbstractKeycloakTest {
return AdminRoles.MANAGE_IDENTITY_PROVIDERS;
case IDENTITY_PROVIDER:
return AdminRoles.MANAGE_REALM;
+ case AUTHORIZATION:
+ return AdminRoles.MANAGE_IDENTITY_PROVIDERS;
default:
throw new RuntimeException("Unexpected resouce");
}