Merge pull request #4214 from pedroigor/KEYCLOAK-4904
[KEYCLOAK-4904] - Authorization Audit - Part 1
This commit is contained in:
commit
fd8a3dccaf
18 changed files with 254 additions and 95 deletions
|
@ -156,5 +156,25 @@ public enum ResourceType {
|
|||
/**
|
||||
*
|
||||
*/
|
||||
, COMPONENT;
|
||||
, COMPONENT
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
, AUTHORIZATION_RESOURCE_SERVER
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
, AUTHORIZATION_RESOURCE
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
, AUTHORIZATION_SCOPE
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
, AUTHORIZATION_POLICY;
|
||||
}
|
||||
|
|
|
@ -772,11 +772,7 @@ public class ModelToRepresentation {
|
|||
return rep;
|
||||
}
|
||||
|
||||
public static ScopeRepresentation toRepresentation(Scope model, AuthorizationProvider authorizationProvider) {
|
||||
return toRepresentation(model, authorizationProvider, true);
|
||||
}
|
||||
|
||||
public static ScopeRepresentation toRepresentation(Scope model, AuthorizationProvider authorizationProvider, boolean deep) {
|
||||
public static ScopeRepresentation toRepresentation(Scope model) {
|
||||
ScopeRepresentation scope = new ScopeRepresentation();
|
||||
|
||||
scope.setId(model.getId());
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.keycloak.authorization.AuthorizationProvider;
|
|||
import org.keycloak.authorization.model.ResourceServer;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.services.resources.admin.AdminEventBuilder;
|
||||
import org.keycloak.services.resources.admin.RealmAuth;
|
||||
|
||||
import javax.ws.rs.Path;
|
||||
|
@ -34,14 +35,14 @@ public class AuthorizationService {
|
|||
|
||||
private final RealmAuth auth;
|
||||
private final ClientModel client;
|
||||
private final KeycloakSession session;
|
||||
private final ResourceServer resourceServer;
|
||||
private final AuthorizationProvider authorization;
|
||||
private final AdminEventBuilder adminEvent;
|
||||
|
||||
public AuthorizationService(KeycloakSession session, ClientModel client, RealmAuth auth) {
|
||||
this.session = session;
|
||||
public AuthorizationService(KeycloakSession session, ClientModel client, RealmAuth auth, AdminEventBuilder adminEvent) {
|
||||
this.client = client;
|
||||
this.authorization = session.getProvider(AuthorizationProvider.class);
|
||||
this.adminEvent = adminEvent;
|
||||
this.resourceServer = this.authorization.getStoreFactory().getResourceServerStore().findByClient(this.client.getId());
|
||||
this.auth = auth;
|
||||
|
||||
|
@ -52,16 +53,16 @@ public class AuthorizationService {
|
|||
|
||||
@Path("/resource-server")
|
||||
public ResourceServerService resourceServer() {
|
||||
ResourceServerService resource = new ResourceServerService(this.authorization, this.resourceServer, this.client, this.auth);
|
||||
ResourceServerService resource = new ResourceServerService(this.authorization, this.resourceServer, this.client, this.auth, adminEvent);
|
||||
|
||||
ResteasyProviderFactory.getInstance().injectProperties(resource);
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
public void enable() {
|
||||
public void enable(boolean newClient) {
|
||||
if (!isEnabled()) {
|
||||
resourceServer().create();
|
||||
resourceServer().create(newClient);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ import java.util.Map;
|
|||
import org.keycloak.authorization.AuthorizationProvider;
|
||||
import org.keycloak.authorization.model.Policy;
|
||||
import org.keycloak.authorization.model.ResourceServer;
|
||||
import org.keycloak.services.resources.admin.AdminEventBuilder;
|
||||
import org.keycloak.services.resources.admin.RealmAuth;
|
||||
|
||||
/**
|
||||
|
@ -29,18 +30,18 @@ import org.keycloak.services.resources.admin.RealmAuth;
|
|||
*/
|
||||
public class PermissionService extends PolicyService {
|
||||
|
||||
public PermissionService(ResourceServer resourceServer, AuthorizationProvider authorization, RealmAuth auth) {
|
||||
super(resourceServer, authorization, auth);
|
||||
public PermissionService(ResourceServer resourceServer, AuthorizationProvider authorization, RealmAuth auth, AdminEventBuilder adminEvent) {
|
||||
super(resourceServer, authorization, auth, adminEvent);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PolicyResourceService doCreatePolicyResource(Policy policy) {
|
||||
return new PolicyTypeResourceService(policy, resourceServer, authorization, auth);
|
||||
return new PolicyTypeResourceService(policy, resourceServer, authorization, auth, adminEvent);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PolicyTypeService doCreatePolicyTypeResource(String type) {
|
||||
return new PolicyTypeService(type, resourceServer, authorization, auth) {
|
||||
return new PolicyTypeService(type, resourceServer, authorization, auth, adminEvent) {
|
||||
@Override
|
||||
protected List<Object> doSearch(Integer firstResult, Integer maxResult, Map<String, String[]> filters) {
|
||||
filters.put("permission", new String[] {Boolean.TRUE.toString()});
|
||||
|
|
|
@ -26,8 +26,10 @@ import javax.ws.rs.GET;
|
|||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.Response.Status;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
|
||||
import org.jboss.resteasy.annotations.cache.NoCache;
|
||||
import org.keycloak.authorization.AuthorizationProvider;
|
||||
|
@ -36,12 +38,15 @@ import org.keycloak.authorization.model.ResourceServer;
|
|||
import org.keycloak.authorization.policy.provider.PolicyProviderFactory;
|
||||
import org.keycloak.authorization.store.PolicyStore;
|
||||
import org.keycloak.authorization.store.StoreFactory;
|
||||
import org.keycloak.events.admin.OperationType;
|
||||
import org.keycloak.events.admin.ResourceType;
|
||||
import org.keycloak.models.utils.ModelToRepresentation;
|
||||
import org.keycloak.models.utils.RepresentationToModel;
|
||||
import org.keycloak.representations.idm.authorization.AbstractPolicyRepresentation;
|
||||
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
|
||||
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
|
||||
import org.keycloak.representations.idm.authorization.ScopeRepresentation;
|
||||
import org.keycloak.services.resources.admin.AdminEventBuilder;
|
||||
import org.keycloak.services.resources.admin.RealmAuth;
|
||||
import org.keycloak.util.JsonSerialization;
|
||||
|
||||
|
@ -54,19 +59,21 @@ public class PolicyResourceService {
|
|||
protected final ResourceServer resourceServer;
|
||||
protected final AuthorizationProvider authorization;
|
||||
protected final RealmAuth auth;
|
||||
private final AdminEventBuilder adminEvent;
|
||||
|
||||
public PolicyResourceService(Policy policy, ResourceServer resourceServer, AuthorizationProvider authorization, RealmAuth auth) {
|
||||
public PolicyResourceService(Policy policy, ResourceServer resourceServer, AuthorizationProvider authorization, RealmAuth auth, AdminEventBuilder adminEvent) {
|
||||
this.policy = policy;
|
||||
this.resourceServer = resourceServer;
|
||||
this.authorization = authorization;
|
||||
this.auth = auth;
|
||||
this.adminEvent = adminEvent.resource(ResourceType.AUTHORIZATION_POLICY);
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Consumes("application/json")
|
||||
@Produces("application/json")
|
||||
@NoCache
|
||||
public Response update(String payload) {
|
||||
public Response update(@Context UriInfo uriInfo, String payload) {
|
||||
this.auth.requireManage();
|
||||
|
||||
AbstractPolicyRepresentation representation = doCreateRepresentation(payload);
|
||||
|
@ -79,11 +86,14 @@ public class PolicyResourceService {
|
|||
|
||||
RepresentationToModel.toModel(representation, authorization, policy);
|
||||
|
||||
|
||||
audit(uriInfo, representation, OperationType.UPDATE);
|
||||
|
||||
return Response.status(Status.CREATED).build();
|
||||
}
|
||||
|
||||
@DELETE
|
||||
public Response delete() {
|
||||
public Response delete(@Context UriInfo uriInfo) {
|
||||
this.auth.requireManage();
|
||||
|
||||
if (policy == null) {
|
||||
|
@ -98,6 +108,10 @@ public class PolicyResourceService {
|
|||
|
||||
policyStore.delete(policy.getId());
|
||||
|
||||
if (authorization.getRealm().isAdminEventsEnabled()) {
|
||||
audit(uriInfo, toRepresentation(policy, authorization), OperationType.DELETE);
|
||||
}
|
||||
|
||||
return Response.noContent().build();
|
||||
}
|
||||
|
||||
|
@ -225,4 +239,10 @@ public class PolicyResourceService {
|
|||
protected Policy getPolicy() {
|
||||
return policy;
|
||||
}
|
||||
|
||||
private void audit(@Context UriInfo uriInfo, AbstractPolicyRepresentation policy, OperationType operation) {
|
||||
if (authorization.getRealm().isAdminEventsEnabled()) {
|
||||
adminEvent.operation(operation).resourcePath(uriInfo).representation(policy).success();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,9 +33,11 @@ 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.Context;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.Response.Status;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
|
||||
import org.jboss.resteasy.annotations.cache.NoCache;
|
||||
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
||||
|
@ -46,12 +48,16 @@ import org.keycloak.authorization.policy.provider.PolicyProviderAdminService;
|
|||
import org.keycloak.authorization.policy.provider.PolicyProviderFactory;
|
||||
import org.keycloak.authorization.store.PolicyStore;
|
||||
import org.keycloak.authorization.store.StoreFactory;
|
||||
import org.keycloak.events.admin.OperationType;
|
||||
import org.keycloak.events.admin.ResourceType;
|
||||
import org.keycloak.models.Constants;
|
||||
import org.keycloak.models.utils.ModelToRepresentation;
|
||||
import org.keycloak.representations.idm.authorization.AbstractPolicyRepresentation;
|
||||
import org.keycloak.representations.idm.authorization.PolicyProviderRepresentation;
|
||||
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
|
||||
import org.keycloak.representations.idm.authorization.ScopeRepresentation;
|
||||
import org.keycloak.services.ErrorResponseException;
|
||||
import org.keycloak.services.resources.admin.AdminEventBuilder;
|
||||
import org.keycloak.services.resources.admin.RealmAuth;
|
||||
import org.keycloak.util.JsonSerialization;
|
||||
|
||||
|
@ -63,11 +69,13 @@ public class PolicyService {
|
|||
protected final ResourceServer resourceServer;
|
||||
protected final AuthorizationProvider authorization;
|
||||
protected final RealmAuth auth;
|
||||
protected final AdminEventBuilder adminEvent;
|
||||
|
||||
public PolicyService(ResourceServer resourceServer, AuthorizationProvider authorization, RealmAuth auth) {
|
||||
public PolicyService(ResourceServer resourceServer, AuthorizationProvider authorization, RealmAuth auth, AdminEventBuilder adminEvent) {
|
||||
this.resourceServer = resourceServer;
|
||||
this.authorization = authorization;
|
||||
this.auth = auth;
|
||||
this.adminEvent = adminEvent.resource(ResourceType.AUTHORIZATION_POLICY);
|
||||
}
|
||||
|
||||
@Path("{type}")
|
||||
|
@ -84,18 +92,18 @@ public class PolicyService {
|
|||
}
|
||||
|
||||
protected PolicyTypeService doCreatePolicyTypeResource(String type) {
|
||||
return new PolicyTypeService(type, resourceServer, authorization, auth);
|
||||
return new PolicyTypeService(type, resourceServer, authorization, auth, adminEvent);
|
||||
}
|
||||
|
||||
protected Object doCreatePolicyResource(Policy policy) {
|
||||
return new PolicyResourceService(policy, resourceServer, authorization, auth);
|
||||
return new PolicyResourceService(policy, resourceServer, authorization, auth, adminEvent);
|
||||
}
|
||||
|
||||
@POST
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@NoCache
|
||||
public Response create(String payload) {
|
||||
public Response create(@Context UriInfo uriInfo, String payload) {
|
||||
this.auth.requireManage();
|
||||
|
||||
AbstractPolicyRepresentation representation = doCreateRepresentation(payload);
|
||||
|
@ -103,6 +111,8 @@ public class PolicyService {
|
|||
|
||||
representation.setId(policy.getId());
|
||||
|
||||
audit(uriInfo, representation, representation.getId(), OperationType.CREATE);
|
||||
|
||||
return Response.status(Status.CREATED).entity(representation).build();
|
||||
}
|
||||
|
||||
|
@ -280,4 +290,14 @@ public class PolicyService {
|
|||
findAssociatedPolicies(associated, policies);
|
||||
});
|
||||
}
|
||||
|
||||
private void audit(@Context UriInfo uriInfo, AbstractPolicyRepresentation resource, String id, OperationType operation) {
|
||||
if (authorization.getRealm().isAdminEventsEnabled()) {
|
||||
if (id != null) {
|
||||
adminEvent.operation(operation).resourcePath(uriInfo, id).representation(resource).success();
|
||||
} else {
|
||||
adminEvent.operation(operation).resourcePath(uriInfo).representation(resource).success();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.keycloak.authorization.model.ResourceServer;
|
|||
import org.keycloak.authorization.policy.provider.PolicyProviderFactory;
|
||||
import org.keycloak.models.utils.ModelToRepresentation;
|
||||
import org.keycloak.representations.idm.authorization.AbstractPolicyRepresentation;
|
||||
import org.keycloak.services.resources.admin.AdminEventBuilder;
|
||||
import org.keycloak.services.resources.admin.RealmAuth;
|
||||
import org.keycloak.util.JsonSerialization;
|
||||
|
||||
|
@ -32,8 +33,8 @@ import org.keycloak.util.JsonSerialization;
|
|||
*/
|
||||
public class PolicyTypeResourceService extends PolicyResourceService {
|
||||
|
||||
public PolicyTypeResourceService(Policy policy, ResourceServer resourceServer, AuthorizationProvider authorization, RealmAuth auth) {
|
||||
super(policy, resourceServer, authorization, auth);
|
||||
public PolicyTypeResourceService(Policy policy, ResourceServer resourceServer, AuthorizationProvider authorization, RealmAuth auth, AdminEventBuilder adminEvent) {
|
||||
super(policy, resourceServer, authorization, auth, adminEvent);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -30,6 +30,7 @@ import org.keycloak.authorization.policy.provider.PolicyProviderAdminService;
|
|||
import org.keycloak.authorization.policy.provider.PolicyProviderFactory;
|
||||
import org.keycloak.models.utils.ModelToRepresentation;
|
||||
import org.keycloak.representations.idm.authorization.AbstractPolicyRepresentation;
|
||||
import org.keycloak.services.resources.admin.AdminEventBuilder;
|
||||
import org.keycloak.services.resources.admin.RealmAuth;
|
||||
import org.keycloak.util.JsonSerialization;
|
||||
|
||||
|
@ -40,8 +41,8 @@ public class PolicyTypeService extends PolicyService {
|
|||
|
||||
private final String type;
|
||||
|
||||
PolicyTypeService(String type, ResourceServer resourceServer, AuthorizationProvider authorization, RealmAuth auth) {
|
||||
super(resourceServer, authorization, auth);
|
||||
PolicyTypeService(String type, ResourceServer resourceServer, AuthorizationProvider authorization, RealmAuth auth, AdminEventBuilder adminEvent) {
|
||||
super(resourceServer, authorization, auth, adminEvent);
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
|
@ -60,7 +61,7 @@ public class PolicyTypeService extends PolicyService {
|
|||
|
||||
@Override
|
||||
protected Object doCreatePolicyResource(Policy policy) {
|
||||
return new PolicyTypeResourceService(policy, resourceServer,authorization, auth);
|
||||
return new PolicyTypeResourceService(policy, resourceServer,authorization, auth, adminEvent);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -40,12 +40,15 @@ import org.keycloak.authorization.store.PolicyStore;
|
|||
import org.keycloak.authorization.store.ResourceStore;
|
||||
import org.keycloak.authorization.store.ScopeStore;
|
||||
import org.keycloak.authorization.store.StoreFactory;
|
||||
import org.keycloak.events.admin.OperationType;
|
||||
import org.keycloak.events.admin.ResourceType;
|
||||
import org.keycloak.exportimport.util.ExportUtils;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.Constants;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.utils.ModelToRepresentation;
|
||||
import org.keycloak.models.utils.RepresentationToModel;
|
||||
import org.keycloak.representations.idm.authorization.DecisionStrategy;
|
||||
import org.keycloak.representations.idm.authorization.Logic;
|
||||
|
@ -53,6 +56,7 @@ import org.keycloak.representations.idm.authorization.PolicyRepresentation;
|
|||
import org.keycloak.representations.idm.authorization.ResourcePermissionRepresentation;
|
||||
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
|
||||
import org.keycloak.representations.idm.authorization.ResourceServerRepresentation;
|
||||
import org.keycloak.services.resources.admin.AdminEventBuilder;
|
||||
import org.keycloak.services.resources.admin.RealmAuth;
|
||||
|
||||
/**
|
||||
|
@ -62,19 +66,24 @@ public class ResourceServerService {
|
|||
|
||||
private final AuthorizationProvider authorization;
|
||||
private final RealmAuth auth;
|
||||
private final AdminEventBuilder adminEvent;
|
||||
private final KeycloakSession session;
|
||||
private ResourceServer resourceServer;
|
||||
private final ClientModel client;
|
||||
|
||||
public ResourceServerService(AuthorizationProvider authorization, ResourceServer resourceServer, ClientModel client, RealmAuth auth) {
|
||||
@Context
|
||||
private UriInfo uriInfo;
|
||||
|
||||
public ResourceServerService(AuthorizationProvider authorization, ResourceServer resourceServer, ClientModel client, RealmAuth auth, AdminEventBuilder adminEvent) {
|
||||
this.authorization = authorization;
|
||||
this.session = authorization.getKeycloakSession();
|
||||
this.client = client;
|
||||
this.resourceServer = resourceServer;
|
||||
this.auth = auth;
|
||||
this.adminEvent = adminEvent;
|
||||
}
|
||||
|
||||
public void create() {
|
||||
public void create(boolean newClient) {
|
||||
this.auth.requireManage();
|
||||
|
||||
UserModel serviceAccount = this.session.users().getServiceAccount(client);
|
||||
|
@ -86,16 +95,17 @@ public class ResourceServerService {
|
|||
this.resourceServer = this.authorization.getStoreFactory().getResourceServerStore().create(this.client.getId());
|
||||
createDefaultRoles(serviceAccount);
|
||||
createDefaultPermission(createDefaultResource(), createDefaultPolicy());
|
||||
audit(OperationType.CREATE, uriInfo, newClient);
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Consumes("application/json")
|
||||
@Produces("application/json")
|
||||
public Response update(ResourceServerRepresentation server) {
|
||||
public Response update(@Context UriInfo uriInfo, ResourceServerRepresentation server) {
|
||||
this.auth.requireManage();
|
||||
this.resourceServer.setAllowRemoteResourceManagement(server.isAllowRemoteResourceManagement());
|
||||
this.resourceServer.setPolicyEnforcementMode(server.getPolicyEnforcementMode());
|
||||
|
||||
audit(OperationType.UPDATE, uriInfo, false);
|
||||
return Response.noContent().build();
|
||||
}
|
||||
|
||||
|
@ -105,17 +115,19 @@ public class ResourceServerService {
|
|||
ResourceStore resourceStore = storeFactory.getResourceStore();
|
||||
String id = resourceServer.getId();
|
||||
|
||||
PolicyStore policyStore = storeFactory.getPolicyStore();
|
||||
|
||||
policyStore.findByResourceServer(id).forEach(scope -> policyStore.delete(scope.getId()));
|
||||
|
||||
resourceStore.findByResourceServer(id).forEach(resource -> resourceStore.delete(resource.getId()));
|
||||
|
||||
ScopeStore scopeStore = storeFactory.getScopeStore();
|
||||
|
||||
scopeStore.findByResourceServer(id).forEach(scope -> scopeStore.delete(scope.getId()));
|
||||
|
||||
PolicyStore policyStore = storeFactory.getPolicyStore();
|
||||
|
||||
policyStore.findByResourceServer(id).forEach(scope -> policyStore.delete(scope.getId()));
|
||||
|
||||
storeFactory.getResourceServerStore().delete(id);
|
||||
|
||||
audit(OperationType.DELETE, uriInfo, false);
|
||||
}
|
||||
|
||||
@GET
|
||||
|
@ -143,12 +155,14 @@ public class ResourceServerService {
|
|||
|
||||
RepresentationToModel.toModel(rep, authorization);
|
||||
|
||||
audit(OperationType.UPDATE, uriInfo, false);
|
||||
|
||||
return Response.noContent().build();
|
||||
}
|
||||
|
||||
@Path("/resource")
|
||||
public ResourceSetService getResourceSetResource() {
|
||||
ResourceSetService resource = new ResourceSetService(this.resourceServer, this.authorization, this.auth);
|
||||
ResourceSetService resource = new ResourceSetService(this.resourceServer, this.authorization, this.auth, adminEvent);
|
||||
|
||||
ResteasyProviderFactory.getInstance().injectProperties(resource);
|
||||
|
||||
|
@ -157,7 +171,7 @@ public class ResourceServerService {
|
|||
|
||||
@Path("/scope")
|
||||
public ScopeService getScopeResource() {
|
||||
ScopeService resource = new ScopeService(this.resourceServer, this.authorization, this.auth);
|
||||
ScopeService resource = new ScopeService(this.resourceServer, this.authorization, this.auth, adminEvent);
|
||||
|
||||
ResteasyProviderFactory.getInstance().injectProperties(resource);
|
||||
|
||||
|
@ -166,7 +180,7 @@ public class ResourceServerService {
|
|||
|
||||
@Path("/policy")
|
||||
public PolicyService getPolicyResource() {
|
||||
PolicyService resource = new PolicyService(this.resourceServer, this.authorization, this.auth);
|
||||
PolicyService resource = new PolicyService(this.resourceServer, this.authorization, this.auth, adminEvent);
|
||||
|
||||
ResteasyProviderFactory.getInstance().injectProperties(resource);
|
||||
|
||||
|
@ -176,7 +190,7 @@ public class ResourceServerService {
|
|||
@Path("/permission")
|
||||
public Object getPermissionTypeResource() {
|
||||
this.auth.requireView();
|
||||
PermissionService resource = new PermissionService(this.resourceServer, this.authorization, this.auth);
|
||||
PermissionService resource = new PermissionService(this.resourceServer, this.authorization, this.auth, adminEvent);
|
||||
|
||||
ResteasyProviderFactory.getInstance().injectProperties(resource);
|
||||
|
||||
|
@ -239,4 +253,14 @@ public class ResourceServerService {
|
|||
serviceAccount.grantRole(umaProtectionRole);
|
||||
}
|
||||
}
|
||||
|
||||
private void audit(OperationType operation, UriInfo uriInfo, boolean newClient) {
|
||||
if (newClient) {
|
||||
adminEvent.resource(ResourceType.AUTHORIZATION_RESOURCE_SERVER).operation(operation).resourcePath(uriInfo, client.getId())
|
||||
.representation(ModelToRepresentation.toRepresentation(resourceServer, client)).success();
|
||||
} else {
|
||||
adminEvent.resource(ResourceType.AUTHORIZATION_RESOURCE_SERVER).operation(operation).resourcePath(uriInfo)
|
||||
.representation(ModelToRepresentation.toRepresentation(resourceServer, client)).success();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,8 @@ import org.keycloak.authorization.model.Scope;
|
|||
import org.keycloak.authorization.store.PolicyStore;
|
||||
import org.keycloak.authorization.store.ResourceStore;
|
||||
import org.keycloak.authorization.store.StoreFactory;
|
||||
import org.keycloak.events.admin.OperationType;
|
||||
import org.keycloak.events.admin.ResourceType;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.Constants;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
|
@ -37,6 +39,7 @@ import org.keycloak.representations.idm.authorization.ResourceOwnerRepresentatio
|
|||
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
|
||||
import org.keycloak.representations.idm.authorization.ScopeRepresentation;
|
||||
import org.keycloak.services.ErrorResponse;
|
||||
import org.keycloak.services.resources.admin.AdminEventBuilder;
|
||||
import org.keycloak.services.resources.admin.RealmAuth;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
|
@ -48,8 +51,10 @@ 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.Context;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.Response.Status;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
@ -70,17 +75,25 @@ public class ResourceSetService {
|
|||
|
||||
private final AuthorizationProvider authorization;
|
||||
private final RealmAuth auth;
|
||||
private final AdminEventBuilder adminEvent;
|
||||
private ResourceServer resourceServer;
|
||||
|
||||
public ResourceSetService(ResourceServer resourceServer, AuthorizationProvider authorization, RealmAuth auth) {
|
||||
public ResourceSetService(ResourceServer resourceServer, AuthorizationProvider authorization, RealmAuth auth, AdminEventBuilder adminEvent) {
|
||||
this.resourceServer = resourceServer;
|
||||
this.authorization = authorization;
|
||||
this.auth = auth;
|
||||
this.adminEvent = adminEvent.resource(ResourceType.AUTHORIZATION_RESOURCE);
|
||||
}
|
||||
|
||||
@POST
|
||||
@Consumes("application/json")
|
||||
@Produces("application/json")
|
||||
public Response create(@Context UriInfo uriInfo, ResourceRepresentation resource) {
|
||||
Response response = create(resource);
|
||||
audit(uriInfo, resource, resource.getId(), OperationType.CREATE);
|
||||
return response;
|
||||
}
|
||||
|
||||
public Response create(ResourceRepresentation resource) {
|
||||
requireManage();
|
||||
StoreFactory storeFactory = this.authorization.getStoreFactory();
|
||||
|
@ -128,7 +141,7 @@ public class ResourceSetService {
|
|||
@PUT
|
||||
@Consumes("application/json")
|
||||
@Produces("application/json")
|
||||
public Response update(@PathParam("id") String id, ResourceRepresentation resource) {
|
||||
public Response update(@Context UriInfo uriInfo, @PathParam("id") String id, ResourceRepresentation resource) {
|
||||
requireManage();
|
||||
resource.setId(id);
|
||||
StoreFactory storeFactory = this.authorization.getStoreFactory();
|
||||
|
@ -141,12 +154,14 @@ public class ResourceSetService {
|
|||
|
||||
toModel(resource, resourceServer, authorization);
|
||||
|
||||
audit(uriInfo, resource, OperationType.UPDATE);
|
||||
|
||||
return Response.noContent().build();
|
||||
}
|
||||
|
||||
@Path("{id}")
|
||||
@DELETE
|
||||
public Response delete(@PathParam("id") String id) {
|
||||
public Response delete(@Context UriInfo uriInfo, @PathParam("id") String id) {
|
||||
requireManage();
|
||||
StoreFactory storeFactory = authorization.getStoreFactory();
|
||||
Resource resource = storeFactory.getResourceStore().findById(id, resourceServer.getId());
|
||||
|
@ -168,6 +183,10 @@ public class ResourceSetService {
|
|||
|
||||
storeFactory.getResourceStore().delete(id);
|
||||
|
||||
if (authorization.getRealm().isAdminEventsEnabled()) {
|
||||
audit(uriInfo, toRepresentation(resource, resourceServer, authorization), OperationType.DELETE);
|
||||
}
|
||||
|
||||
return Response.noContent().build();
|
||||
}
|
||||
|
||||
|
@ -376,4 +395,18 @@ public class ResourceSetService {
|
|||
this.auth.requireManage();
|
||||
}
|
||||
}
|
||||
|
||||
private void audit(@Context UriInfo uriInfo, ResourceRepresentation resource, OperationType operation) {
|
||||
audit(uriInfo, resource, null, operation);
|
||||
}
|
||||
|
||||
private void audit(@Context UriInfo uriInfo, ResourceRepresentation resource, String id, OperationType operation) {
|
||||
if (authorization.getRealm().isAdminEventsEnabled()) {
|
||||
if (id != null) {
|
||||
adminEvent.operation(operation).resourcePath(uriInfo, id).representation(resource).success();
|
||||
} else {
|
||||
adminEvent.operation(operation).resourcePath(uriInfo).representation(resource).success();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -25,11 +25,14 @@ import org.keycloak.authorization.model.ResourceServer;
|
|||
import org.keycloak.authorization.model.Scope;
|
||||
import org.keycloak.authorization.store.PolicyStore;
|
||||
import org.keycloak.authorization.store.StoreFactory;
|
||||
import org.keycloak.events.admin.OperationType;
|
||||
import org.keycloak.events.admin.ResourceType;
|
||||
import org.keycloak.models.Constants;
|
||||
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
|
||||
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
|
||||
import org.keycloak.representations.idm.authorization.ScopeRepresentation;
|
||||
import org.keycloak.services.ErrorResponse;
|
||||
import org.keycloak.services.resources.admin.AdminEventBuilder;
|
||||
import org.keycloak.services.resources.admin.RealmAuth;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
|
@ -41,9 +44,11 @@ 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.Context;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.Response.Status;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
|
@ -61,23 +66,27 @@ public class ScopeService {
|
|||
|
||||
private final AuthorizationProvider authorization;
|
||||
private final RealmAuth auth;
|
||||
private final AdminEventBuilder adminEvent;
|
||||
private ResourceServer resourceServer;
|
||||
|
||||
public ScopeService(ResourceServer resourceServer, AuthorizationProvider authorization, RealmAuth auth) {
|
||||
public ScopeService(ResourceServer resourceServer, AuthorizationProvider authorization, RealmAuth auth, AdminEventBuilder adminEvent) {
|
||||
this.resourceServer = resourceServer;
|
||||
this.authorization = authorization;
|
||||
this.auth = auth;
|
||||
this.adminEvent = adminEvent.resource(ResourceType.AUTHORIZATION_SCOPE);
|
||||
}
|
||||
|
||||
@POST
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Response create(ScopeRepresentation scope) {
|
||||
public Response create(@Context UriInfo uriInfo, ScopeRepresentation scope) {
|
||||
this.auth.requireManage();
|
||||
Scope model = toModel(scope, this.resourceServer, authorization);
|
||||
|
||||
scope.setId(model.getId());
|
||||
|
||||
audit(uriInfo, scope, scope.getId(), OperationType.CREATE);
|
||||
|
||||
return Response.status(Status.CREATED).entity(scope).build();
|
||||
}
|
||||
|
||||
|
@ -85,7 +94,7 @@ public class ScopeService {
|
|||
@PUT
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Response update(@PathParam("id") String id, ScopeRepresentation scope) {
|
||||
public Response update(@Context UriInfo uriInfo, @PathParam("id") String id, ScopeRepresentation scope) {
|
||||
this.auth.requireManage();
|
||||
scope.setId(id);
|
||||
StoreFactory storeFactory = authorization.getStoreFactory();
|
||||
|
@ -97,12 +106,14 @@ public class ScopeService {
|
|||
|
||||
toModel(scope, resourceServer, authorization);
|
||||
|
||||
audit(uriInfo, scope, OperationType.UPDATE);
|
||||
|
||||
return Response.noContent().build();
|
||||
}
|
||||
|
||||
@Path("{id}")
|
||||
@DELETE
|
||||
public Response delete(@PathParam("id") String id) {
|
||||
public Response delete(@Context UriInfo uriInfo, @PathParam("id") String id) {
|
||||
this.auth.requireManage();
|
||||
StoreFactory storeFactory = authorization.getStoreFactory();
|
||||
List<Resource> resources = storeFactory.getResourceStore().findByScope(Arrays.asList(id), resourceServer.getId());
|
||||
|
@ -130,6 +141,10 @@ public class ScopeService {
|
|||
|
||||
storeFactory.getScopeStore().delete(id);
|
||||
|
||||
if (authorization.getRealm().isAdminEventsEnabled()) {
|
||||
audit(uriInfo, toRepresentation(scope), OperationType.DELETE);
|
||||
}
|
||||
|
||||
return Response.noContent().build();
|
||||
}
|
||||
|
||||
|
@ -144,7 +159,7 @@ public class ScopeService {
|
|||
return Response.status(Status.NOT_FOUND).build();
|
||||
}
|
||||
|
||||
return Response.ok(toRepresentation(model, this.authorization)).build();
|
||||
return Response.ok(toRepresentation(model)).build();
|
||||
}
|
||||
|
||||
@Path("{id}/resources")
|
||||
|
@ -212,22 +227,17 @@ public class ScopeService {
|
|||
return Response.status(Status.OK).build();
|
||||
}
|
||||
|
||||
return Response.ok(toRepresentation(model, authorization)).build();
|
||||
return Response.ok(toRepresentation(model)).build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Produces("application/json")
|
||||
public Response findAll(@QueryParam("scopeId") String id,
|
||||
@QueryParam("name") String name,
|
||||
@QueryParam("deep") Boolean deep,
|
||||
@QueryParam("first") Integer firstResult,
|
||||
@QueryParam("max") Integer maxResult) {
|
||||
this.auth.requireView();
|
||||
|
||||
if (deep == null) {
|
||||
deep = true;
|
||||
}
|
||||
|
||||
Map<String, String[]> search = new HashMap<>();
|
||||
|
||||
if (id != null && !"".equals(id.trim())) {
|
||||
|
@ -238,11 +248,24 @@ public class ScopeService {
|
|||
search.put("name", new String[] {name});
|
||||
}
|
||||
|
||||
Boolean finalDeep = deep;
|
||||
return Response.ok(
|
||||
this.authorization.getStoreFactory().getScopeStore().findByResourceServer(search, this.resourceServer.getId(), firstResult != null ? firstResult : -1, maxResult != null ? maxResult : Constants.DEFAULT_MAX_RESULTS).stream()
|
||||
.map(scope -> toRepresentation(scope, this.authorization, finalDeep))
|
||||
.map(scope -> toRepresentation(scope))
|
||||
.collect(Collectors.toList()))
|
||||
.build();
|
||||
}
|
||||
|
||||
private void audit(@Context UriInfo uriInfo, ScopeRepresentation resource, OperationType operation) {
|
||||
audit(uriInfo, resource, null, operation);
|
||||
}
|
||||
|
||||
private void audit(@Context UriInfo uriInfo, ScopeRepresentation resource, String id, OperationType operation) {
|
||||
if (authorization.getRealm().isAdminEventsEnabled()) {
|
||||
if (id != null) {
|
||||
adminEvent.operation(operation).resourcePath(uriInfo, id).representation(resource).success();
|
||||
} else {
|
||||
adminEvent.operation(operation).resourcePath(uriInfo).representation(resource).success();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,12 +27,17 @@ import org.keycloak.authorization.model.ResourceServer;
|
|||
import org.keycloak.authorization.protection.permission.PermissionService;
|
||||
import org.keycloak.authorization.protection.permission.PermissionsService;
|
||||
import org.keycloak.authorization.protection.resource.ResourceService;
|
||||
import org.keycloak.common.ClientConnection;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.services.ErrorResponseException;
|
||||
import org.keycloak.services.resources.admin.AdminAuth;
|
||||
import org.keycloak.services.resources.admin.AdminEventBuilder;
|
||||
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.Response.Status;
|
||||
|
||||
/**
|
||||
|
@ -41,6 +46,8 @@ import javax.ws.rs.core.Response.Status;
|
|||
public class ProtectionService {
|
||||
|
||||
private final AuthorizationProvider authorization;
|
||||
@Context
|
||||
protected ClientConnection clientConnection;
|
||||
|
||||
public ProtectionService(AuthorizationProvider authorization) {
|
||||
this.authorization = authorization;
|
||||
|
@ -50,7 +57,12 @@ public class ProtectionService {
|
|||
public Object resource() {
|
||||
KeycloakIdentity identity = createIdentity();
|
||||
ResourceServer resourceServer = getResourceServer(identity);
|
||||
ResourceSetService resourceManager = new ResourceSetService(resourceServer, this.authorization, null);
|
||||
RealmModel realm = authorization.getRealm();
|
||||
ClientModel client = realm.getClientById(identity.getId());
|
||||
KeycloakSession keycloakSession = authorization.getKeycloakSession();
|
||||
UserModel serviceAccount = keycloakSession.users().getServiceAccount(client);
|
||||
AdminEventBuilder adminEvent = new AdminEventBuilder(realm, new AdminAuth(realm, identity.getAccessToken(), serviceAccount, client), keycloakSession, clientConnection);
|
||||
ResourceSetService resourceManager = new ResourceSetService(resourceServer, this.authorization, null, adminEvent.realm(realm).authClient(client).authUser(serviceAccount));
|
||||
|
||||
ResteasyProviderFactory.getInstance().injectProperties(resourceManager);
|
||||
|
||||
|
|
|
@ -31,8 +31,10 @@ 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.Context;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.Response.Status;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
|
||||
import org.keycloak.authorization.AuthorizationProvider;
|
||||
import org.keycloak.authorization.admin.ResourceSetService;
|
||||
|
@ -68,10 +70,10 @@ public class ResourceService {
|
|||
@POST
|
||||
@Consumes("application/json")
|
||||
@Produces("application/json")
|
||||
public Response create(UmaResourceRepresentation umaResource) {
|
||||
public Response create(@Context UriInfo uriInfo, UmaResourceRepresentation umaResource) {
|
||||
checkResourceServerSettings();
|
||||
ResourceRepresentation resource = toResourceRepresentation(umaResource);
|
||||
Response response = this.resourceManager.create(resource);
|
||||
Response response = this.resourceManager.create(uriInfo, resource);
|
||||
|
||||
if (response.getEntity() instanceof ResourceRepresentation) {
|
||||
return Response.status(Status.CREATED).entity(toUmaRepresentation((ResourceRepresentation) response.getEntity())).build();
|
||||
|
@ -84,9 +86,9 @@ public class ResourceService {
|
|||
@PUT
|
||||
@Consumes("application/json")
|
||||
@Produces("application/json")
|
||||
public Response update(@PathParam("id") String id, UmaResourceRepresentation representation) {
|
||||
public Response update(@Context UriInfo uriInfo, @PathParam("id") String id, UmaResourceRepresentation representation) {
|
||||
ResourceRepresentation resource = toResourceRepresentation(representation);
|
||||
Response response = this.resourceManager.update(id, resource);
|
||||
Response response = this.resourceManager.update(uriInfo, id, resource);
|
||||
|
||||
if (response.getEntity() instanceof ResourceRepresentation) {
|
||||
return Response.noContent().build();
|
||||
|
@ -97,9 +99,9 @@ public class ResourceService {
|
|||
|
||||
@Path("/{id}")
|
||||
@DELETE
|
||||
public Response delete(@PathParam("id") String id) {
|
||||
public Response delete(@Context UriInfo uriInfo, @PathParam("id") String id) {
|
||||
checkResourceServerSettings();
|
||||
return this.resourceManager.delete(id);
|
||||
return this.resourceManager.delete(uriInfo, id);
|
||||
}
|
||||
|
||||
@Path("/{id}")
|
||||
|
|
|
@ -343,7 +343,7 @@ public class ExportUtils {
|
|||
representation.setPolicies(policies);
|
||||
|
||||
List<ScopeRepresentation> scopes = storeFactory.getScopeStore().findByResourceServer(settingsModel.getId()).stream().map(scope -> {
|
||||
ScopeRepresentation rep = toRepresentation(scope, authorization);
|
||||
ScopeRepresentation rep = toRepresentation(scope);
|
||||
|
||||
rep.setId(null);
|
||||
rep.setPolicies(null);
|
||||
|
|
|
@ -151,7 +151,7 @@ public class KeycloakOIDCClientInstallation implements ClientInstallationProvide
|
|||
}
|
||||
|
||||
private void configureAuthorizationSettings(KeycloakSession session, ClientModel client, ClientManager.InstallationAdapterConfig rep) {
|
||||
if (new AuthorizationService(session, client, null).isEnabled()) {
|
||||
if (new AuthorizationService(session, client, null, null).isEnabled()) {
|
||||
PolicyEnforcerConfig enforcerConfig = new PolicyEnforcerConfig();
|
||||
|
||||
enforcerConfig.setEnforcementMode(null);
|
||||
|
|
|
@ -148,36 +148,13 @@ public class ClientResource {
|
|||
try {
|
||||
updateClientFromRep(rep, client, session);
|
||||
adminEvent.operation(OperationType.UPDATE).resourcePath(uriInfo).representation(rep).success();
|
||||
updateAuthorizationSettings(rep);
|
||||
return Response.noContent().build();
|
||||
} catch (ModelDuplicateException e) {
|
||||
return ErrorResponse.exists("Client " + rep.getClientId() + " already exists");
|
||||
}
|
||||
}
|
||||
|
||||
public void updateClientFromRep(ClientRepresentation rep, ClientModel client, KeycloakSession session) throws ModelDuplicateException {
|
||||
if (TRUE.equals(rep.isServiceAccountsEnabled())) {
|
||||
UserModel serviceAccount = this.session.users().getServiceAccount(client);
|
||||
|
||||
if (serviceAccount == null) {
|
||||
new ClientManager(new RealmManager(session)).enableServiceAccount(client);
|
||||
}
|
||||
}
|
||||
|
||||
if (!rep.getClientId().equals(client.getClientId())) {
|
||||
new ClientManager(new RealmManager(session)).clientIdChanged(client, rep.getClientId());
|
||||
}
|
||||
|
||||
RepresentationToModel.updateClient(rep, client);
|
||||
|
||||
if (Profile.isFeatureEnabled(Profile.Feature.AUTHORIZATION)) {
|
||||
if (TRUE.equals(rep.getAuthorizationServicesEnabled())) {
|
||||
authorization().enable();
|
||||
} else {
|
||||
authorization().disable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get representation of the client
|
||||
*
|
||||
|
@ -587,10 +564,36 @@ public class ClientResource {
|
|||
public AuthorizationService authorization() {
|
||||
ProfileHelper.requireFeature(Profile.Feature.AUTHORIZATION);
|
||||
|
||||
AuthorizationService resource = new AuthorizationService(this.session, this.client, this.auth);
|
||||
AuthorizationService resource = new AuthorizationService(this.session, this.client, this.auth, adminEvent);
|
||||
|
||||
ResteasyProviderFactory.getInstance().injectProperties(resource);
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
private void updateClientFromRep(ClientRepresentation rep, ClientModel client, KeycloakSession session) throws ModelDuplicateException {
|
||||
if (TRUE.equals(rep.isServiceAccountsEnabled())) {
|
||||
UserModel serviceAccount = this.session.users().getServiceAccount(client);
|
||||
|
||||
if (serviceAccount == null) {
|
||||
new ClientManager(new RealmManager(session)).enableServiceAccount(client);
|
||||
}
|
||||
}
|
||||
|
||||
if (!rep.getClientId().equals(client.getClientId())) {
|
||||
new ClientManager(new RealmManager(session)).clientIdChanged(client, rep.getClientId());
|
||||
}
|
||||
|
||||
RepresentationToModel.updateClient(rep, client);
|
||||
}
|
||||
|
||||
private void updateAuthorizationSettings(ClientRepresentation rep) {
|
||||
if (Profile.isFeatureEnabled(Profile.Feature.AUTHORIZATION)) {
|
||||
if (TRUE.equals(rep.getAuthorizationServicesEnabled())) {
|
||||
authorization().enable(false);
|
||||
} else {
|
||||
authorization().disable();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -129,7 +129,7 @@ public class ClientsResource {
|
|||
}
|
||||
|
||||
private AuthorizationService getAuthorizationService(ClientModel clientModel) {
|
||||
return new AuthorizationService(session, clientModel, auth);
|
||||
return new AuthorizationService(session, clientModel, auth, adminEvent);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -167,14 +167,14 @@ public class ClientsResource {
|
|||
}
|
||||
}
|
||||
|
||||
adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo, clientModel.getId()).representation(rep).success();
|
||||
|
||||
if (Profile.isFeatureEnabled(Profile.Feature.AUTHORIZATION)) {
|
||||
if (TRUE.equals(rep.getAuthorizationServicesEnabled())) {
|
||||
getAuthorizationService(clientModel).enable();
|
||||
getAuthorizationService(clientModel).enable(true);
|
||||
}
|
||||
}
|
||||
|
||||
adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo, clientModel.getId()).representation(rep).success();
|
||||
|
||||
return Response.created(uriInfo.getAbsolutePathBuilder().path(clientModel.getId()).build()).build();
|
||||
} catch (ModelDuplicateException e) {
|
||||
return ErrorResponse.exists("Client " + rep.getClientId() + " already exists");
|
||||
|
|
|
@ -107,7 +107,9 @@ public abstract class AbstractClientTest extends AbstractAuthTest {
|
|||
clientRep.setPublicClient(Boolean.FALSE);
|
||||
clientRep.setAuthorizationServicesEnabled(Boolean.TRUE);
|
||||
clientRep.setServiceAccountsEnabled(Boolean.TRUE);
|
||||
return createClient(clientRep);
|
||||
String id = createClient(clientRep);
|
||||
assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientResourcePath(id), ResourceType.AUTHORIZATION_RESOURCE_SERVER);
|
||||
return id;
|
||||
}
|
||||
|
||||
protected ClientRepresentation createOidcClientRep(String name) {
|
||||
|
|
Loading…
Reference in a new issue