KEYCLOAK-4858: Slow query performance for client with large data volume

- Changing RESOURCE_SERVER PK to the client ID.
- Changing FK on children of RESOURCE_SERVER.
- Use direct fetch of ResourceServer through ID/PK to avoid a lot of implicit Hibernate flush.
This commit is contained in:
Gabriel Lavoie 2017-09-01 15:05:12 -04:00 committed by Pedro Igor
parent 1fb8846a7a
commit c1664478d9
44 changed files with 154 additions and 195 deletions

View file

@ -108,7 +108,7 @@ public class ClientPolicyProviderFactory implements PolicyProviderFactory<Client
PolicyStore policyStore = storeFactory.getPolicyStore(); PolicyStore policyStore = storeFactory.getPolicyStore();
ClientModel removedClient = ((ClientRemovedEvent) event).getClient(); ClientModel removedClient = ((ClientRemovedEvent) event).getClient();
ResourceServerStore resourceServerStore = storeFactory.getResourceServerStore(); ResourceServerStore resourceServerStore = storeFactory.getResourceServerStore();
ResourceServer resourceServer = resourceServerStore.findByClient(removedClient.getId()); ResourceServer resourceServer = resourceServerStore.findById(removedClient.getId());
if (resourceServer != null) { if (resourceServer != null) {
policyStore.findByType(getId(), resourceServer.getId()).forEach(policy -> { policyStore.findByType(getId(), resourceServer.getId()).forEach(policy -> {

View file

@ -222,7 +222,7 @@ public class RolePolicyProviderFactory implements PolicyProviderFactory<RolePoli
} }
private void updateResourceServer(ClientModel clientModel, RoleModel removedRole, ResourceServerStore resourceServerStore, PolicyStore policyStore) { private void updateResourceServer(ClientModel clientModel, RoleModel removedRole, ResourceServerStore resourceServerStore, PolicyStore policyStore) {
ResourceServer resourceServer = resourceServerStore.findByClient(clientModel.getId()); ResourceServer resourceServer = resourceServerStore.findById(clientModel.getId());
if (resourceServer != null) { if (resourceServer != null) {
policyStore.findByType(getId(), resourceServer.getId()).forEach(policy -> { policyStore.findByType(getId(), resourceServer.getId()).forEach(policy -> {

View file

@ -181,7 +181,7 @@ public class UserPolicyProviderFactory implements PolicyProviderFactory<UserPoli
RealmModel realm = ((UserRemovedEvent) event).getRealm(); RealmModel realm = ((UserRemovedEvent) event).getRealm();
ResourceServerStore resourceServerStore = storeFactory.getResourceServerStore(); ResourceServerStore resourceServerStore = storeFactory.getResourceServerStore();
realm.getClients().forEach(clientModel -> { realm.getClients().forEach(clientModel -> {
ResourceServer resourceServer = resourceServerStore.findByClient(clientModel.getId()); ResourceServer resourceServer = resourceServerStore.findById(clientModel.getId());
if (resourceServer != null) { if (resourceServer != null) {
policyStore.findByType(getId(), resourceServer.getId()).forEach(policy -> { policyStore.findByType(getId(), resourceServer.getId()).forEach(policy -> {

View file

@ -38,7 +38,7 @@ public class ResourceServerAdapter implements ResourceServer, CachedModel<Resour
@Override @Override
public ResourceServer getDelegateForUpdate() { public ResourceServer getDelegateForUpdate() {
if (updated == null) { if (updated == null) {
cacheSession.registerResourceServerInvalidation(cached.getId(), cached.getClientId()); cacheSession.registerResourceServerInvalidation(cached.getId());
updated = cacheSession.getResourceServerStoreDelegate().findById(cached.getId()); updated = cacheSession.getResourceServerStoreDelegate().findById(cached.getId());
if (updated == null) throw new IllegalStateException("Not found in database"); if (updated == null) throw new IllegalStateException("Not found in database");
} }
@ -78,12 +78,6 @@ public class ResourceServerAdapter implements ResourceServer, CachedModel<Resour
return cached.getId(); return cached.getId();
} }
@Override
public String getClientId() {
if (isUpdated()) return updated.getClientId();
return cached.getClientId();
}
@Override @Override
public boolean isAllowRemoteResourceManagement() { public boolean isAllowRemoteResourceManagement() {
if (isUpdated()) return updated.isAllowRemoteResourceManagement(); if (isUpdated()) return updated.isAllowRemoteResourceManagement();

View file

@ -53,13 +53,13 @@ public class StoreFactoryCacheManager extends CacheManager {
} }
} }
public void resourceServerUpdated(String id, String clientId, Set<String> invalidations) { public void resourceServerUpdated(String id, Set<String> invalidations) {
invalidations.add(id); invalidations.add(id);
invalidations.add(StoreFactoryCacheSession.getResourceServerByClientCacheKey(clientId)); invalidations.add(StoreFactoryCacheSession.getResourceServerByClientCacheKey(id));
} }
public void resourceServerRemoval(String id, String name, Set<String> invalidations) { public void resourceServerRemoval(String id, Set<String> invalidations) {
resourceServerUpdated(id, name, invalidations); resourceServerUpdated(id, invalidations);
addInvalidations(InResourceServerPredicate.create().resourceServer(id), invalidations); addInvalidations(InResourceServerPredicate.create().resourceServer(id), invalidations);
} }

View file

@ -229,12 +229,12 @@ public class StoreFactoryCacheSession implements CachedStoreFactoryProvider {
return invalidations.contains(id); return invalidations.contains(id);
} }
public void registerResourceServerInvalidation(String id, String clientId) { public void registerResourceServerInvalidation(String id) {
cache.resourceServerUpdated(id, clientId, invalidations); cache.resourceServerUpdated(id, invalidations);
ResourceServerAdapter adapter = managedResourceServers.get(id); ResourceServerAdapter adapter = managedResourceServers.get(id);
if (adapter != null) adapter.invalidateFlag(); if (adapter != null) adapter.invalidateFlag();
invalidationEvents.add(ResourceServerUpdatedEvent.create(id, clientId)); invalidationEvents.add(ResourceServerUpdatedEvent.create(id));
} }
public void registerScopeInvalidation(String id, String name, String serverId) { public void registerScopeInvalidation(String id, String name, String serverId) {
@ -350,7 +350,7 @@ public class StoreFactoryCacheSession implements CachedStoreFactoryProvider {
@Override @Override
public ResourceServer create(String clientId) { public ResourceServer create(String clientId) {
ResourceServer server = getResourceServerStoreDelegate().create(clientId); ResourceServer server = getResourceServerStoreDelegate().create(clientId);
registerResourceServerInvalidation(server.getId(), server.getClientId()); registerResourceServerInvalidation(server.getId());
return server; return server;
} }
@ -361,8 +361,8 @@ public class StoreFactoryCacheSession implements CachedStoreFactoryProvider {
if (server == null) return; if (server == null) return;
cache.invalidateObject(id); cache.invalidateObject(id);
invalidationEvents.add(ResourceServerRemovedEvent.create(id, server.getClientId())); invalidationEvents.add(ResourceServerRemovedEvent.create(id, server.getId()));
cache.resourceServerRemoval(id, server.getClientId(), invalidations); cache.resourceServerRemoval(id, invalidations);
getResourceServerStoreDelegate().delete(id); getResourceServerStoreDelegate().delete(id);
} }
@ -392,33 +392,6 @@ public class StoreFactoryCacheSession implements CachedStoreFactoryProvider {
managedResourceServers.put(id, adapter); managedResourceServers.put(id, adapter);
return adapter; return adapter;
} }
@Override
public ResourceServer findByClient(String clientId) {
String cacheKey = getResourceServerByClientCacheKey(clientId);
ResourceServerListQuery query = cache.get(cacheKey, ResourceServerListQuery.class);
if (query != null) {
logger.tracev("ResourceServer by clientId cache hit: {0}", clientId);
}
if (query == null) {
Long loaded = cache.getCurrentRevision(cacheKey);
ResourceServer model = getResourceServerStoreDelegate().findByClient(clientId);
if (model == null) return null;
if (invalidations.contains(model.getId())) return model;
query = new ResourceServerListQuery(loaded, cacheKey, model.getId());
cache.addRevisioned(query, startupRevision);
return model;
} else if (invalidations.contains(cacheKey)) {
return getResourceServerStoreDelegate().findByClient(clientId);
} else {
String serverId = query.getResourceServers().iterator().next();
if (invalidations.contains(serverId)) {
return getResourceServerStoreDelegate().findByClient(clientId);
}
return findById(serverId);
}
}
} }
protected class ScopeCache implements ScopeStore { protected class ScopeCache implements ScopeStore {

View file

@ -22,29 +22,20 @@ import org.keycloak.authorization.model.ResourceServer;
import org.keycloak.models.cache.infinispan.entities.AbstractRevisioned; import org.keycloak.models.cache.infinispan.entities.AbstractRevisioned;
import org.keycloak.representations.idm.authorization.PolicyEnforcementMode; import org.keycloak.representations.idm.authorization.PolicyEnforcementMode;
import java.io.Serializable;
/** /**
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a> * @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
*/ */
public class CachedResourceServer extends AbstractRevisioned { public class CachedResourceServer extends AbstractRevisioned {
private String clientId;
private boolean allowRemoteResourceManagement; private boolean allowRemoteResourceManagement;
private PolicyEnforcementMode policyEnforcementMode; private PolicyEnforcementMode policyEnforcementMode;
public CachedResourceServer(Long revision, ResourceServer resourceServer) { public CachedResourceServer(Long revision, ResourceServer resourceServer) {
super(revision, resourceServer.getId()); super(revision, resourceServer.getId());
this.clientId = resourceServer.getClientId();
this.allowRemoteResourceManagement = resourceServer.isAllowRemoteResourceManagement(); this.allowRemoteResourceManagement = resourceServer.isAllowRemoteResourceManagement();
this.policyEnforcementMode = resourceServer.getPolicyEnforcementMode(); this.policyEnforcementMode = resourceServer.getPolicyEnforcementMode();
} }
public String getClientId() {
return this.clientId;
}
public boolean isAllowRemoteResourceManagement() { public boolean isAllowRemoteResourceManagement() {
return this.allowRemoteResourceManagement; return this.allowRemoteResourceManagement;
} }

View file

@ -49,6 +49,6 @@ public class ResourceServerRemovedEvent extends InvalidationEvent implements Aut
@Override @Override
public void addInvalidations(StoreFactoryCacheManager cache, Set<String> invalidations) { public void addInvalidations(StoreFactoryCacheManager cache, Set<String> invalidations) {
cache.resourceServerRemoval(id, clientId, invalidations); cache.resourceServerRemoval(id, invalidations);
} }
} }

View file

@ -28,12 +28,10 @@ import java.util.Set;
public class ResourceServerUpdatedEvent extends InvalidationEvent implements AuthorizationCacheInvalidationEvent { public class ResourceServerUpdatedEvent extends InvalidationEvent implements AuthorizationCacheInvalidationEvent {
private String id; private String id;
private String clientId;
public static ResourceServerUpdatedEvent create(String id, String clientId) { public static ResourceServerUpdatedEvent create(String id) {
ResourceServerUpdatedEvent event = new ResourceServerUpdatedEvent(); ResourceServerUpdatedEvent event = new ResourceServerUpdatedEvent();
event.id = id; event.id = id;
event.clientId = clientId;
return event; return event;
} }
@ -44,11 +42,11 @@ public class ResourceServerUpdatedEvent extends InvalidationEvent implements Aut
@Override @Override
public String toString() { public String toString() {
return String.format("ResourceServerRemovedEvent [ id=%s, clientId=%s ]", id, clientId); return String.format("ResourceServerRemovedEvent [ id=%s, clientId=%s ]", id, id);
} }
@Override @Override
public void addInvalidations(StoreFactoryCacheManager cache, Set<String> invalidations) { public void addInvalidations(StoreFactoryCacheManager cache, Set<String> invalidations) {
cache.resourceServerUpdated(id, clientId, invalidations); cache.resourceServerUpdated(id, invalidations);
} }
} }

View file

@ -18,41 +18,24 @@
package org.keycloak.authorization.jpa.entities; package org.keycloak.authorization.jpa.entities;
import org.keycloak.authorization.model.ResourceServer;
import org.keycloak.representations.idm.authorization.PolicyEnforcementMode; import org.keycloak.representations.idm.authorization.PolicyEnforcementMode;
import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.Id; import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table; import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import java.util.List;
/** /**
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a> * @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
*/ */
@Entity @Entity
@Table(name = "RESOURCE_SERVER", uniqueConstraints = {@UniqueConstraint(columnNames = "CLIENT_ID")}) @Table(name = "RESOURCE_SERVER")
@NamedQueries(
{
@NamedQuery(name="findResourceServerIdByClient", query="select r.id from ResourceServerEntity r where r.clientId = :clientId"),
}
)
public class ResourceServerEntity { public class ResourceServerEntity {
@Id @Id
@Column(name="ID", length = 36) @Column(name="ID", length = 36)
@Access(AccessType.PROPERTY) // we do this because relationships often fetch id, but not entity. This avoids an extra SQL
private String id; private String id;
@Column(name = "CLIENT_ID")
private String clientId;
@Column(name = "ALLOW_RS_REMOTE_MGMT") @Column(name = "ALLOW_RS_REMOTE_MGMT")
private boolean allowRemoteResourceManagement; private boolean allowRemoteResourceManagement;
@ -67,14 +50,6 @@ public class ResourceServerEntity {
this.id = id; this.id = id;
} }
public String getClientId() {
return this.clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public boolean isAllowRemoteResourceManagement() { public boolean isAllowRemoteResourceManagement() {
return this.allowRemoteResourceManagement; return this.allowRemoteResourceManagement;
} }

View file

@ -22,16 +22,11 @@ import org.keycloak.authorization.jpa.entities.PolicyEntity;
import org.keycloak.authorization.jpa.entities.ResourceEntity; import org.keycloak.authorization.jpa.entities.ResourceEntity;
import org.keycloak.authorization.jpa.entities.ResourceServerEntity; import org.keycloak.authorization.jpa.entities.ResourceServerEntity;
import org.keycloak.authorization.jpa.entities.ScopeEntity; import org.keycloak.authorization.jpa.entities.ScopeEntity;
import org.keycloak.authorization.model.Policy;
import org.keycloak.authorization.model.Resource; import org.keycloak.authorization.model.Resource;
import org.keycloak.authorization.model.ResourceServer; import org.keycloak.authorization.model.ResourceServer;
import org.keycloak.authorization.model.Scope;
import org.keycloak.authorization.store.ResourceServerStore; import org.keycloak.authorization.store.ResourceServerStore;
import org.keycloak.models.utils.KeycloakModelUtils;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.Query;
import javax.persistence.TypedQuery; import javax.persistence.TypedQuery;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
@ -53,8 +48,7 @@ public class JPAResourceServerStore implements ResourceServerStore {
public ResourceServer create(String clientId) { public ResourceServer create(String clientId) {
ResourceServerEntity entity = new ResourceServerEntity(); ResourceServerEntity entity = new ResourceServerEntity();
entity.setId(KeycloakModelUtils.generateId()); entity.setId(clientId);
entity.setClientId(clientId);
this.entityManager.persist(entity); this.entityManager.persist(entity);
@ -116,17 +110,4 @@ public class JPAResourceServerStore implements ResourceServerStore {
if (entity == null) return null; if (entity == null) return null;
return new ResourceServerAdapter(entity, entityManager, provider.getStoreFactory()); return new ResourceServerAdapter(entity, entityManager, provider.getStoreFactory());
} }
@Override
public ResourceServer findByClient(final String clientId) {
TypedQuery<String> query = entityManager.createNamedQuery("findResourceServerIdByClient", String.class);
query.setParameter("clientId", clientId);
try {
String id = query.getSingleResult();
return provider.getStoreFactory().getResourceServerStore().findById(id);
} catch (NoResultException ex) {
return null;
}
}
} }

View file

@ -16,7 +16,6 @@
*/ */
package org.keycloak.authorization.jpa.store; package org.keycloak.authorization.jpa.store;
import org.keycloak.authorization.AuthorizationProvider;
import org.keycloak.authorization.jpa.entities.PolicyEntity; import org.keycloak.authorization.jpa.entities.PolicyEntity;
import org.keycloak.authorization.jpa.entities.ResourceEntity; import org.keycloak.authorization.jpa.entities.ResourceEntity;
import org.keycloak.authorization.jpa.entities.ScopeEntity; import org.keycloak.authorization.jpa.entities.ScopeEntity;

View file

@ -16,7 +16,6 @@
*/ */
package org.keycloak.authorization.jpa.store; package org.keycloak.authorization.jpa.store;
import org.keycloak.authorization.AuthorizationProvider;
import org.keycloak.authorization.jpa.entities.ResourceEntity; import org.keycloak.authorization.jpa.entities.ResourceEntity;
import org.keycloak.authorization.jpa.entities.ScopeEntity; import org.keycloak.authorization.jpa.entities.ScopeEntity;
import org.keycloak.authorization.model.Resource; import org.keycloak.authorization.model.Resource;

View file

@ -16,11 +16,7 @@
*/ */
package org.keycloak.authorization.jpa.store; package org.keycloak.authorization.jpa.store;
import org.keycloak.authorization.AuthorizationProvider;
import org.keycloak.authorization.jpa.entities.ResourceEntity;
import org.keycloak.authorization.jpa.entities.ResourceServerEntity; import org.keycloak.authorization.jpa.entities.ResourceServerEntity;
import org.keycloak.authorization.model.Policy;
import org.keycloak.authorization.model.Resource;
import org.keycloak.authorization.model.ResourceServer; import org.keycloak.authorization.model.ResourceServer;
import org.keycloak.authorization.store.StoreFactory; import org.keycloak.authorization.store.StoreFactory;
import org.keycloak.models.jpa.JpaModel; import org.keycloak.models.jpa.JpaModel;
@ -53,11 +49,6 @@ public class ResourceServerAdapter implements ResourceServer, JpaModel<ResourceS
return entity.getId(); return entity.getId();
} }
@Override
public String getClientId() {
return entity.getClientId();
}
@Override @Override
public boolean isAllowRemoteResourceManagement() { public boolean isAllowRemoteResourceManagement() {
return entity.isAllowRemoteResourceManagement(); return entity.isAllowRemoteResourceManagement();

View file

@ -16,12 +16,10 @@
*/ */
package org.keycloak.authorization.jpa.store; package org.keycloak.authorization.jpa.store;
import org.keycloak.authorization.AuthorizationProvider;
import org.keycloak.authorization.jpa.entities.ScopeEntity; import org.keycloak.authorization.jpa.entities.ScopeEntity;
import org.keycloak.authorization.model.ResourceServer; import org.keycloak.authorization.model.ResourceServer;
import org.keycloak.authorization.model.Scope; import org.keycloak.authorization.model.Scope;
import org.keycloak.authorization.store.StoreFactory; import org.keycloak.authorization.store.StoreFactory;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.jpa.JpaModel; import org.keycloak.models.jpa.JpaModel;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;

View file

@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!--
~ Copyright 2017 Red Hat, Inc. and/or its affiliates
~ and other contributors as indicated by the @author tags.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
<changeSet author="keycloak" id="3.4.0-res-server-pk">
<!-- Data migration to change the PK of RESOURCE_SERVER to use the CLIENT_ID. -->
<addColumn tableName="RESOURCE_SERVER_POLICY">
<column name="RESOURCE_SERVER_CLIENT_ID" type="VARCHAR(36)"/>
</addColumn>
<addColumn tableName="RESOURCE_SERVER_RESOURCE">
<column name="RESOURCE_SERVER_CLIENT_ID" type="VARCHAR(36)"/>
</addColumn>
<addColumn tableName="RESOURCE_SERVER_SCOPE">
<column name="RESOURCE_SERVER_CLIENT_ID" type="VARCHAR(36)"/>
</addColumn>
<sql>
UPDATE RESOURCE_SERVER_POLICY p SET RESOURCE_SERVER_CLIENT_ID=(SELECT CLIENT_ID FROM RESOURCE_SERVER s WHERE s.ID = p.RESOURCE_SERVER_ID);
UPDATE RESOURCE_SERVER_RESOURCE p SET RESOURCE_SERVER_CLIENT_ID=(SELECT CLIENT_ID FROM RESOURCE_SERVER s WHERE s.ID = p.RESOURCE_SERVER_ID);
UPDATE RESOURCE_SERVER_SCOPE p SET RESOURCE_SERVER_CLIENT_ID=(SELECT CLIENT_ID FROM RESOURCE_SERVER s WHERE s.ID = p.RESOURCE_SERVER_ID);
</sql>
<addNotNullConstraint tableName="RESOURCE_SERVER_POLICY" columnName="RESOURCE_SERVER_CLIENT_ID" columnDataType="VARCHAR(36)"/>
<addNotNullConstraint tableName="RESOURCE_SERVER_RESOURCE" columnName="RESOURCE_SERVER_CLIENT_ID" columnDataType="VARCHAR(36)"/>
<addNotNullConstraint tableName="RESOURCE_SERVER_SCOPE" columnName="RESOURCE_SERVER_CLIENT_ID" columnDataType="VARCHAR(36)"/>
<dropUniqueConstraint tableName="RESOURCE_SERVER_POLICY" constraintName="UK_FRSRPT700S9V50BU18WS5HA6"/>
<dropUniqueConstraint tableName="RESOURCE_SERVER_RESOURCE" constraintName="UK_FRSR6T700S9V50BU18WS5HA6"/>
<dropUniqueConstraint tableName="RESOURCE_SERVER_SCOPE" constraintName="UK_FRSRST700S9V50BU18WS5HA6"/>
<addUniqueConstraint tableName="RESOURCE_SERVER_POLICY" constraintName="UK_FRSRPT700S9V50BU18WS5HA6"
columnNames="NAME, RESOURCE_SERVER_CLIENT_ID"/>
<addUniqueConstraint tableName="RESOURCE_SERVER_RESOURCE" constraintName="UK_FRSR6T700S9V50BU18WS5HA6"
columnNames="NAME, OWNER, RESOURCE_SERVER_CLIENT_ID"/>
<addUniqueConstraint tableName="RESOURCE_SERVER_SCOPE" constraintName="UK_FRSRST700S9V50BU18WS5HA6"
columnNames="NAME, RESOURCE_SERVER_CLIENT_ID"/>
<dropColumn tableName="RESOURCE_SERVER_POLICY" columnName="RESOURCE_SERVER_ID"/>
<dropColumn tableName="RESOURCE_SERVER_RESOURCE" columnName="RESOURCE_SERVER_ID"/>
<dropColumn tableName="RESOURCE_SERVER_SCOPE" columnName="RESOURCE_SERVER_ID"/>
<dropPrimaryKey tableName="RESOURCE_SERVER" constraintName="CONSTRAINT_FARS"/>
<dropUniqueConstraint tableName="RESOURCE_SERVER" constraintName="UK_AU8TT6T700S9V50BU18WS5HA6"/>
<addPrimaryKey tableName="RESOURCE_SERVER" constraintName="PK_RESOURCE_SERVER" columnNames="CLIENT_ID"/>
<dropColumn tableName="RESOURCE_SERVER" columnName="ID"/>
<createIndex indexName="IDX_RES_SERV_POL_RES_SERV" tableName="RESOURCE_SERVER_POLICY">
<column name="RESOURCE_SERVER_CLIENT_ID" type="VARCHAR(36)"/>
</createIndex>
<createIndex indexName="IDX_RES_SRV_RES_RES_SRV" tableName="RESOURCE_SERVER_RESOURCE">
<column name="RESOURCE_SERVER_CLIENT_ID" type="VARCHAR(36)"/>
</createIndex>
<createIndex indexName="IDX_RES_SRV_SCOPE_RES_SRV" tableName="RESOURCE_SERVER_SCOPE">
<column name="RESOURCE_SERVER_CLIENT_ID" type="VARCHAR(36)"/>
</createIndex>
<addForeignKeyConstraint constraintName="FK_FRSRPO213XCX4WNKOG82SSRFY"
baseTableName="RESOURCE_SERVER_POLICY" baseColumnNames="RESOURCE_SERVER_CLIENT_ID"
referencedTableName="RESOURCE_SERVER" referencedColumnNames="CLIENT_ID"/>
<addForeignKeyConstraint constraintName="FK_FRSRHO213XCX4WNKOG82SSRFY"
baseTableName="RESOURCE_SERVER_RESOURCE" baseColumnNames="RESOURCE_SERVER_CLIENT_ID"
referencedTableName="RESOURCE_SERVER" referencedColumnNames="CLIENT_ID"/>
<addForeignKeyConstraint constraintName="FK_FRSRSO213XCX4WNKOG82SSRFY"
baseTableName="RESOURCE_SERVER_SCOPE" baseColumnNames="RESOURCE_SERVER_CLIENT_ID"
referencedTableName="RESOURCE_SERVER" referencedColumnNames="CLIENT_ID"/>
<renameColumn tableName="RESOURCE_SERVER" oldColumnName="CLIENT_ID" newColumnName="ID"/>
<renameColumn tableName="RESOURCE_SERVER_POLICY" oldColumnName="RESOURCE_SERVER_CLIENT_ID" newColumnName="RESOURCE_SERVER_ID"/>
<renameColumn tableName="RESOURCE_SERVER_RESOURCE" oldColumnName="RESOURCE_SERVER_CLIENT_ID" newColumnName="RESOURCE_SERVER_ID"/>
<renameColumn tableName="RESOURCE_SERVER_SCOPE" oldColumnName="RESOURCE_SERVER_CLIENT_ID" newColumnName="RESOURCE_SERVER_ID"/>
</changeSet>
</databaseChangeLog>

View file

@ -49,4 +49,5 @@
<include file="META-INF/jpa-changelog-3.0.0.xml"/> <include file="META-INF/jpa-changelog-3.0.0.xml"/>
<include file="META-INF/jpa-changelog-3.2.0.xml"/> <include file="META-INF/jpa-changelog-3.2.0.xml"/>
<include file="META-INF/jpa-changelog-3.3.0.xml"/> <include file="META-INF/jpa-changelog-3.3.0.xml"/>
<include file="META-INF/jpa-changelog-3.4.0.xml"/>
</databaseChangeLog> </databaseChangeLog>

View file

@ -35,14 +35,6 @@ public interface ResourceServer {
*/ */
String getId(); String getId();
/**
* Returns the identifier of the client application (which already exists in Keycloak) that is also acting as a resource
* server.
*
* @return the identifier of the client application associated with this instance.
*/
String getClientId();
/** /**
* Indicates if the resource server is allowed to manage its own resources remotely using the Protection API. * Indicates if the resource server is allowed to manage its own resources remotely using the Protection API.
* *

View file

@ -165,7 +165,7 @@ public class DefaultPolicyEvaluator implements PolicyEvaluator {
List<Resource> resourcesByType = resourceStore.findByType(type, resource.getResourceServer().getId()); List<Resource> resourcesByType = resourceStore.findByType(type, resource.getResourceServer().getId());
for (Resource resourceType : resourcesByType) { for (Resource resourceType : resourcesByType) {
if (resourceType.getOwner().equals(resource.getResourceServer().getClientId())) { if (resourceType.getOwner().equals(resource.getResourceServer().getId())) {
resources.add(resourceType); resources.add(resourceType);
} }
} }

View file

@ -51,13 +51,4 @@ public interface ResourceServerStore {
* @return the resource server instance with the given identifier or null if no instance was found * @return the resource server instance with the given identifier or null if no instance was found
*/ */
ResourceServer findById(String id); ResourceServer findById(String id);
/**
* Returns a {@link ResourceServer} instance based on the identifier of a client application.
*
* @param id the identifier of an existing client application
*
* @return the resource server instance, with the given client id or null if no instance was found
*/
ResourceServer findByClient(String id);
} }

View file

@ -37,7 +37,7 @@ public class ClientApplicationSynchronizer implements Synchronizer<ClientRemoved
AuthorizationProvider authorizationProvider = providerFactory.create(event.getKeycloakSession()); AuthorizationProvider authorizationProvider = providerFactory.create(event.getKeycloakSession());
StoreFactory storeFactory = authorizationProvider.getStoreFactory(); StoreFactory storeFactory = authorizationProvider.getStoreFactory();
ResourceServerStore store = storeFactory.getResourceServerStore(); ResourceServerStore store = storeFactory.getResourceServerStore();
ResourceServer resourceServer = store.findByClient(event.getClient().getId()); ResourceServer resourceServer = store.findById(event.getClient().getId());
if (resourceServer != null) { if (resourceServer != null) {
String id = resourceServer.getId(); String id = resourceServer.getId();

View file

@ -36,7 +36,7 @@ public class RealmSynchronizer implements Synchronizer<RealmRemovedEvent> {
StoreFactory storeFactory = authorizationProvider.getStoreFactory(); StoreFactory storeFactory = authorizationProvider.getStoreFactory();
event.getRealm().getClients().forEach(clientModel -> { event.getRealm().getClients().forEach(clientModel -> {
ResourceServer resourceServer = storeFactory.getResourceServerStore().findByClient(clientModel.getId()); ResourceServer resourceServer = storeFactory.getResourceServerStore().findById(clientModel.getId());
if (resourceServer != null) { if (resourceServer != null) {
String id = resourceServer.getId(); String id = resourceServer.getId();

View file

@ -17,8 +17,6 @@
package org.keycloak.authorization.store.syncronization; package org.keycloak.authorization.store.syncronization;
import java.util.function.Consumer;
import org.keycloak.authorization.AuthorizationProvider; import org.keycloak.authorization.AuthorizationProvider;
import org.keycloak.authorization.model.ResourceServer; import org.keycloak.authorization.model.ResourceServer;
import org.keycloak.authorization.store.PolicyStore; import org.keycloak.authorization.store.PolicyStore;
@ -48,7 +46,7 @@ public class UserSynchronizer implements Synchronizer<UserRemovedEvent> {
RealmModel realm = event.getRealm(); RealmModel realm = event.getRealm();
realm.getClients().forEach(clientModel -> { realm.getClients().forEach(clientModel -> {
ResourceServer resourceServer = resourceServerStore.findByClient(clientModel.getId()); ResourceServer resourceServer = resourceServerStore.findById(clientModel.getId());
if (resourceServer != null) { if (resourceServer != null) {
resourceStore.findByOwner(userModel.getId(), resourceServer.getId()).forEach(resource -> { resourceStore.findByOwner(userModel.getId(), resourceServer.getId()).forEach(resource -> {

View file

@ -67,7 +67,7 @@ public class MigrateTo2_1_0 implements Migration {
StoreFactory storeFactory = authorizationProvider.getStoreFactory(); StoreFactory storeFactory = authorizationProvider.getStoreFactory();
PolicyStore policyStore = storeFactory.getPolicyStore(); PolicyStore policyStore = storeFactory.getPolicyStore();
realm.getClients().forEach(clientModel -> { realm.getClients().forEach(clientModel -> {
ResourceServer resourceServer = storeFactory.getResourceServerStore().findByClient(clientModel.getId()); ResourceServer resourceServer = storeFactory.getResourceServerStore().findById(clientModel.getId());
if (resourceServer != null) { if (resourceServer != null) {
policyStore.findByType("role", resourceServer.getId()).forEach(policy -> { policyStore.findByType("role", resourceServer.getId()).forEach(policy -> {

View file

@ -35,7 +35,6 @@ import org.keycloak.authorization.model.ResourceServer;
import org.keycloak.authorization.model.Scope; import org.keycloak.authorization.model.Scope;
import org.keycloak.authorization.policy.provider.PolicyProviderFactory; import org.keycloak.authorization.policy.provider.PolicyProviderFactory;
import org.keycloak.authorization.store.ResourceStore; import org.keycloak.authorization.store.ResourceStore;
import org.keycloak.common.Profile;
import org.keycloak.common.util.MultivaluedHashMap; import org.keycloak.common.util.MultivaluedHashMap;
import org.keycloak.common.util.Time; import org.keycloak.common.util.Time;
import org.keycloak.component.ComponentModel; import org.keycloak.component.ComponentModel;
@ -43,10 +42,10 @@ import org.keycloak.credential.CredentialModel;
import org.keycloak.events.Event; import org.keycloak.events.Event;
import org.keycloak.events.admin.AdminEvent; import org.keycloak.events.admin.AdminEvent;
import org.keycloak.events.admin.AuthDetails; import org.keycloak.events.admin.AuthDetails;
import org.keycloak.models.AuthenticatedClientSessionModel;
import org.keycloak.models.AuthenticationExecutionModel; import org.keycloak.models.AuthenticationExecutionModel;
import org.keycloak.models.AuthenticationFlowModel; import org.keycloak.models.AuthenticationFlowModel;
import org.keycloak.models.AuthenticatorConfigModel; import org.keycloak.models.AuthenticatorConfigModel;
import org.keycloak.models.AuthenticatedClientSessionModel;
import org.keycloak.models.ClientModel; import org.keycloak.models.ClientModel;
import org.keycloak.models.ClientTemplateModel; import org.keycloak.models.ClientTemplateModel;
import org.keycloak.models.FederatedIdentityModel; import org.keycloak.models.FederatedIdentityModel;
@ -789,7 +788,7 @@ public class ModelToRepresentation {
ResourceServerRepresentation server = new ResourceServerRepresentation(); ResourceServerRepresentation server = new ResourceServerRepresentation();
server.setId(model.getId()); server.setId(model.getId());
server.setClientId(model.getClientId()); server.setClientId(model.getId());
server.setName(client.getClientId()); server.setName(client.getClientId());
server.setAllowRemoteResourceManagement(model.isAllowRemoteResourceManagement()); server.setAllowRemoteResourceManagement(model.isAllowRemoteResourceManagement());
server.setPolicyEnforcementMode(model.getPolicyEnforcementMode()); server.setPolicyEnforcementMode(model.getPolicyEnforcementMode());
@ -852,8 +851,8 @@ public class ModelToRepresentation {
KeycloakSession keycloakSession = authorization.getKeycloakSession(); KeycloakSession keycloakSession = authorization.getKeycloakSession();
RealmModel realm = authorization.getRealm(); RealmModel realm = authorization.getRealm();
if (owner.getId().equals(resourceServer.getClientId())) { if (owner.getId().equals(resourceServer.getId())) {
ClientModel clientModel = realm.getClientById(resourceServer.getClientId()); ClientModel clientModel = realm.getClientById(resourceServer.getId());
owner.setName(clientModel.getClientId()); owner.setName(clientModel.getClientId());
} else { } else {
UserModel userModel = keycloakSession.users().getUserById(owner.getId(), realm); UserModel userModel = keycloakSession.users().getUserById(owner.getId(), realm);
@ -882,7 +881,7 @@ public class ModelToRepresentation {
if (resource.getType() != null) { if (resource.getType() != null) {
ResourceStore resourceStore = authorization.getStoreFactory().getResourceStore(); ResourceStore resourceStore = authorization.getStoreFactory().getResourceStore();
for (Resource typed : resourceStore.findByType(resource.getType(), resourceServer.getId())) { for (Resource typed : resourceStore.findByType(resource.getType(), resourceServer.getId())) {
if (typed.getOwner().equals(resourceServer.getClientId()) && !typed.getId().equals(resource.getId())) { if (typed.getOwner().equals(resourceServer.getId()) && !typed.getId().equals(resource.getId())) {
resource.setTypedScopes(typed.getScopes().stream().map(model1 -> { resource.setTypedScopes(typed.getScopes().stream().map(model1 -> {
ScopeRepresentation scope = new ScopeRepresentation(); ScopeRepresentation scope = new ScopeRepresentation();
scope.setId(model1.getId()); scope.setId(model1.getId());

View file

@ -1922,7 +1922,7 @@ public class RepresentationToModel {
public static void toModel(ResourceServerRepresentation rep, AuthorizationProvider authorization) { public static void toModel(ResourceServerRepresentation rep, AuthorizationProvider authorization) {
ResourceServerStore resourceServerStore = authorization.getStoreFactory().getResourceServerStore(); ResourceServerStore resourceServerStore = authorization.getStoreFactory().getResourceServerStore();
ResourceServer resourceServer; ResourceServer resourceServer;
ResourceServer existing = resourceServerStore.findByClient(rep.getClientId()); ResourceServer existing = resourceServerStore.findById(rep.getClientId());
if (existing == null) { if (existing == null) {
resourceServer = resourceServerStore.create(rep.getClientId()); resourceServer = resourceServerStore.create(rep.getClientId());
@ -1947,7 +1947,7 @@ public class RepresentationToModel {
if (owner == null) { if (owner == null) {
owner = new ResourceOwnerRepresentation(); owner = new ResourceOwnerRepresentation();
owner.setId(resourceServer.getClientId()); owner.setId(resourceServer.getId());
resource.setOwner(owner); resource.setOwner(owner);
} else if (owner.getName() != null) { } else if (owner.getName() != null) {
UserModel user = session.users().getUserByUsername(owner.getName(), realm); UserModel user = session.users().getUserByUsername(owner.getName(), realm);
@ -2270,7 +2270,7 @@ public class RepresentationToModel {
if (owner == null) { if (owner == null) {
owner = new ResourceOwnerRepresentation(); owner = new ResourceOwnerRepresentation();
owner.setId(resourceServer.getClientId()); owner.setId(resourceServer.getId());
} }
String ownerId = owner.getId(); String ownerId = owner.getId();
@ -2279,7 +2279,7 @@ public class RepresentationToModel {
throw new RuntimeException("No owner specified for resource [" + resource.getName() + "]."); throw new RuntimeException("No owner specified for resource [" + resource.getName() + "].");
} }
if (!resourceServer.getClientId().equals(ownerId)) { if (!resourceServer.getId().equals(ownerId)) {
RealmModel realm = authorization.getRealm(); RealmModel realm = authorization.getRealm();
KeycloakSession keycloakSession = authorization.getKeycloakSession(); KeycloakSession keycloakSession = authorization.getKeycloakSession();
UserProvider users = keycloakSession.users(); UserProvider users = keycloakSession.users();

View file

@ -18,15 +18,15 @@
package org.keycloak.authorization.admin; package org.keycloak.authorization.admin;
import javax.ws.rs.Path;
import org.jboss.resteasy.spi.ResteasyProviderFactory; import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.keycloak.authorization.AuthorizationProvider; import org.keycloak.authorization.AuthorizationProvider;
import org.keycloak.authorization.model.ResourceServer; import org.keycloak.authorization.model.ResourceServer;
import org.keycloak.models.ClientModel; import org.keycloak.models.ClientModel;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
import org.keycloak.services.resources.admin.AdminEventBuilder; import org.keycloak.services.resources.admin.AdminEventBuilder;
import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
import javax.ws.rs.Path;
/** /**
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a> * @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
@ -43,7 +43,7 @@ public class AuthorizationService {
this.client = client; this.client = client;
this.authorization = session.getProvider(AuthorizationProvider.class); this.authorization = session.getProvider(AuthorizationProvider.class);
this.adminEvent = adminEvent; this.adminEvent = adminEvent;
this.resourceServer = this.authorization.getStoreFactory().getResourceServerStore().findByClient(this.client.getId()); this.resourceServer = this.authorization.getStoreFactory().getResourceServerStore().findById(this.client.getId());
this.auth = auth; this.auth = auth;
} }

View file

@ -229,7 +229,7 @@ public class PolicyEvaluationService {
String clientId = representation.getClientId(); String clientId = representation.getClientId();
if (clientId == null) { if (clientId == null) {
clientId = resourceServer.getClientId(); clientId = resourceServer.getId();
} }
if (clientId != null) { if (clientId != null) {

View file

@ -30,17 +30,15 @@ import org.keycloak.events.admin.OperationType;
import org.keycloak.events.admin.ResourceType; import org.keycloak.events.admin.ResourceType;
import org.keycloak.models.ClientModel; import org.keycloak.models.ClientModel;
import org.keycloak.models.Constants; import org.keycloak.models.Constants;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel; import org.keycloak.models.UserModel;
import org.keycloak.models.UserProvider;
import org.keycloak.representations.idm.authorization.PolicyRepresentation; import org.keycloak.representations.idm.authorization.PolicyRepresentation;
import org.keycloak.representations.idm.authorization.ResourceOwnerRepresentation; import org.keycloak.representations.idm.authorization.ResourceOwnerRepresentation;
import org.keycloak.representations.idm.authorization.ResourceRepresentation; import org.keycloak.representations.idm.authorization.ResourceRepresentation;
import org.keycloak.representations.idm.authorization.ScopeRepresentation; import org.keycloak.representations.idm.authorization.ScopeRepresentation;
import org.keycloak.services.ErrorResponse; import org.keycloak.services.ErrorResponse;
import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
import org.keycloak.services.resources.admin.AdminEventBuilder; import org.keycloak.services.resources.admin.AdminEventBuilder;
import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
import javax.ws.rs.Consumes; import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE; import javax.ws.rs.DELETE;
@ -103,7 +101,7 @@ public class ResourceSetService {
if (owner == null) { if (owner == null) {
owner = new ResourceOwnerRepresentation(); owner = new ResourceOwnerRepresentation();
owner.setId(resourceServer.getClientId()); owner.setId(resourceServer.getId());
} }
String ownerId = owner.getId(); String ownerId = owner.getId();
@ -217,7 +215,7 @@ public class ResourceSetService {
if (model.getType() != null) { if (model.getType() != null) {
ResourceStore resourceStore = authorization.getStoreFactory().getResourceStore(); ResourceStore resourceStore = authorization.getStoreFactory().getResourceStore();
for (Resource typed : resourceStore.findByType(model.getType(), resourceServer.getId())) { for (Resource typed : resourceStore.findByType(model.getType(), resourceServer.getId())) {
if (typed.getOwner().equals(resourceServer.getClientId()) && !typed.getId().equals(model.getId())) { if (typed.getOwner().equals(resourceServer.getId()) && !typed.getId().equals(model.getId())) {
scopes.addAll(typed.getScopes().stream().map(model1 -> { scopes.addAll(typed.getScopes().stream().map(model1 -> {
ScopeRepresentation scope = new ScopeRepresentation(); ScopeRepresentation scope = new ScopeRepresentation();
scope.setId(model1.getId()); scope.setId(model1.getId());

View file

@ -119,7 +119,7 @@ public class EntitlementService {
} }
StoreFactory storeFactory = authorization.getStoreFactory(); StoreFactory storeFactory = authorization.getStoreFactory();
ResourceServer resourceServer = storeFactory.getResourceServerStore().findByClient(client.getId()); ResourceServer resourceServer = storeFactory.getResourceServerStore().findById(client.getId());
if (resourceServer == null) { if (resourceServer == null) {
throw new ErrorResponseException(OAuthErrorException.INVALID_REQUEST, "Client does not support permissions", Status.FORBIDDEN); throw new ErrorResponseException(OAuthErrorException.INVALID_REQUEST, "Client does not support permissions", Status.FORBIDDEN);
@ -152,7 +152,7 @@ public class EntitlementService {
} }
StoreFactory storeFactory = authorization.getStoreFactory(); StoreFactory storeFactory = authorization.getStoreFactory();
ResourceServer resourceServer = storeFactory.getResourceServerStore().findByClient(client.getId()); ResourceServer resourceServer = storeFactory.getResourceServerStore().findById(client.getId());
if (resourceServer == null) { if (resourceServer == null) {
throw new ErrorResponseException(OAuthErrorException.INVALID_REQUEST, "Client does not support permissions", Status.FORBIDDEN); throw new ErrorResponseException(OAuthErrorException.INVALID_REQUEST, "Client does not support permissions", Status.FORBIDDEN);

View file

@ -100,7 +100,7 @@ public class ProtectionService {
ResourceServer resourceServer = getResourceServer(identity); ResourceServer resourceServer = getResourceServer(identity);
KeycloakSession keycloakSession = authorization.getKeycloakSession(); KeycloakSession keycloakSession = authorization.getKeycloakSession();
RealmModel realm = keycloakSession.getContext().getRealm(); RealmModel realm = keycloakSession.getContext().getRealm();
ClientModel client = realm.getClientById(resourceServer.getClientId()); ClientModel client = realm.getClientById(resourceServer.getId());
if (!identity.hasClientRole(client.getClientId(), "uma_protection")) { if (!identity.hasClientRole(client.getClientId(), "uma_protection")) {
throw new ErrorResponseException(OAuthErrorException.INVALID_SCOPE, "Requires uma_protection scope.", Status.FORBIDDEN); throw new ErrorResponseException(OAuthErrorException.INVALID_SCOPE, "Requires uma_protection scope.", Status.FORBIDDEN);
@ -117,7 +117,7 @@ public class ProtectionService {
throw new ErrorResponseException("invalid_clientId", "Client application with id [" + identity.getId() + "] does not exist in realm [" + realm.getName() + "]", Status.BAD_REQUEST); throw new ErrorResponseException("invalid_clientId", "Client application with id [" + identity.getId() + "] does not exist in realm [" + realm.getName() + "]", Status.BAD_REQUEST);
} }
ResourceServer resourceServer = this.authorization.getStoreFactory().getResourceServerStore().findByClient(identity.getId()); ResourceServer resourceServer = this.authorization.getStoreFactory().getResourceServerStore().findById(identity.getId());
if (resourceServer == null) { if (resourceServer == null) {
throw new ErrorResponseException("invalid_clientId", "Client application [" + clientApplication.getClientId() + "] is not registered as resource server.", Status.FORBIDDEN); throw new ErrorResponseException("invalid_clientId", "Client application [" + clientApplication.getClientId() + "] is not registered as resource server.", Status.FORBIDDEN);

View file

@ -114,7 +114,7 @@ public class AbstractPermissionService {
} }
for (Resource baseResource : authorization.getStoreFactory().getResourceStore().findByType(resource.getType(), resourceServer.getId())) { for (Resource baseResource : authorization.getStoreFactory().getResourceStore().findByType(resource.getType(), resourceServer.getId())) {
if (baseResource.getOwner().equals(resource.getResourceServer().getClientId())) { if (baseResource.getOwner().equals(resource.getResourceServer().getId())) {
for (Scope baseScope : baseResource.getScopes()) { for (Scope baseScope : baseResource.getScopes()) {
if (baseScope.getName().equals(scopeName)) { if (baseScope.getName().equals(scopeName)) {
return new ScopeRepresentation(scopeName); return new ScopeRepresentation(scopeName);

View file

@ -20,8 +20,6 @@ package org.keycloak.authorization.util;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.LinkedList; import java.util.LinkedList;
@ -70,7 +68,7 @@ public final class Permissions {
StoreFactory storeFactory = authorization.getStoreFactory(); StoreFactory storeFactory = authorization.getStoreFactory();
ResourceStore resourceStore = storeFactory.getResourceStore(); ResourceStore resourceStore = storeFactory.getResourceStore();
resourceStore.findByOwner(resourceServer.getClientId(), resourceServer.getId()).stream().forEach(resource -> permissions.addAll(createResourcePermissionsWithScopes(resource, new LinkedList(resource.getScopes()), authorization))); resourceStore.findByOwner(resourceServer.getId(), resourceServer.getId()).stream().forEach(resource -> permissions.addAll(createResourcePermissionsWithScopes(resource, new LinkedList(resource.getScopes()), authorization)));
resourceStore.findByOwner(identity.getId(), resourceServer.getId()).stream().forEach(resource -> permissions.addAll(createResourcePermissionsWithScopes(resource, new LinkedList(resource.getScopes()), authorization))); resourceStore.findByOwner(identity.getId(), resourceServer.getId()).stream().forEach(resource -> permissions.addAll(createResourcePermissionsWithScopes(resource, new LinkedList(resource.getScopes()), authorization)));
return permissions; return permissions;
@ -86,11 +84,11 @@ public final class Permissions {
scopes = new LinkedList<>(resource.getScopes()); scopes = new LinkedList<>(resource.getScopes());
// check if there is a typed resource whose scopes are inherited by the resource being requested. In this case, we assume that parent resource // check if there is a typed resource whose scopes are inherited by the resource being requested. In this case, we assume that parent resource
// is owned by the resource server itself // is owned by the resource server itself
if (type != null && !resource.getOwner().equals(resourceServer.getClientId())) { if (type != null && !resource.getOwner().equals(resourceServer.getId())) {
StoreFactory storeFactory = authorization.getStoreFactory(); StoreFactory storeFactory = authorization.getStoreFactory();
ResourceStore resourceStore = storeFactory.getResourceStore(); ResourceStore resourceStore = storeFactory.getResourceStore();
resourceStore.findByType(type, resourceServer.getId()).forEach(resource1 -> { resourceStore.findByType(type, resourceServer.getId()).forEach(resource1 -> {
if (resource1.getOwner().equals(resourceServer.getClientId())) { if (resource1.getOwner().equals(resourceServer.getId())) {
for (Scope typeScope : resource1.getScopes()) { for (Scope typeScope : resource1.getScopes()) {
if (!scopes.contains(typeScope)) { if (!scopes.contains(typeScope)) {
scopes.add(typeScope); scopes.add(typeScope);
@ -123,11 +121,11 @@ public final class Permissions {
// check if there is a typed resource whose scopes are inherited by the resource being requested. In this case, we assume that parent resource // check if there is a typed resource whose scopes are inherited by the resource being requested. In this case, we assume that parent resource
// is owned by the resource server itself // is owned by the resource server itself
if (type != null && !resource.getOwner().equals(resourceServer.getClientId())) { if (type != null && !resource.getOwner().equals(resourceServer.getId())) {
StoreFactory storeFactory = authorization.getStoreFactory(); StoreFactory storeFactory = authorization.getStoreFactory();
ResourceStore resourceStore = storeFactory.getResourceStore(); ResourceStore resourceStore = storeFactory.getResourceStore();
resourceStore.findByType(type, resourceServer.getId()).forEach(resource1 -> { resourceStore.findByType(type, resourceServer.getId()).forEach(resource1 -> {
if (resource1.getOwner().equals(resourceServer.getClientId())) { if (resource1.getOwner().equals(resourceServer.getId())) {
for (Scope typeScope : resource1.getScopes()) { for (Scope typeScope : resource1.getScopes()) {
if (!scopes.contains(typeScope)) { if (!scopes.contains(typeScope)) {
scopes.add(typeScope); scopes.add(typeScope);

View file

@ -55,7 +55,6 @@ import org.keycloak.models.RoleContainerModel;
import org.keycloak.models.RoleModel; import org.keycloak.models.RoleModel;
import org.keycloak.models.UserConsentModel; import org.keycloak.models.UserConsentModel;
import org.keycloak.models.UserModel; import org.keycloak.models.UserModel;
import org.keycloak.models.UserProvider;
import org.keycloak.models.utils.ModelToRepresentation; import org.keycloak.models.utils.ModelToRepresentation;
import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.ClientTemplateRepresentation; import org.keycloak.representations.idm.ClientTemplateRepresentation;
@ -73,6 +72,7 @@ import org.keycloak.representations.idm.authorization.ResourceRepresentation;
import org.keycloak.representations.idm.authorization.ResourceServerRepresentation; import org.keycloak.representations.idm.authorization.ResourceServerRepresentation;
import org.keycloak.representations.idm.authorization.ScopeRepresentation; import org.keycloak.representations.idm.authorization.ScopeRepresentation;
import org.keycloak.util.JsonSerialization; import org.keycloak.util.JsonSerialization;
import com.fasterxml.jackson.core.JsonEncoding; import com.fasterxml.jackson.core.JsonEncoding;
import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonGenerator;
@ -298,7 +298,7 @@ public class ExportUtils {
AuthorizationProviderFactory providerFactory = (AuthorizationProviderFactory) session.getKeycloakSessionFactory().getProviderFactory(AuthorizationProvider.class); AuthorizationProviderFactory providerFactory = (AuthorizationProviderFactory) session.getKeycloakSessionFactory().getProviderFactory(AuthorizationProvider.class);
AuthorizationProvider authorization = providerFactory.create(session, client.getRealm()); AuthorizationProvider authorization = providerFactory.create(session, client.getRealm());
StoreFactory storeFactory = authorization.getStoreFactory(); StoreFactory storeFactory = authorization.getStoreFactory();
ResourceServer settingsModel = authorization.getStoreFactory().getResourceServerStore().findByClient(client.getId()); ResourceServer settingsModel = authorization.getStoreFactory().getResourceServerStore().findById(client.getId());
if (settingsModel == null) { if (settingsModel == null) {
return null; return null;
@ -314,7 +314,7 @@ public class ExportUtils {
.stream().map(resource -> { .stream().map(resource -> {
ResourceRepresentation rep = toRepresentation(resource, settingsModel, authorization); ResourceRepresentation rep = toRepresentation(resource, settingsModel, authorization);
if (rep.getOwner().getId().equals(settingsModel.getClientId())) { if (rep.getOwner().getId().equals(settingsModel.getId())) {
rep.setOwner(null); rep.setOwner(null);
} else { } else {
rep.getOwner().setId(null); rep.getOwner().setId(null);

View file

@ -112,7 +112,7 @@ class ClientPermissions implements ClientPermissionEvaluator, ClientPermissionM
String resourceName = getResourceName(client); String resourceName = getResourceName(client);
Resource resource = authz.getStoreFactory().getResourceStore().findByName(resourceName, server.getId()); Resource resource = authz.getStoreFactory().getResourceStore().findByName(resourceName, server.getId());
if (resource == null) { if (resource == null) {
resource = authz.getStoreFactory().getResourceStore().create(resourceName, server, server.getClientId()); resource = authz.getStoreFactory().getResourceStore().create(resourceName, server, server.getId());
resource.setType("Client"); resource.setType("Client");
Set<Scope> scopeset = new HashSet<>(); Set<Scope> scopeset = new HashSet<>();
scopeset.add(configureScope); scopeset.add(configureScope);

View file

@ -26,7 +26,6 @@ import org.keycloak.models.AdminRoles;
import org.keycloak.models.GroupModel; import org.keycloak.models.GroupModel;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.utils.ModelToRepresentation;
import org.keycloak.services.ForbiddenException; import org.keycloak.services.ForbiddenException;
import java.util.HashMap; import java.util.HashMap;
@ -95,7 +94,7 @@ class GroupPermissions implements GroupPermissionEvaluator, GroupPermissionManag
String groupResourceName = getGroupResourceName(group); String groupResourceName = getGroupResourceName(group);
Resource groupResource = authz.getStoreFactory().getResourceStore().findByName(groupResourceName, server.getId()); Resource groupResource = authz.getStoreFactory().getResourceStore().findByName(groupResourceName, server.getId());
if (groupResource == null) { if (groupResource == null) {
groupResource = authz.getStoreFactory().getResourceStore().create(groupResourceName, server, server.getClientId()); groupResource = authz.getStoreFactory().getResourceStore().create(groupResourceName, server, server.getId());
Set<Scope> scopeset = new HashSet<>(); Set<Scope> scopeset = new HashSet<>();
scopeset.add(manageScope); scopeset.add(manageScope);
scopeset.add(viewScope); scopeset.add(viewScope);

View file

@ -32,7 +32,6 @@ import org.keycloak.models.RealmModel;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
@ -76,7 +75,7 @@ class IdentityProviderPermissions implements IdentityProviderPermissionManageme
String resourceName = getResourceName(idp); String resourceName = getResourceName(idp);
Resource resource = authz.getStoreFactory().getResourceStore().findByName(resourceName, server.getId()); Resource resource = authz.getStoreFactory().getResourceStore().findByName(resourceName, server.getId());
if (resource == null) { if (resource == null) {
resource = authz.getStoreFactory().getResourceStore().create(resourceName, server, server.getClientId()); resource = authz.getStoreFactory().getResourceStore().create(resourceName, server, server.getId());
resource.setType("IdentityProvider"); resource.setType("IdentityProvider");
Set<Scope> scopeset = new HashSet<>(); Set<Scope> scopeset = new HashSet<>();
scopeset.add(exchangeToScope); scopeset.add(exchangeToScope);

View file

@ -40,7 +40,6 @@ import org.keycloak.models.Constants;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory; import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel; import org.keycloak.models.UserModel;
import org.keycloak.services.ForbiddenException; import org.keycloak.services.ForbiddenException;
import org.keycloak.services.managers.RealmManager; import org.keycloak.services.managers.RealmManager;
@ -252,7 +251,7 @@ class MgmtPermissions implements AdminPermissionEvaluator, AdminPermissionManage
ResourceServerStore resourceServerStore = authz.getStoreFactory().getResourceServerStore(); ResourceServerStore resourceServerStore = authz.getStoreFactory().getResourceServerStore();
ClientModel client = getRealmManagementClient(); ClientModel client = getRealmManagementClient();
if (client == null) return null; if (client == null) return null;
realmResourceServer = authz.getStoreFactory().getResourceServerStore().findByClient(client.getId()); realmResourceServer = authz.getStoreFactory().getResourceServerStore().findById(client.getId());
return realmResourceServer; return realmResourceServer;
} }
@ -260,7 +259,7 @@ class MgmtPermissions implements AdminPermissionEvaluator, AdminPermissionManage
public ResourceServer initializeRealmResourceServer() { public ResourceServer initializeRealmResourceServer() {
if (realmResourceServer != null) return realmResourceServer; if (realmResourceServer != null) return realmResourceServer;
ClientModel client = getRealmManagementClient(); ClientModel client = getRealmManagementClient();
realmResourceServer = authz.getStoreFactory().getResourceServerStore().findByClient(client.getId()); realmResourceServer = authz.getStoreFactory().getResourceServerStore().findById(client.getId());
if (realmResourceServer == null) { if (realmResourceServer == null) {
realmResourceServer = authz.getStoreFactory().getResourceServerStore().create(client.getId()); realmResourceServer = authz.getStoreFactory().getResourceServerStore().create(client.getId());
} }

View file

@ -34,7 +34,6 @@ import org.keycloak.models.RoleModel;
import org.keycloak.representations.idm.authorization.DecisionStrategy; import org.keycloak.representations.idm.authorization.DecisionStrategy;
import org.keycloak.services.ForbiddenException; import org.keycloak.services.ForbiddenException;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
@ -541,7 +540,7 @@ class RolePermissions implements RolePermissionEvaluator, RolePermissionManageme
String roleResourceName = getRoleResourceName(role); String roleResourceName = getRoleResourceName(role);
Resource resource = authz.getStoreFactory().getResourceStore().findByName(roleResourceName, server.getId()); Resource resource = authz.getStoreFactory().getResourceStore().findByName(roleResourceName, server.getId());
if (resource == null) { if (resource == null) {
resource = authz.getStoreFactory().getResourceStore().create(roleResourceName, server, server.getClientId()); resource = authz.getStoreFactory().getResourceStore().create(roleResourceName, server, server.getId());
Set<Scope> scopeset = new HashSet<>(); Set<Scope> scopeset = new HashSet<>();
scopeset.add(mapClientScope); scopeset.add(mapClientScope);
scopeset.add(mapCompositeScope); scopeset.add(mapCompositeScope);

View file

@ -84,7 +84,7 @@ class UserPermissions implements UserPermissionEvaluator, UserPermissionManageme
Resource usersResource = authz.getStoreFactory().getResourceStore().findByName(USERS_RESOURCE, server.getId()); Resource usersResource = authz.getStoreFactory().getResourceStore().findByName(USERS_RESOURCE, server.getId());
if (usersResource == null) { if (usersResource == null) {
usersResource = authz.getStoreFactory().getResourceStore().create(USERS_RESOURCE, server, server.getClientId()); usersResource = authz.getStoreFactory().getResourceStore().create(USERS_RESOURCE, server, server.getId());
Set<Scope> scopeset = new HashSet<>(); Set<Scope> scopeset = new HashSet<>();
scopeset.add(manageScope); scopeset.add(manageScope);
scopeset.add(viewScope); scopeset.add(viewScope);

View file

@ -85,7 +85,7 @@ public class AuthzCleanupTest extends AbstractKeycloakTest {
session.getContext().setRealm(realm); session.getContext().setRealm(realm);
AuthorizationProvider authz = session.getProvider(AuthorizationProvider.class); AuthorizationProvider authz = session.getProvider(AuthorizationProvider.class);
ClientModel myclient = realm.getClientByClientId("myclient"); ClientModel myclient = realm.getClientByClientId("myclient");
ResourceServer resourceServer = authz.getStoreFactory().getResourceServerStore().findByClient(myclient.getId()); ResourceServer resourceServer = authz.getStoreFactory().getResourceServerStore().findById(myclient.getId());
createRolePolicy(authz, resourceServer, "client-role-1"); createRolePolicy(authz, resourceServer, "client-role-1");
createRolePolicy(authz, resourceServer, "client-role-2"); createRolePolicy(authz, resourceServer, "client-role-2");
} }

View file

@ -87,7 +87,7 @@ public class PolicyEvaluationCompositeRoleTest extends AbstractAuthzTest {
Policy policy = createRolePolicy(authz, resourceServer, role1); Policy policy = createRolePolicy(authz, resourceServer, role1);
Scope scope = authz.getStoreFactory().getScopeStore().create("myscope", resourceServer); Scope scope = authz.getStoreFactory().getScopeStore().create("myscope", resourceServer);
Resource resource = authz.getStoreFactory().getResourceStore().create("myresource", resourceServer, resourceServer.getClientId()); Resource resource = authz.getStoreFactory().getResourceStore().create("myresource", resourceServer, resourceServer.getId());
addScopePermission(authz, resourceServer, "mypermission", resource, scope, policy); addScopePermission(authz, resourceServer, "mypermission", resource, scope, policy);
RoleModel composite = realm.addRole("composite"); RoleModel composite = realm.addRole("composite");

View file

@ -61,7 +61,6 @@ public class ResourceManagementTest extends AbstractPhotozAdminTest {
assertEquals("Resource Type", resourceModel.getType()); assertEquals("Resource Type", resourceModel.getType());
assertEquals("Resource Icon URI", resourceModel.getIconUri()); assertEquals("Resource Icon URI", resourceModel.getIconUri());
assertEquals("Resource URI", resourceModel.getUri()); assertEquals("Resource URI", resourceModel.getUri());
assertEquals(resourceServer.getClientId(), resourceModel.getOwner());
assertEquals(resourceServer.getId(), resourceModel.getResourceServer().getId()); assertEquals(resourceServer.getId(), resourceModel.getResourceServer().getId());
}); });
} }