[KEYCLOAK-4808] - Import large authz settings a bit faster
This commit is contained in:
parent
db269e28d6
commit
6865b4bbb1
4 changed files with 62 additions and 40 deletions
|
@ -24,6 +24,7 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.persistence.EntityManager;
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.FlushModeType;
|
||||||
import javax.persistence.NoResultException;
|
import javax.persistence.NoResultException;
|
||||||
import javax.persistence.Query;
|
import javax.persistence.Query;
|
||||||
import javax.persistence.TypedQuery;
|
import javax.persistence.TypedQuery;
|
||||||
|
@ -34,14 +35,10 @@ import javax.persistence.criteria.Root;
|
||||||
|
|
||||||
import org.keycloak.authorization.AuthorizationProvider;
|
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.ResourceServerEntity;
|
|
||||||
import org.keycloak.authorization.model.Policy;
|
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.PolicyStore;
|
import org.keycloak.authorization.store.PolicyStore;
|
||||||
import org.keycloak.authorization.store.StoreFactory;
|
|
||||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
import org.keycloak.models.utils.RepresentationToModel;
|
|
||||||
import org.keycloak.representations.idm.authorization.AbstractPolicyRepresentation;
|
import org.keycloak.representations.idm.authorization.AbstractPolicyRepresentation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -96,8 +93,10 @@ public class JPAPolicyStore implements PolicyStore {
|
||||||
public Policy findByName(String name, String resourceServerId) {
|
public Policy findByName(String name, String resourceServerId) {
|
||||||
TypedQuery<String> query = entityManager.createNamedQuery("findPolicyIdByName", String.class);
|
TypedQuery<String> query = entityManager.createNamedQuery("findPolicyIdByName", String.class);
|
||||||
|
|
||||||
|
query.setFlushMode(FlushModeType.COMMIT);
|
||||||
query.setParameter("serverId", resourceServerId);
|
query.setParameter("serverId", resourceServerId);
|
||||||
query.setParameter("name", name);
|
query.setParameter("name", name);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String id = query.getSingleResult();
|
String id = query.getSingleResult();
|
||||||
return provider.getStoreFactory().getPolicyStore().findById(id, resourceServerId);
|
return provider.getStoreFactory().getPolicyStore().findById(id, resourceServerId);
|
||||||
|
@ -167,6 +166,7 @@ public class JPAPolicyStore implements PolicyStore {
|
||||||
public List<Policy> findByResource(final String resourceId, String resourceServerId) {
|
public List<Policy> findByResource(final String resourceId, String resourceServerId) {
|
||||||
TypedQuery<String> query = entityManager.createNamedQuery("findPolicyIdByResource", String.class);
|
TypedQuery<String> query = entityManager.createNamedQuery("findPolicyIdByResource", String.class);
|
||||||
|
|
||||||
|
query.setFlushMode(FlushModeType.COMMIT);
|
||||||
query.setParameter("resourceId", resourceId);
|
query.setParameter("resourceId", resourceId);
|
||||||
query.setParameter("serverId", resourceServerId);
|
query.setParameter("serverId", resourceServerId);
|
||||||
|
|
||||||
|
@ -182,6 +182,7 @@ public class JPAPolicyStore implements PolicyStore {
|
||||||
public List<Policy> findByResourceType(final String resourceType, String resourceServerId) {
|
public List<Policy> findByResourceType(final String resourceType, String resourceServerId) {
|
||||||
TypedQuery<String> query = entityManager.createNamedQuery("findPolicyIdByResourceType", String.class);
|
TypedQuery<String> query = entityManager.createNamedQuery("findPolicyIdByResourceType", String.class);
|
||||||
|
|
||||||
|
query.setFlushMode(FlushModeType.COMMIT);
|
||||||
query.setParameter("type", resourceType);
|
query.setParameter("type", resourceType);
|
||||||
query.setParameter("serverId", resourceServerId);
|
query.setParameter("serverId", resourceServerId);
|
||||||
|
|
||||||
|
@ -202,6 +203,7 @@ public class JPAPolicyStore implements PolicyStore {
|
||||||
// Use separate subquery to handle DB2 and MSSSQL
|
// Use separate subquery to handle DB2 and MSSSQL
|
||||||
TypedQuery<String> query = entityManager.createNamedQuery("findPolicyIdByScope", String.class);
|
TypedQuery<String> query = entityManager.createNamedQuery("findPolicyIdByScope", String.class);
|
||||||
|
|
||||||
|
query.setFlushMode(FlushModeType.COMMIT);
|
||||||
query.setParameter("scopeIds", scopeIds);
|
query.setParameter("scopeIds", scopeIds);
|
||||||
query.setParameter("serverId", resourceServerId);
|
query.setParameter("serverId", resourceServerId);
|
||||||
|
|
||||||
|
@ -217,6 +219,7 @@ public class JPAPolicyStore implements PolicyStore {
|
||||||
public List<Policy> findByType(String type, String resourceServerId) {
|
public List<Policy> findByType(String type, String resourceServerId) {
|
||||||
TypedQuery<String> query = entityManager.createNamedQuery("findPolicyIdByType", String.class);
|
TypedQuery<String> query = entityManager.createNamedQuery("findPolicyIdByType", String.class);
|
||||||
|
|
||||||
|
query.setFlushMode(FlushModeType.COMMIT);
|
||||||
query.setParameter("serverId", resourceServerId);
|
query.setParameter("serverId", resourceServerId);
|
||||||
query.setParameter("type", type);
|
query.setParameter("type", type);
|
||||||
|
|
||||||
|
@ -233,6 +236,7 @@ public class JPAPolicyStore implements PolicyStore {
|
||||||
|
|
||||||
TypedQuery<String> query = entityManager.createNamedQuery("findPolicyIdByDependentPolices", String.class);
|
TypedQuery<String> query = entityManager.createNamedQuery("findPolicyIdByDependentPolices", String.class);
|
||||||
|
|
||||||
|
query.setFlushMode(FlushModeType.COMMIT);
|
||||||
query.setParameter("serverId", resourceServerId);
|
query.setParameter("serverId", resourceServerId);
|
||||||
query.setParameter("policyId", policyId);
|
query.setParameter("policyId", policyId);
|
||||||
|
|
||||||
|
|
|
@ -19,13 +19,13 @@ package org.keycloak.authorization.jpa.store;
|
||||||
|
|
||||||
import org.keycloak.authorization.AuthorizationProvider;
|
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.ResourceServerEntity;
|
|
||||||
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.store.ResourceStore;
|
import org.keycloak.authorization.store.ResourceStore;
|
||||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
|
|
||||||
import javax.persistence.EntityManager;
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.FlushModeType;
|
||||||
import javax.persistence.NoResultException;
|
import javax.persistence.NoResultException;
|
||||||
import javax.persistence.Query;
|
import javax.persistence.Query;
|
||||||
import javax.persistence.TypedQuery;
|
import javax.persistence.TypedQuery;
|
||||||
|
@ -34,7 +34,6 @@ import javax.persistence.criteria.CriteriaQuery;
|
||||||
import javax.persistence.criteria.Predicate;
|
import javax.persistence.criteria.Predicate;
|
||||||
import javax.persistence.criteria.Root;
|
import javax.persistence.criteria.Root;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -62,6 +61,7 @@ public class JPAResourceStore implements ResourceStore {
|
||||||
entity.setOwner(owner);
|
entity.setOwner(owner);
|
||||||
|
|
||||||
this.entityManager.persist(entity);
|
this.entityManager.persist(entity);
|
||||||
|
this.entityManager.flush();
|
||||||
|
|
||||||
return new ResourceAdapter(entity, entityManager, provider.getStoreFactory());
|
return new ResourceAdapter(entity, entityManager, provider.getStoreFactory());
|
||||||
}
|
}
|
||||||
|
@ -90,6 +90,7 @@ public class JPAResourceStore implements ResourceStore {
|
||||||
public List<Resource> findByOwner(String ownerId, String resourceServerId) {
|
public List<Resource> findByOwner(String ownerId, String resourceServerId) {
|
||||||
TypedQuery<String> query = entityManager.createNamedQuery("findResourceIdByOwner", String.class);
|
TypedQuery<String> query = entityManager.createNamedQuery("findResourceIdByOwner", String.class);
|
||||||
|
|
||||||
|
query.setFlushMode(FlushModeType.COMMIT);
|
||||||
query.setParameter("owner", ownerId);
|
query.setParameter("owner", ownerId);
|
||||||
query.setParameter("serverId", resourceServerId);
|
query.setParameter("serverId", resourceServerId);
|
||||||
|
|
||||||
|
@ -108,6 +109,7 @@ public class JPAResourceStore implements ResourceStore {
|
||||||
public List<Resource> findByUri(String uri, String resourceServerId) {
|
public List<Resource> findByUri(String uri, String resourceServerId) {
|
||||||
TypedQuery<String> query = entityManager.createNamedQuery("findResourceIdByUri", String.class);
|
TypedQuery<String> query = entityManager.createNamedQuery("findResourceIdByUri", String.class);
|
||||||
|
|
||||||
|
query.setFlushMode(FlushModeType.COMMIT);
|
||||||
query.setParameter("uri", uri);
|
query.setParameter("uri", uri);
|
||||||
query.setParameter("serverId", resourceServerId);
|
query.setParameter("serverId", resourceServerId);
|
||||||
|
|
||||||
|
@ -185,6 +187,7 @@ public class JPAResourceStore implements ResourceStore {
|
||||||
public List<Resource> findByScope(List<String> scopes, String resourceServerId) {
|
public List<Resource> findByScope(List<String> scopes, String resourceServerId) {
|
||||||
TypedQuery<String> query = entityManager.createNamedQuery("findResourceIdByScope", String.class);
|
TypedQuery<String> query = entityManager.createNamedQuery("findResourceIdByScope", String.class);
|
||||||
|
|
||||||
|
query.setFlushMode(FlushModeType.COMMIT);
|
||||||
query.setParameter("scopeIds", scopes);
|
query.setParameter("scopeIds", scopes);
|
||||||
query.setParameter("serverId", resourceServerId);
|
query.setParameter("serverId", resourceServerId);
|
||||||
|
|
||||||
|
@ -203,8 +206,10 @@ public class JPAResourceStore implements ResourceStore {
|
||||||
public Resource findByName(String name, String resourceServerId) {
|
public Resource findByName(String name, String resourceServerId) {
|
||||||
TypedQuery<String> query = entityManager.createNamedQuery("findResourceIdByName", String.class);
|
TypedQuery<String> query = entityManager.createNamedQuery("findResourceIdByName", String.class);
|
||||||
|
|
||||||
|
query.setFlushMode(FlushModeType.COMMIT);
|
||||||
query.setParameter("serverId", resourceServerId);
|
query.setParameter("serverId", resourceServerId);
|
||||||
query.setParameter("name", name);
|
query.setParameter("name", name);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String id = query.getSingleResult();
|
String id = query.getSingleResult();
|
||||||
return provider.getStoreFactory().getResourceStore().findById(id, resourceServerId);
|
return provider.getStoreFactory().getResourceStore().findById(id, resourceServerId);
|
||||||
|
@ -217,6 +222,7 @@ public class JPAResourceStore implements ResourceStore {
|
||||||
public List<Resource> findByType(String type, String resourceServerId) {
|
public List<Resource> findByType(String type, String resourceServerId) {
|
||||||
TypedQuery<String> query = entityManager.createNamedQuery("findResourceIdByType", String.class);
|
TypedQuery<String> query = entityManager.createNamedQuery("findResourceIdByType", String.class);
|
||||||
|
|
||||||
|
query.setFlushMode(FlushModeType.COMMIT);
|
||||||
query.setParameter("type", type);
|
query.setParameter("type", type);
|
||||||
query.setParameter("serverId", resourceServerId);
|
query.setParameter("serverId", resourceServerId);
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.persistence.EntityManager;
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.FlushModeType;
|
||||||
import javax.persistence.NoResultException;
|
import javax.persistence.NoResultException;
|
||||||
import javax.persistence.Query;
|
import javax.persistence.Query;
|
||||||
import javax.persistence.TypedQuery;
|
import javax.persistence.TypedQuery;
|
||||||
|
@ -32,7 +33,6 @@ import javax.persistence.criteria.Predicate;
|
||||||
import javax.persistence.criteria.Root;
|
import javax.persistence.criteria.Root;
|
||||||
|
|
||||||
import org.keycloak.authorization.AuthorizationProvider;
|
import org.keycloak.authorization.AuthorizationProvider;
|
||||||
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.ResourceServer;
|
import org.keycloak.authorization.model.ResourceServer;
|
||||||
import org.keycloak.authorization.model.Scope;
|
import org.keycloak.authorization.model.Scope;
|
||||||
|
@ -61,6 +61,7 @@ public class JPAScopeStore implements ScopeStore {
|
||||||
entity.setResourceServer(ResourceServerAdapter.toEntity(entityManager, resourceServer));
|
entity.setResourceServer(ResourceServerAdapter.toEntity(entityManager, resourceServer));
|
||||||
|
|
||||||
this.entityManager.persist(entity);
|
this.entityManager.persist(entity);
|
||||||
|
this.entityManager.flush();
|
||||||
|
|
||||||
return new ScopeAdapter(entity, entityManager, provider.getStoreFactory());
|
return new ScopeAdapter(entity, entityManager, provider.getStoreFactory());
|
||||||
}
|
}
|
||||||
|
@ -91,8 +92,10 @@ public class JPAScopeStore implements ScopeStore {
|
||||||
try {
|
try {
|
||||||
TypedQuery<String> query = entityManager.createNamedQuery("findScopeIdByName", String.class);
|
TypedQuery<String> query = entityManager.createNamedQuery("findScopeIdByName", String.class);
|
||||||
|
|
||||||
|
query.setFlushMode(FlushModeType.COMMIT);
|
||||||
query.setParameter("serverId", resourceServerId);
|
query.setParameter("serverId", resourceServerId);
|
||||||
query.setParameter("name", name);
|
query.setParameter("name", name);
|
||||||
|
|
||||||
String id = query.getSingleResult();
|
String id = query.getSingleResult();
|
||||||
return provider.getStoreFactory().getScopeStore().findById(id, resourceServerId);
|
return provider.getStoreFactory().getScopeStore().findById(id, resourceServerId);
|
||||||
} catch (NoResultException nre) {
|
} catch (NoResultException nre) {
|
||||||
|
@ -104,6 +107,7 @@ public class JPAScopeStore implements ScopeStore {
|
||||||
public List<Scope> findByResourceServer(final String serverId) {
|
public List<Scope> findByResourceServer(final String serverId) {
|
||||||
TypedQuery<String> query = entityManager.createNamedQuery("findScopeIdByResourceServer", String.class);
|
TypedQuery<String> query = entityManager.createNamedQuery("findScopeIdByResourceServer", String.class);
|
||||||
|
|
||||||
|
query.setFlushMode(FlushModeType.COMMIT);
|
||||||
query.setParameter("serverId", serverId);
|
query.setParameter("serverId", serverId);
|
||||||
|
|
||||||
List<String> result = query.getResultList();
|
List<String> result = query.getResultList();
|
||||||
|
|
|
@ -1930,24 +1930,21 @@ public class RepresentationToModel {
|
||||||
resourceServer.setPolicyEnforcementMode(rep.getPolicyEnforcementMode());
|
resourceServer.setPolicyEnforcementMode(rep.getPolicyEnforcementMode());
|
||||||
resourceServer.setAllowRemoteResourceManagement(rep.isAllowRemoteResourceManagement());
|
resourceServer.setAllowRemoteResourceManagement(rep.isAllowRemoteResourceManagement());
|
||||||
|
|
||||||
rep.getScopes().forEach(scope -> {
|
for (ScopeRepresentation scope : rep.getScopes()) {
|
||||||
toModel(scope, resourceServer, authorization);
|
toModel(scope, resourceServer, authorization);
|
||||||
});
|
}
|
||||||
|
|
||||||
KeycloakSession session = authorization.getKeycloakSession();
|
KeycloakSession session = authorization.getKeycloakSession();
|
||||||
RealmModel realm = authorization.getRealm();
|
RealmModel realm = authorization.getRealm();
|
||||||
|
|
||||||
rep.getResources().forEach(resourceRepresentation -> {
|
for (ResourceRepresentation resource : rep.getResources()) {
|
||||||
ResourceOwnerRepresentation owner = resourceRepresentation.getOwner();
|
ResourceOwnerRepresentation owner = resource.getOwner();
|
||||||
|
|
||||||
if (owner == null) {
|
if (owner == null) {
|
||||||
owner = new ResourceOwnerRepresentation();
|
owner = new ResourceOwnerRepresentation();
|
||||||
resourceRepresentation.setOwner(owner);
|
owner.setId(resourceServer.getClientId());
|
||||||
}
|
resource.setOwner(owner);
|
||||||
|
} else if (owner.getName() != null) {
|
||||||
owner.setId(resourceServer.getClientId());
|
|
||||||
|
|
||||||
if (owner.getName() != null) {
|
|
||||||
UserModel user = session.users().getUserByUsername(owner.getName(), realm);
|
UserModel user = session.users().getUserByUsername(owner.getName(), realm);
|
||||||
|
|
||||||
if (user != null) {
|
if (user != null) {
|
||||||
|
@ -1955,8 +1952,8 @@ public class RepresentationToModel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
toModel(resourceRepresentation, resourceServer, authorization);
|
toModel(resource, resourceServer, authorization);
|
||||||
});
|
}
|
||||||
|
|
||||||
importPolicies(authorization, resourceServer, rep.getPolicies(), null);
|
importPolicies(authorization, resourceServer, rep.getPolicies(), null);
|
||||||
}
|
}
|
||||||
|
@ -1975,7 +1972,9 @@ public class RepresentationToModel {
|
||||||
PolicyStore policyStore = storeFactory.getPolicyStore();
|
PolicyStore policyStore = storeFactory.getPolicyStore();
|
||||||
try {
|
try {
|
||||||
List<String> policies = (List<String>) JsonSerialization.readValue(applyPolicies, List.class);
|
List<String> policies = (List<String>) JsonSerialization.readValue(applyPolicies, List.class);
|
||||||
config.put("applyPolicies", JsonSerialization.writeValueAsString(policies.stream().map(policyName -> {
|
Set<String> policyIds = new HashSet<>();
|
||||||
|
|
||||||
|
for (String policyName : policies) {
|
||||||
Policy policy = policyStore.findByName(policyName, resourceServer.getId());
|
Policy policy = policyStore.findByName(policyName, resourceServer.getId());
|
||||||
|
|
||||||
if (policy == null) {
|
if (policy == null) {
|
||||||
|
@ -1989,8 +1988,10 @@ public class RepresentationToModel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return policy.getId();
|
policyIds.add(policy.getId());
|
||||||
}).collect(Collectors.toList())));
|
}
|
||||||
|
|
||||||
|
config.put("applyPolicies", JsonSerialization.writeValueAsString(policyIds));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException("Error while importing policy [" + policyRepresentation.getName() + "].", e);
|
throw new RuntimeException("Error while importing policy [" + policyRepresentation.getName() + "].", e);
|
||||||
}
|
}
|
||||||
|
@ -2029,33 +2030,40 @@ public class RepresentationToModel {
|
||||||
|
|
||||||
if (representation instanceof PolicyRepresentation) {
|
if (representation instanceof PolicyRepresentation) {
|
||||||
PolicyRepresentation policy = PolicyRepresentation.class.cast(representation);
|
PolicyRepresentation policy = PolicyRepresentation.class.cast(representation);
|
||||||
String resourcesConfig = policy.getConfig().get("resources");
|
|
||||||
|
|
||||||
if (resourcesConfig != null) {
|
if (resources == null) {
|
||||||
try {
|
String resourcesConfig = policy.getConfig().get("resources");
|
||||||
resources = JsonSerialization.readValue(resourcesConfig, Set.class);
|
|
||||||
} catch (IOException e) {
|
if (resourcesConfig != null) {
|
||||||
throw new RuntimeException(e);
|
try {
|
||||||
|
resources = JsonSerialization.readValue(resourcesConfig, Set.class);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String scopesConfig = policy.getConfig().get("scopes");
|
if (scopes == null) {
|
||||||
|
String scopesConfig = policy.getConfig().get("scopes");
|
||||||
|
|
||||||
if (scopesConfig != null) {
|
if (scopesConfig != null) {
|
||||||
try {
|
try {
|
||||||
scopes = JsonSerialization.readValue(scopesConfig, Set.class);
|
scopes = JsonSerialization.readValue(scopesConfig, Set.class);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String policiesConfig = policy.getConfig().get("applyPolicies");
|
if (policies == null) {
|
||||||
|
String policiesConfig = policy.getConfig().get("applyPolicies");
|
||||||
|
|
||||||
if (policiesConfig != null) {
|
if (policiesConfig != null) {
|
||||||
try {
|
try {
|
||||||
policies = JsonSerialization.readValue(policiesConfig, Set.class);
|
policies = JsonSerialization.readValue(policiesConfig, Set.class);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue