[KEYCLOAK-3144] - Add authorization settings when exporting/importing a realm.

This commit is contained in:
Pedro Igor 2016-08-15 10:35:28 -03:00
parent fd983690e2
commit a8d2b810cf
24 changed files with 1376 additions and 849 deletions

View file

@ -17,6 +17,8 @@
package org.keycloak.representations.idm;
import org.keycloak.representations.idm.authorization.ResourceServerRepresentation;
import java.util.List;
import java.util.Map;
@ -62,6 +64,7 @@ public class ClientRepresentation {
private Boolean useTemplateConfig;
private Boolean useTemplateScope;
private Boolean useTemplateMappers;
private ResourceServerRepresentation authorizationSettings;
public String getId() {
@ -241,6 +244,9 @@ public class ClientRepresentation {
}
public Boolean getAuthorizationServicesEnabled() {
if (authorizationSettings != null) {
return true;
}
return authorizationServicesEnabled;
}
@ -353,4 +359,11 @@ public class ClientRepresentation {
this.useTemplateMappers = useTemplateMappers;
}
public ResourceServerRepresentation getAuthorizationSettings() {
return authorizationSettings;
}
public void setAuthorizationSettings(ResourceServerRepresentation authorizationSettings) {
this.authorizationSettings = authorizationSettings;
}
}

View file

@ -89,7 +89,7 @@
<local-cache name="sessions"/>
<local-cache name="offlineSessions"/>
<local-cache name="loginFailures"/>
<local-cache name="authorization "/>
<local-cache name="authorization"/>
<local-cache name="work"/>
</cache-container>
<xsl:apply-templates select="node()|@*"/>

View file

@ -24,6 +24,7 @@ import org.keycloak.authorization.policy.provider.PolicyProvider;
import org.keycloak.authorization.policy.provider.PolicyProviderFactory;
import org.keycloak.authorization.store.StoreFactory;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.provider.Provider;
import org.keycloak.provider.ProviderFactory;
@ -64,17 +65,19 @@ public final class AuthorizationProvider implements Provider {
private final StoreFactory storeFactory;
private final List<PolicyProviderFactory> policyProviderFactories;
private final KeycloakSession keycloakSession;
private final RealmModel realm;
public AuthorizationProvider(KeycloakSession session, StoreFactory storeFactory, Executor scheduller) {
public AuthorizationProvider(KeycloakSession session, RealmModel realm, StoreFactory storeFactory, Executor scheduller) {
this.keycloakSession = session;
this.realm = realm;
this.storeFactory = storeFactory;
this.scheduller = scheduller;
this.policyProviderFactories = configurePolicyProviderFactories(session);
this.policyEvaluator = new DefaultPolicyEvaluator(this, this.policyProviderFactories);
}
public AuthorizationProvider(KeycloakSession session, StoreFactory storeFactory) {
this(session, storeFactory, Runnable::run);
public AuthorizationProvider(KeycloakSession session, RealmModel realm, StoreFactory storeFactory) {
this(session, realm, storeFactory, Runnable::run);
}
/**
@ -120,6 +123,10 @@ public final class AuthorizationProvider implements Provider {
return this.keycloakSession;
}
public RealmModel getRealm() {
return realm;
}
private List<PolicyProviderFactory> configurePolicyProviderFactories(KeycloakSession session) {
List<ProviderFactory> providerFactories = session.getKeycloakSessionFactory().getProviderFactories(PolicyProvider.class);

View file

@ -18,10 +18,14 @@
package org.keycloak.authorization;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.provider.ProviderFactory;
/**
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
*/
public interface AuthorizationProviderFactory extends ProviderFactory<AuthorizationProvider> {
AuthorizationProvider create(KeycloakSession session, RealmModel realm);
}

View file

@ -17,6 +17,14 @@
package org.keycloak.models.utils;
import org.keycloak.authorization.AuthorizationProvider;
import org.keycloak.authorization.model.Policy;
import org.keycloak.authorization.model.Resource;
import org.keycloak.authorization.model.ResourceServer;
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.component.ComponentModel;
import org.keycloak.events.Event;
import org.keycloak.events.admin.AdminEvent;
@ -31,6 +39,7 @@ import org.keycloak.models.FederatedIdentityModel;
import org.keycloak.models.GroupModel;
import org.keycloak.models.IdentityProviderMapperModel;
import org.keycloak.models.IdentityProviderModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ModelException;
import org.keycloak.models.OTPPolicy;
import org.keycloak.models.ProtocolMapperModel;
@ -72,8 +81,25 @@ import org.keycloak.representations.idm.UserFederationProviderRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.representations.idm.UserSessionRepresentation;
import org.keycloak.common.util.Time;
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
import org.keycloak.representations.idm.authorization.ResourceOwnerRepresentation;
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
import org.keycloak.representations.idm.authorization.ResourceServerRepresentation;
import org.keycloak.representations.idm.authorization.ScopeRepresentation;
import org.keycloak.util.JsonSerialization;
import java.util.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@ -767,4 +793,181 @@ public class ModelToRepresentation {
rep.setConfig(component.getConfig());
return rep;
}
public static ScopeRepresentation toRepresentation(Scope model, AuthorizationProvider authorizationProvider) {
ScopeRepresentation scope = new ScopeRepresentation();
scope.setId(model.getId());
scope.setName(model.getName());
scope.setIconUri(model.getIconUri());
StoreFactory storeFactory = authorizationProvider.getStoreFactory();
scope.setResources(new ArrayList<>());
storeFactory.getResourceStore().findByScope(model.getId()).forEach(resource -> scope.getResources().add(toRepresentation(resource, resource.getResourceServer(), authorizationProvider)));
PolicyStore policyStore = storeFactory.getPolicyStore();
scope.setPolicies(new ArrayList<>());
policyStore.findByScopeIds(Arrays.asList(model.getId()), model.getResourceServer().getId()).forEach(policyModel -> {
PolicyRepresentation policy = new PolicyRepresentation();
policy.setId(policyModel.getId());
policy.setName(policyModel.getName());
policy.setType(policyModel.getType());
if (!scope.getPolicies().contains(policy)) {
scope.getPolicies().add(policy);
}
});
return scope;
}
public static ResourceServerRepresentation toRepresentation(ResourceServer model, ClientModel client) {
ResourceServerRepresentation server = new ResourceServerRepresentation();
server.setId(model.getId());
server.setClientId(model.getClientId());
server.setName(client.getClientId());
server.setAllowRemoteResourceManagement(model.isAllowRemoteResourceManagement());
server.setPolicyEnforcementMode(model.getPolicyEnforcementMode());
return server;
}
public static PolicyRepresentation toRepresentation(Policy model, AuthorizationProvider authorization) {
PolicyRepresentation representation = new PolicyRepresentation();
representation.setId(model.getId());
representation.setName(model.getName());
representation.setDescription(model.getDescription());
representation.setType(model.getType());
representation.setDecisionStrategy(model.getDecisionStrategy());
representation.setLogic(model.getLogic());
representation.setConfig(new HashMap<>(model.getConfig()));
List<Policy> policies = authorization.getStoreFactory().getPolicyStore().findDependentPolicies(model.getId());
representation.setDependentPolicies(policies.stream().map(policy -> {
PolicyRepresentation representation1 = new PolicyRepresentation();
representation1.setId(policy.getId());
representation1.setName(policy.getName());
return representation1;
}).collect(Collectors.toList()));
List<PolicyRepresentation> associatedPolicies = new ArrayList<>();
List<String> obj = model.getAssociatedPolicies().stream().map(policy -> {
PolicyRepresentation representation1 = new PolicyRepresentation();
representation1.setId(policy.getId());
representation1.setName(policy.getName());
representation1.setType(policy.getType());
associatedPolicies.add(representation1);
return policy.getId();
}).collect(Collectors.toList());
representation.setAssociatedPolicies(associatedPolicies);
try {
representation.getConfig().put("applyPolicies", JsonSerialization.writeValueAsString(obj));
} catch (IOException e) {
e.printStackTrace();
}
return representation;
}
public static ResourceRepresentation toRepresentation(Resource model, ResourceServer resourceServer, AuthorizationProvider authorization) {
ResourceRepresentation resource = new ResourceRepresentation();
resource.setId(model.getId());
resource.setType(model.getType());
resource.setName(model.getName());
resource.setUri(model.getUri());
resource.setIconUri(model.getIconUri());
ResourceOwnerRepresentation owner = new ResourceOwnerRepresentation();
owner.setId(model.getOwner());
KeycloakSession keycloakSession = authorization.getKeycloakSession();
RealmModel realm = authorization.getRealm();
if (owner.getId().equals(resourceServer.getClientId())) {
ClientModel clientModel = realm.getClientById(resourceServer.getClientId());
owner.setName(clientModel.getClientId());
} else {
UserModel userModel = keycloakSession.users().getUserById(owner.getId(), realm);
if (userModel == null) {
throw new RuntimeException("Could not find the user [" + owner.getId() + "] who owns the Resource [" + resource.getId() + "].");
}
owner.setName(userModel.getUsername());
}
resource.setOwner(owner);
resource.setScopes(model.getScopes().stream().map(model1 -> {
ScopeRepresentation scope = new ScopeRepresentation();
scope.setId(model1.getId());
scope.setName(model1.getName());
String iconUri = model1.getIconUri();
if (iconUri != null) {
scope.setIconUri(iconUri);
}
return scope;
}).collect(Collectors.toSet()));
resource.setTypedScopes(new ArrayList<>());
if (resource.getType() != null) {
ResourceStore resourceStore = authorization.getStoreFactory().getResourceStore();
for (Resource typed : resourceStore.findByType(resource.getType())) {
if (typed.getOwner().equals(resourceServer.getClientId()) && !typed.getId().equals(resource.getId())) {
resource.setTypedScopes(typed.getScopes().stream().map(model1 -> {
ScopeRepresentation scope = new ScopeRepresentation();
scope.setId(model1.getId());
scope.setName(model1.getName());
String iconUri = model1.getIconUri();
if (iconUri != null) {
scope.setIconUri(iconUri);
}
return scope;
}).filter(scopeRepresentation -> !resource.getScopes().contains(scopeRepresentation)).collect(Collectors.toList()));
}
}
}
resource.setPolicies(new ArrayList<>());
Set<Policy> policies = new HashSet<>();
PolicyStore policyStore = authorization.getStoreFactory().getPolicyStore();
policies.addAll(policyStore.findByResource(resource.getId()));
policies.addAll(policyStore.findByResourceType(resource.getType(), resourceServer.getId()));
policies.addAll(policyStore.findByScopeIds(resource.getScopes().stream().map(scope -> scope.getId()).collect(Collectors.toList()), resourceServer.getId()));
for (Policy policyModel : policies) {
PolicyRepresentation policy = new PolicyRepresentation();
policy.setId(policyModel.getId());
policy.setName(policyModel.getName());
policy.setType(policyModel.getType());
if (!resource.getPolicies().contains(policy)) {
resource.getPolicies().add(policy);
}
}
return resource;
}
}

View file

@ -18,8 +18,16 @@
package org.keycloak.models.utils;
import org.keycloak.authorization.AuthorizationProvider;
import org.keycloak.authorization.AuthorizationProviderFactory;
import org.keycloak.authorization.model.Policy;
import org.keycloak.authorization.model.Resource;
import org.keycloak.authorization.model.ResourceServer;
import org.keycloak.authorization.model.Scope;
import org.keycloak.authorization.store.PolicyStore;
import org.keycloak.authorization.store.ResourceServerStore;
import org.keycloak.authorization.store.ResourceStore;
import org.keycloak.authorization.store.ScopeStore;
import org.keycloak.authorization.store.StoreFactory;
import org.keycloak.common.util.MultivaluedHashMap;
import org.keycloak.component.ComponentModel;
import org.keycloak.hash.Pbkdf2PasswordHashProvider;
@ -84,6 +92,12 @@ import org.keycloak.representations.idm.UserFederationMapperRepresentation;
import org.keycloak.representations.idm.UserFederationProviderRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.representations.idm.authorization.PolicyEnforcementMode;
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
import org.keycloak.representations.idm.authorization.ResourceOwnerRepresentation;
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
import org.keycloak.representations.idm.authorization.ResourceServerRepresentation;
import org.keycloak.representations.idm.authorization.ScopeRepresentation;
import org.keycloak.util.JsonSerialization;
import java.io.IOException;
import java.util.ArrayList;
@ -95,8 +109,8 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import static java.lang.Boolean.TRUE;
import java.util.function.Function;
import java.util.stream.Collectors;
public class RepresentationToModel {
@ -277,6 +291,13 @@ public class RepresentationToModel {
}
}
if (rep.getClients() != null) {
rep.getClients().forEach(clientRepresentation -> {
ClientModel client = newRealm.getClientByClientId(clientRepresentation.getClientId());
importAuthorizationSettings(clientRepresentation, client, session);
});
}
if (rep.getSmtpServer() != null) {
newRealm.setSmtpConfig(new HashMap(rep.getSmtpServer()));
}
@ -1022,22 +1043,6 @@ public class RepresentationToModel {
if (resourceRep.isUseTemplateMappers() != null) client.setUseTemplateMappers(resourceRep.isUseTemplateMappers());
else client.setUseTemplateMappers(resourceRep.getClientTemplate() != null);
boolean createResourceServer = TRUE.equals(resourceRep.getAuthorizationServicesEnabled());
if (createResourceServer) {
AuthorizationProvider provider = session.getProvider(AuthorizationProvider.class);
ResourceServerStore resourceServerStore = provider.getStoreFactory().getResourceServerStore();
client.setServiceAccountsEnabled(true);
client.setBearerOnly(false);
client.setPublicClient(false);
ResourceServer resourceServer = resourceServerStore.create(client.getId());
resourceServer.setAllowRemoteResourceManagement(true);
resourceServer.setPolicyEnforcementMode(PolicyEnforcementMode.ENFORCING);
}
return client;
}
@ -1656,4 +1661,432 @@ public class RepresentationToModel {
model.setName(rep.getName());
return model;
}
public static void importAuthorizationSettings(ClientRepresentation clientRepresentation, ClientModel client, KeycloakSession session) {
if (Boolean.TRUE.equals(clientRepresentation.getAuthorizationServicesEnabled())) {
AuthorizationProviderFactory authorizationFactory = (AuthorizationProviderFactory) session.getKeycloakSessionFactory().getProviderFactory(AuthorizationProvider.class);
AuthorizationProvider authorization = authorizationFactory.create(session, client.getRealm());
client.setServiceAccountsEnabled(true);
client.setBearerOnly(false);
client.setPublicClient(false);
ResourceServerRepresentation rep = clientRepresentation.getAuthorizationSettings();
if (rep == null) {
rep = new ResourceServerRepresentation();
}
rep.setClientId(client.getId());
toModel(rep, authorization);
}
}
public static void toModel(ResourceServerRepresentation rep, AuthorizationProvider authorization) {
ResourceServerStore resourceServerStore = authorization.getStoreFactory().getResourceServerStore();
ResourceServer resourceServer;
ResourceServer existing = resourceServerStore.findByClient(rep.getClientId());
if (existing == null) {
resourceServer = resourceServerStore.create(rep.getClientId());
resourceServer.setAllowRemoteResourceManagement(true);
resourceServer.setPolicyEnforcementMode(PolicyEnforcementMode.ENFORCING);
} else {
resourceServer = existing;
}
resourceServer.setPolicyEnforcementMode(rep.getPolicyEnforcementMode());
resourceServer.setAllowRemoteResourceManagement(rep.isAllowRemoteResourceManagement());
StoreFactory storeFactory = authorization.getStoreFactory();
ScopeStore scopeStore = storeFactory.getScopeStore();
rep.getScopes().forEach(scope -> {
toModel(scope, resourceServer, authorization);
});
KeycloakSession session = authorization.getKeycloakSession();
RealmModel realm = authorization.getRealm();
rep.getResources().forEach(resourceRepresentation -> {
ResourceOwnerRepresentation owner = resourceRepresentation.getOwner();
if (owner == null) {
owner = new ResourceOwnerRepresentation();
resourceRepresentation.setOwner(owner);
}
owner.setId(resourceServer.getClientId());
if (owner.getName() != null) {
UserModel user = session.users().getUserByUsername(owner.getName(), realm);
if (user != null) {
owner.setId(user.getId());
}
}
toModel(resourceRepresentation, resourceServer, authorization);
});
rep.getPolicies().forEach(policyRepresentation -> {
Map<String, String> config = policyRepresentation.getConfig();
String roles = config.get("roles");
if (roles != null && !roles.isEmpty()) {
try {
List<Map> rolesMap = JsonSerialization.readValue(roles, List.class);
config.put("roles", JsonSerialization.writeValueAsString(rolesMap.stream().map(roleConfig -> {
String roleName = roleConfig.get("id").toString();
String clientId = null;
int clientIdSeparator = roleName.indexOf("/");
if (clientIdSeparator != -1) {
clientId = roleName.substring(0, clientIdSeparator);
roleName = roleName.substring(clientIdSeparator + 1);
}
RoleModel role;
if (clientId == null) {
role = realm.getRole(roleName);
} else {
role = realm.getClientByClientId(clientId).getRole(roleName);
}
// fallback to find any client role with the given name
if (role == null) {
String finalRoleName = roleName;
role = realm.getClients().stream().map(clientModel -> clientModel.getRole(finalRoleName)).filter(roleModel -> roleModel != null)
.findFirst().orElse(null);
}
if (role == null) {
throw new RuntimeException("Error while importing configuration. Role [" + roleName + "] could not be found.");
}
roleConfig.put("id", role.getId());
return roleConfig;
}).collect(Collectors.toList())));
} catch (Exception e) {
throw new RuntimeException("Error while exporting policy [" + policyRepresentation.getName() + "].", e);
}
}
String users = config.get("users");
if (users != null && !users.isEmpty()) {
try {
List<String> usersMap = JsonSerialization.readValue(users, List.class);
config.put("users", JsonSerialization.writeValueAsString(usersMap.stream().map(userName -> session.users().getUserByUsername(userName, realm).getId()).collect(Collectors.toList())));
} catch (Exception e) {
throw new RuntimeException("Error while exporting policy [" + policyRepresentation.getName() + "].", e);
}
}
String scopes = config.get("scopes");
if (scopes != null && !scopes.isEmpty()) {
try {
List<String> scopesMap = JsonSerialization.readValue(scopes, List.class);
config.put("scopes", JsonSerialization.writeValueAsString(scopesMap.stream().map(scopeName -> {
Scope newScope = scopeStore.findByName(scopeName, resourceServer.getId());
if (newScope == null) {
throw new RuntimeException("Scope with name [" + scopeName + "] not defined.");
}
return newScope.getId();
}).collect(Collectors.toList())));
} catch (Exception e) {
throw new RuntimeException("Error while exporting policy [" + policyRepresentation.getName() + "].", e);
}
}
String policyResources = config.get("resources");
if (policyResources != null && !policyResources.isEmpty()) {
ResourceStore resourceStore = storeFactory.getResourceStore();
try {
List<String> resources = JsonSerialization.readValue(policyResources, List.class);
config.put("resources", JsonSerialization.writeValueAsString(resources.stream().map(resourceName -> {
return resourceStore.findByName(resourceName, resourceServer.getId()).getId();
}).collect(Collectors.toList())));
} catch (Exception e) {
throw new RuntimeException("Error while exporting policy [" + policyRepresentation.getName() + "].", e);
}
}
String applyPolicies = config.get("applyPolicies");
if (applyPolicies != null && !applyPolicies.isEmpty()) {
PolicyStore policyStore = storeFactory.getPolicyStore();
try {
List<String> policies = JsonSerialization.readValue(applyPolicies, List.class);
config.put("applyPolicies", JsonSerialization.writeValueAsString(policies.stream().map(policyName -> {
Policy policy = policyStore.findByName(policyName, resourceServer.getId());
if (policy == null) {
throw new RuntimeException("Policy with name [" + policyName + "] not defined.");
}
return policy.getId();
}).collect(Collectors.toList())));
} catch (Exception e) {
throw new RuntimeException("Error while exporting policy [" + policyRepresentation.getName() + "].", e);
}
}
toModel(policyRepresentation, resourceServer, authorization);
});
}
public static Policy toModel(PolicyRepresentation policy, ResourceServer resourceServer, AuthorizationProvider authorization) {
PolicyStore policyStore = authorization.getStoreFactory().getPolicyStore();
Policy existing;
if (policy.getId() != null) {
existing = policyStore.findById(policy.getId());
} else {
existing = policyStore.findByName(policy.getName(), resourceServer.getId());
}
if (existing != null) {
existing.setName(policy.getName());
existing.setDescription(policy.getDescription());
existing.setConfig(policy.getConfig());
existing.setDecisionStrategy(policy.getDecisionStrategy());
existing.setLogic(policy.getLogic());
updateResources(existing, authorization);
updateAssociatedPolicies(existing, resourceServer, authorization);
updateScopes(existing, authorization);
return existing;
}
Policy model = policyStore.create(policy.getName(), policy.getType(), resourceServer);
model.setDescription(policy.getDescription());
model.setDecisionStrategy(policy.getDecisionStrategy());
model.setLogic(policy.getLogic());
model.setConfig(policy.getConfig());
updateResources(model, authorization);
updateAssociatedPolicies(model, resourceServer, authorization);
updateScopes(model, authorization);
policy.setId(model.getId());
return model;
}
private static void updateScopes(Policy policy, AuthorizationProvider authorization) {
String scopes = policy.getConfig().get("scopes");
if (scopes != null) {
String[] scopeIds;
try {
scopeIds = JsonSerialization.readValue(scopes, String[].class);
} catch (IOException e) {
throw new RuntimeException(e);
}
StoreFactory storeFactory = authorization.getStoreFactory();
for (String scopeId : scopeIds) {
boolean hasScope = false;
for (Scope scopeModel : new HashSet<Scope>(policy.getScopes())) {
if (scopeModel.getId().equals(scopeId)) {
hasScope = true;
}
}
if (!hasScope) {
policy.addScope(storeFactory.getScopeStore().findById(scopeId));
}
}
for (Scope scopeModel : new HashSet<Scope>(policy.getScopes())) {
boolean hasScope = false;
for (String scopeId : scopeIds) {
if (scopeModel.getId().equals(scopeId)) {
hasScope = true;
}
}
if (!hasScope) {
policy.removeScope(scopeModel);
}
}
}
}
private static void updateAssociatedPolicies(Policy policy, ResourceServer resourceServer, AuthorizationProvider authorization) {
String policies = policy.getConfig().get("applyPolicies");
if (policies != null) {
String[] policyIds;
try {
policyIds = JsonSerialization.readValue(policies, String[].class);
} catch (IOException e) {
throw new RuntimeException(e);
}
StoreFactory storeFactory = authorization.getStoreFactory();
PolicyStore policyStore = storeFactory.getPolicyStore();
for (String policyId : policyIds) {
boolean hasPolicy = false;
for (Policy policyModel : new HashSet<Policy>(policy.getAssociatedPolicies())) {
if (policyModel.getId().equals(policyId) || policyModel.getName().equals(policyId)) {
hasPolicy = true;
}
}
if (!hasPolicy) {
Policy associatedPolicy = policyStore.findById(policyId);
if (associatedPolicy == null) {
associatedPolicy = policyStore.findByName(policyId, resourceServer.getId());
}
policy.addAssociatedPolicy(associatedPolicy);
}
}
for (Policy policyModel : new HashSet<Policy>(policy.getAssociatedPolicies())) {
boolean hasPolicy = false;
for (String policyId : policyIds) {
if (policyModel.getId().equals(policyId) || policyModel.getName().equals(policyId)) {
hasPolicy = true;
}
}
if (!hasPolicy) {
policy.removeAssociatedPolicy(policyModel);;
}
}
}
}
private static void updateResources(Policy policy, AuthorizationProvider authorization) {
String resources = policy.getConfig().get("resources");
if (resources != null) {
String[] resourceIds;
try {
resourceIds = JsonSerialization.readValue(resources, String[].class);
} catch (IOException e) {
throw new RuntimeException(e);
}
StoreFactory storeFactory = authorization.getStoreFactory();
for (String resourceId : resourceIds) {
boolean hasResource = false;
for (Resource resourceModel : new HashSet<Resource>(policy.getResources())) {
if (resourceModel.getId().equals(resourceId)) {
hasResource = true;
}
}
if (!hasResource && !"".equals(resourceId)) {
policy.addResource(storeFactory.getResourceStore().findById(resourceId));
}
}
for (Resource resourceModel : new HashSet<Resource>(policy.getResources())) {
boolean hasResource = false;
for (String resourceId : resourceIds) {
if (resourceModel.getId().equals(resourceId)) {
hasResource = true;
}
}
if (!hasResource) {
policy.removeResource(resourceModel);
}
}
}
}
public static Resource toModel(ResourceRepresentation resource, ResourceServer resourceServer, AuthorizationProvider authorization) {
ResourceStore resourceStore = authorization.getStoreFactory().getResourceStore();
Resource existing;
if (resource.getId() != null) {
existing = resourceStore.findById(resource.getId());
} else {
existing = resourceStore.findByName(resource.getName(), resourceServer.getId());
}
if (existing != null) {
existing.setName(resource.getName());
existing.setType(resource.getType());
existing.setUri(resource.getUri());
existing.setIconUri(resource.getIconUri());
existing.updateScopes(resource.getScopes().stream()
.map((ScopeRepresentation scope) -> toModel(scope, resourceServer, authorization))
.collect(Collectors.toSet()));
return existing;
}
ResourceOwnerRepresentation owner = resource.getOwner();
if (owner == null) {
owner = new ResourceOwnerRepresentation();
owner.setId(resourceServer.getClientId());
}
if (owner.getId() == null) {
throw new RuntimeException("No owner specified for resource [" + resource.getName() + "].");
}
Resource model = resourceStore.create(resource.getName(), resourceServer, owner.getId());
model.setType(resource.getType());
model.setUri(resource.getUri());
model.setIconUri(resource.getIconUri());
Set<ScopeRepresentation> scopes = resource.getScopes();
if (scopes != null) {
model.updateScopes(scopes.stream().map((Function<ScopeRepresentation, Scope>) scope -> toModel(scope, resourceServer, authorization)).collect(Collectors.toSet()));
}
resource.setId(model.getId());
return model;
}
public static Scope toModel(ScopeRepresentation scope, ResourceServer resourceServer, AuthorizationProvider authorization) {
StoreFactory storeFactory = authorization.getStoreFactory();
ScopeStore scopeStore = storeFactory.getScopeStore();
Scope existing;
if (scope.getId() != null) {
existing = scopeStore.findById(scope.getId());
} else {
existing = scopeStore.findByName(scope.getName(), resourceServer.getId());
}
if (existing != null) {
existing.setName(scope.getName());
existing.setIconUri(scope.getIconUri());
return existing;
}
Scope model = scopeStore.create(scope.getName(), resourceServer);
model.setIconUri(scope.getIconUri());
scope.setId(model.getId());
return model;
}
}

View file

@ -22,6 +22,7 @@ import org.keycloak.Config;
import org.keycloak.authorization.store.StoreFactory;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.RealmModel;
import org.keycloak.models.cache.authorization.CachedStoreFactoryProvider;
import java.util.concurrent.Executor;
@ -35,13 +36,7 @@ public class DefaultAuthorizationProviderFactory implements AuthorizationProvide
@Override
public AuthorizationProvider create(KeycloakSession session) {
StoreFactory storeFactory = session.getProvider(CachedStoreFactoryProvider.class);
if (storeFactory == null) {
storeFactory = session.getProvider(StoreFactory.class);
}
return new AuthorizationProvider(session, storeFactory);
return create(session, session.getContext().getRealm());
}
@Override
@ -70,4 +65,15 @@ public class DefaultAuthorizationProviderFactory implements AuthorizationProvide
public String getId() {
return "authorization";
}
}
@Override
public AuthorizationProvider create(KeycloakSession session, RealmModel realm) {
StoreFactory storeFactory = session.getProvider(CachedStoreFactoryProvider.class);
if (storeFactory == null) {
storeFactory = session.getProvider(StoreFactory.class);
}
return new AuthorizationProvider(session, realm, storeFactory);
}
}

View file

@ -90,15 +90,15 @@ public class PolicyEvaluationService {
public void evaluate(PolicyEvaluationRequest evaluationRequest, @Suspended AsyncResponse asyncResponse) {
KeycloakIdentity identity = createIdentity(evaluationRequest);
EvaluationContext evaluationContext = createEvaluationContext(evaluationRequest, identity);
authorization.evaluators().from(createPermissions(evaluationRequest, evaluationContext, authorization), evaluationContext).evaluate(createDecisionCollector(evaluationRequest, authorization, identity, asyncResponse));
authorization.evaluators().from(createPermissions(evaluationRequest, evaluationContext, authorization), evaluationContext).evaluate(createDecisionCollector(authorization, identity, asyncResponse));
}
private DecisionResultCollector createDecisionCollector(PolicyEvaluationRequest evaluationRequest, AuthorizationProvider authorization, KeycloakIdentity identity, AsyncResponse asyncResponse) {
private DecisionResultCollector createDecisionCollector(AuthorizationProvider authorization, KeycloakIdentity identity, AsyncResponse asyncResponse) {
return new DecisionResultCollector() {
@Override
protected void onComplete(List<Result> results) {
try {
asyncResponse.resume(Response.ok(PolicyEvaluationResponse.build(evaluationRequest, results, resourceServer, authorization, identity)).build());
asyncResponse.resume(Response.ok(PolicyEvaluationResponse.build(results, resourceServer, authorization, identity)).build());
} catch (Throwable cause) {
asyncResponse.resume(cause);
}

View file

@ -17,15 +17,11 @@
*/
package org.keycloak.authorization.admin;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.jboss.resteasy.annotations.cache.NoCache;
import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.keycloak.authorization.AuthorizationProvider;
import org.keycloak.authorization.admin.util.Models;
import org.keycloak.authorization.model.Policy;
import org.keycloak.authorization.model.Resource;
import org.keycloak.authorization.model.ResourceServer;
import org.keycloak.authorization.model.Scope;
import org.keycloak.authorization.policy.provider.PolicyProviderAdminService;
import org.keycloak.authorization.policy.provider.PolicyProviderFactory;
import org.keycloak.authorization.store.PolicyStore;
@ -45,11 +41,10 @@ import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import java.io.IOException;
import java.util.HashSet;
import java.util.stream.Collectors;
import static org.keycloak.authorization.admin.util.Models.toRepresentation;
import static org.keycloak.models.utils.ModelToRepresentation.toRepresentation;
import static org.keycloak.models.utils.RepresentationToModel.toModel;
/**
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
@ -72,12 +67,7 @@ public class PolicyService {
@NoCache
public Response create(PolicyRepresentation representation) {
this.auth.requireManage();
Policy policy = Models.toModel(representation, this.resourceServer, authorization);
updateResources(policy, authorization);
updateAssociatedPolicies(policy);
updateScopes(policy, authorization);
Policy policy = toModel(representation, this.resourceServer, authorization);
PolicyProviderAdminService resource = getPolicyProviderAdminResource(policy.getType(), authorization);
if (resource != null) {
@ -108,15 +98,7 @@ public class PolicyService {
return Response.status(Status.NOT_FOUND).build();
}
policy.setName(representation.getName());
policy.setDescription(representation.getDescription());
policy.setConfig(representation.getConfig());
policy.setDecisionStrategy(representation.getDecisionStrategy());
policy.setLogic(representation.getLogic());
updateResources(policy, authorization);
updateAssociatedPolicies(policy);
updateScopes(policy, authorization);
policy = toModel(representation, resourceServer, authorization);
PolicyProviderAdminService resource = getPolicyProviderAdminResource(policy.getType(), authorization);
@ -262,137 +244,4 @@ public class PolicyService {
return null;
}
private void updateScopes(Policy policy, AuthorizationProvider authorization) {
String scopes = policy.getConfig().get("scopes");
if (scopes != null) {
String[] scopeIds;
try {
scopeIds = new ObjectMapper().readValue(scopes, String[].class);
} catch (IOException e) {
throw new RuntimeException(e);
}
StoreFactory storeFactory = authorization.getStoreFactory();
for (String scopeId : scopeIds) {
boolean hasScope = false;
for (Scope scopeModel : new HashSet<Scope>(policy.getScopes())) {
if (scopeModel.getId().equals(scopeId)) {
hasScope = true;
}
}
if (!hasScope) {
policy.addScope(storeFactory.getScopeStore().findById(scopeId));
}
}
for (Scope scopeModel : new HashSet<Scope>(policy.getScopes())) {
boolean hasScope = false;
for (String scopeId : scopeIds) {
if (scopeModel.getId().equals(scopeId)) {
hasScope = true;
}
}
if (!hasScope) {
policy.removeScope(scopeModel);
}
}
}
}
private void updateAssociatedPolicies(Policy policy) {
String policies = policy.getConfig().get("applyPolicies");
if (policies != null) {
String[] policyIds;
try {
policyIds = new ObjectMapper().readValue(policies, String[].class);
} catch (IOException e) {
throw new RuntimeException(e);
}
StoreFactory storeFactory = authorization.getStoreFactory();
PolicyStore policyStore = storeFactory.getPolicyStore();
for (String policyId : policyIds) {
boolean hasPolicy = false;
for (Policy policyModel : new HashSet<Policy>(policy.getAssociatedPolicies())) {
if (policyModel.getId().equals(policyId) || policyModel.getName().equals(policyId)) {
hasPolicy = true;
}
}
if (!hasPolicy) {
Policy associatedPolicy = policyStore.findById(policyId);
if (associatedPolicy == null) {
associatedPolicy = policyStore.findByName(policyId, this.resourceServer.getId());
}
policy.addAssociatedPolicy(associatedPolicy);
}
}
for (Policy policyModel : new HashSet<Policy>(policy.getAssociatedPolicies())) {
boolean hasPolicy = false;
for (String policyId : policyIds) {
if (policyModel.getId().equals(policyId) || policyModel.getName().equals(policyId)) {
hasPolicy = true;
}
}
if (!hasPolicy) {
policy.removeAssociatedPolicy(policyModel);;
}
}
}
}
private void updateResources(Policy policy, AuthorizationProvider authorization) {
String resources = policy.getConfig().get("resources");
if (resources != null) {
String[] resourceIds;
try {
resourceIds = new ObjectMapper().readValue(resources, String[].class);
} catch (IOException e) {
throw new RuntimeException(e);
}
StoreFactory storeFactory = authorization.getStoreFactory();
for (String resourceId : resourceIds) {
boolean hasResource = false;
for (Resource resourceModel : new HashSet<Resource>(policy.getResources())) {
if (resourceModel.getId().equals(resourceId)) {
hasResource = true;
}
}
if (!hasResource && !"".equals(resourceId)) {
policy.addResource(storeFactory.getResourceStore().findById(resourceId));
}
}
for (Resource resourceModel : new HashSet<Resource>(policy.getResources())) {
boolean hasResource = false;
for (String resourceId : resourceIds) {
if (resourceModel.getId().equals(resourceId)) {
hasResource = true;
}
}
if (!hasResource) {
policy.removeResource(resourceModel);
}
}
}
}
}

View file

@ -19,33 +19,25 @@ package org.keycloak.authorization.admin;
import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.keycloak.authorization.AuthorizationProvider;
import org.keycloak.authorization.admin.util.Models;
import org.keycloak.authorization.model.Policy;
import org.keycloak.authorization.model.Resource;
import org.keycloak.authorization.model.ResourceServer;
import org.keycloak.authorization.model.Scope;
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.exportimport.util.ExportUtils;
import org.keycloak.models.ClientModel;
import org.keycloak.models.Constants;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserFederationManager;
import org.keycloak.models.UserModel;
import org.keycloak.models.utils.RepresentationToModel;
import org.keycloak.representations.idm.authorization.DecisionStrategy;
import org.keycloak.representations.idm.authorization.Logic;
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
import org.keycloak.representations.idm.authorization.ResourceOwnerRepresentation;
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
import org.keycloak.representations.idm.authorization.ResourceServerRepresentation;
import org.keycloak.representations.idm.authorization.ScopeRepresentation;
import org.keycloak.services.resources.admin.RealmAuth;
import org.keycloak.util.JsonSerialization;
import javax.management.relation.Role;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
@ -57,14 +49,9 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import static org.keycloak.models.utils.ModelToRepresentation.toRepresentation;
/**
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
@ -73,7 +60,6 @@ public class ResourceServerService {
private final AuthorizationProvider authorization;
private final RealmAuth auth;
private final RealmModel realm;
private final KeycloakSession session;
private ResourceServer resourceServer;
private final ClientModel client;
@ -83,7 +69,6 @@ public class ResourceServerService {
this.session = authorization.getKeycloakSession();
this.client = client;
this.resourceServer = resourceServer;
this.realm = client.getRealm();
this.auth = auth;
}
@ -128,7 +113,7 @@ public class ResourceServerService {
@Produces("application/json")
public Response findById() {
this.auth.requireView();
return Response.ok(Models.toRepresentation(this.resourceServer, this.realm)).build();
return Response.ok(toRepresentation(this.resourceServer, this.client)).build();
}
@Path("/settings")
@ -136,59 +121,7 @@ public class ResourceServerService {
@Produces("application/json")
public Response exportSettings() {
this.auth.requireManage();
StoreFactory storeFactory = authorization.getStoreFactory();
ResourceServerRepresentation settings = Models.toRepresentation(resourceServer, this.realm);
settings.setId(null);
settings.setName(null);
settings.setClientId(null);
List<ResourceRepresentation> resources = storeFactory.getResourceStore().findByResourceServer(resourceServer.getId())
.stream().map(resource -> {
ResourceRepresentation rep = Models.toRepresentation(resource, resourceServer, authorization);
if (rep.getOwner().getId().equals(this.resourceServer.getClientId())) {
rep.setOwner(null);
} else {
rep.getOwner().setId(null);
}
rep.setId(null);
rep.setPolicies(null);
rep.getScopes().forEach(scopeRepresentation -> {
scopeRepresentation.setId(null);
scopeRepresentation.setIconUri(null);
});
return rep;
}).collect(Collectors.toList());
settings.setResources(resources);
List<PolicyRepresentation> policies = new ArrayList<>();
PolicyStore policyStore = storeFactory.getPolicyStore();
policies.addAll(policyStore.findByResourceServer(resourceServer.getId())
.stream().filter(policy -> !policy.getType().equals("resource") && !policy.getType().equals("scope"))
.map(policy -> createPolicyRepresentation(storeFactory, policy)).collect(Collectors.toList()));
policies.addAll(policyStore.findByResourceServer(resourceServer.getId())
.stream().filter(policy -> policy.getType().equals("resource") || policy.getType().equals("scope"))
.map(policy -> createPolicyRepresentation(storeFactory, policy)).collect(Collectors.toList()));
settings.setPolicies(policies);
List<ScopeRepresentation> scopes = storeFactory.getScopeStore().findByResourceServer(resourceServer.getId()).stream().map(scope -> {
ScopeRepresentation rep = Models.toRepresentation(scope, authorization);
rep.setId(null);
rep.setPolicies(null);
rep.setResources(null);
return rep;
}).collect(Collectors.toList());
settings.setScopes(scopes);
return Response.ok(settings).build();
return Response.ok(ExportUtils.exportAuthorizationSettings(session, client)).build();
}
@Path("/import")
@ -197,172 +130,9 @@ public class ResourceServerService {
public Response importSettings(@Context final UriInfo uriInfo, ResourceServerRepresentation rep) throws IOException {
this.auth.requireManage();
resourceServer.setPolicyEnforcementMode(rep.getPolicyEnforcementMode());
resourceServer.setAllowRemoteResourceManagement(rep.isAllowRemoteResourceManagement());
rep.setClientId(client.getId());
StoreFactory storeFactory = authorization.getStoreFactory();
ResourceStore resourceStore = storeFactory.getResourceStore();
ScopeStore scopeStore = storeFactory.getScopeStore();
ScopeService scopeResource = new ScopeService(resourceServer, this.authorization, this.auth);
ResteasyProviderFactory.getInstance().injectProperties(scopeResource);
rep.getScopes().forEach(scope -> {
Scope existing = scopeStore.findByName(scope.getName(), resourceServer.getId());
if (existing != null) {
scopeResource.update(existing.getId(), scope);
} else {
scopeResource.create(scope);
}
});
ResourceSetService resourceSetResource = new ResourceSetService(resourceServer, this.authorization, this.auth);
rep.getResources().forEach(resourceRepresentation -> {
ResourceOwnerRepresentation owner = resourceRepresentation.getOwner();
if (owner == null) {
owner = new ResourceOwnerRepresentation();
}
owner.setId(resourceServer.getClientId());
if (owner.getName() != null) {
UserModel user = this.session.users().getUserByUsername(owner.getName(), this.realm);
if (user != null) {
owner.setId(user.getId());
}
}
Resource existing = resourceStore.findByName(resourceRepresentation.getName(), this.resourceServer.getId());
if (existing != null) {
resourceSetResource.update(existing.getId(), resourceRepresentation);
} else {
resourceSetResource.create(resourceRepresentation);
}
});
PolicyStore policyStore = storeFactory.getPolicyStore();
PolicyService policyResource = new PolicyService(resourceServer, this.authorization, this.auth);
ResteasyProviderFactory.getInstance().injectProperties(policyResource);
rep.getPolicies().forEach(policyRepresentation -> {
Map<String, String> config = policyRepresentation.getConfig();
String roles = config.get("roles");
if (roles != null && !roles.isEmpty()) {
try {
List<Map> rolesMap = JsonSerialization.readValue(roles, List.class);
config.put("roles", JsonSerialization.writeValueAsString(rolesMap.stream().map(roleConfig -> {
String roleName = roleConfig.get("id").toString();
String clientId = null;
int clientIdSeparator = roleName.indexOf("/");
if (clientIdSeparator != -1) {
clientId = roleName.substring(0, clientIdSeparator);
roleName = roleName.substring(clientIdSeparator + 1);
}
RoleModel role;
if (clientId == null) {
role = realm.getRole(roleName);
} else {
role = realm.getClientByClientId(clientId).getRole(roleName);
}
// fallback to find any client role with the given name
if (role == null) {
String finalRoleName = roleName;
role = realm.getClients().stream().map(clientModel -> clientModel.getRole(finalRoleName)).filter(roleModel -> roleModel != null)
.findFirst().orElse(null);
}
if (role == null) {
throw new RuntimeException("Error while importing configuration. Role [" + role + "] could not be found.");
}
roleConfig.put("id", role.getId());
return roleConfig;
}).collect(Collectors.toList())));
} catch (Exception e) {
throw new RuntimeException("Error while exporting policy [" + policyRepresentation.getName() + "].", e);
}
}
String users = config.get("users");
if (users != null && !users.isEmpty()) {
try {
List<String> usersMap = JsonSerialization.readValue(users, List.class);
config.put("users", JsonSerialization.writeValueAsString(usersMap.stream().map(userName -> this.session.users().getUserByUsername(userName, this.realm).getId()).collect(Collectors.toList())));
} catch (Exception e) {
throw new RuntimeException("Error while exporting policy [" + policyRepresentation.getName() + "].", e);
}
}
String scopes = config.get("scopes");
if (scopes != null && !scopes.isEmpty()) {
try {
List<String> scopesMap = JsonSerialization.readValue(scopes, List.class);
config.put("scopes", JsonSerialization.writeValueAsString(scopesMap.stream().map(scopeName -> {
Scope newScope = scopeStore.findByName(scopeName, resourceServer.getId());
if (newScope == null) {
throw new RuntimeException("Scope with name [" + scopeName + "] not defined.");
}
return newScope.getId();
}).collect(Collectors.toList())));
} catch (Exception e) {
throw new RuntimeException("Error while exporting policy [" + policyRepresentation.getName() + "].", e);
}
}
String policyResources = config.get("resources");
if (policyResources != null && !policyResources.isEmpty()) {
try {
List<String> resources = JsonSerialization.readValue(policyResources, List.class);
config.put("resources", JsonSerialization.writeValueAsString(resources.stream().map(resourceName -> storeFactory.getResourceStore().findByName(resourceName, resourceServer.getId()).getId()).collect(Collectors.toList())));
} catch (Exception e) {
throw new RuntimeException("Error while exporting policy [" + policyRepresentation.getName() + "].", e);
}
}
String applyPolicies = config.get("applyPolicies");
if (applyPolicies != null && !applyPolicies.isEmpty()) {
try {
List<String> policies = JsonSerialization.readValue(applyPolicies, List.class);
config.put("applyPolicies", JsonSerialization.writeValueAsString(policies.stream().map(policyName -> {
Policy policy = policyStore.findByName(policyName, resourceServer.getId());
if (policy == null) {
throw new RuntimeException("Policy with name [" + policyName + "] not defined.");
}
return policy.getId();
}).collect(Collectors.toList())));
} catch (Exception e) {
throw new RuntimeException("Error while exporting policy [" + policyRepresentation.getName() + "].", e);
}
}
Policy existing = policyStore.findByName(policyRepresentation.getName(), this.resourceServer.getId());
if (existing != null) {
policyResource.update(existing.getId(), policyRepresentation);
} else {
policyResource.create(policyRepresentation);
}
});
RepresentationToModel.toModel(rep, authorization);
return Response.noContent().build();
}
@ -458,61 +228,4 @@ public class ResourceServerService {
serviceAccount.grantRole(umaProtectionRole);
}
}
private PolicyRepresentation createPolicyRepresentation(StoreFactory storeFactory, Policy policy) {
try {
PolicyRepresentation rep = Models.toRepresentation(policy, authorization);
rep.setId(null);
rep.setDependentPolicies(null);
Map<String, String> config = rep.getConfig();
String roles = config.get("roles");
if (roles != null && !roles.isEmpty()) {
List<Map> rolesMap = JsonSerialization.readValue(roles, List.class);
config.put("roles", JsonSerialization.writeValueAsString(rolesMap.stream().map(roleMap -> {
roleMap.put("id", realm.getRoleById(roleMap.get("id").toString()).getName());
return roleMap;
}).collect(Collectors.toList())));
}
String users = config.get("users");
if (users != null && !users.isEmpty()) {
UserFederationManager userManager = this.session.users();
List<String> userIds = JsonSerialization.readValue(users, List.class);
config.put("users", JsonSerialization.writeValueAsString(userIds.stream().map(userId -> userManager.getUserById(userId, this.realm).getUsername()).collect(Collectors.toList())));
}
String scopes = config.get("scopes");
if (scopes != null && !scopes.isEmpty()) {
ScopeStore scopeStore = storeFactory.getScopeStore();
List<String> scopeIds = JsonSerialization.readValue(scopes, List.class);
config.put("scopes", JsonSerialization.writeValueAsString(scopeIds.stream().map(scopeId -> scopeStore.findById(scopeId).getName()).collect(Collectors.toList())));
}
String policyResources = config.get("resources");
if (policyResources != null && !policyResources.isEmpty()) {
ResourceStore resourceStore = storeFactory.getResourceStore();
List<String> resourceIds = JsonSerialization.readValue(policyResources, List.class);
config.put("resources", JsonSerialization.writeValueAsString(resourceIds.stream().map(resourceId -> resourceStore.findById(resourceId).getName()).collect(Collectors.toList())));
}
Set<Policy> associatedPolicies = policy.getAssociatedPolicies();
if (!associatedPolicies.isEmpty()) {
config.put("applyPolicies", JsonSerialization.writeValueAsString(associatedPolicies.stream().map(associated -> associated.getName()).collect(Collectors.toList())));
}
rep.setAssociatedPolicies(null);
return rep;
} catch (Exception e) {
throw new RuntimeException("Error while exporting policy [" + policy.getName() + "].", e);
}
}
}

View file

@ -19,7 +19,6 @@ package org.keycloak.authorization.admin;
import org.jboss.resteasy.annotations.cache.NoCache;
import org.keycloak.authorization.AuthorizationProvider;
import org.keycloak.authorization.admin.util.Models;
import org.keycloak.authorization.model.Policy;
import org.keycloak.authorization.model.Resource;
import org.keycloak.authorization.model.ResourceServer;
@ -27,7 +26,6 @@ import org.keycloak.authorization.store.PolicyStore;
import org.keycloak.authorization.store.ResourceStore;
import org.keycloak.authorization.store.StoreFactory;
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.RealmAuth;
@ -45,7 +43,8 @@ import javax.ws.rs.core.Response.Status;
import java.util.List;
import java.util.stream.Collectors;
import static org.keycloak.authorization.admin.util.Models.toRepresentation;
import static org.keycloak.models.utils.ModelToRepresentation.toRepresentation;
import static org.keycloak.models.utils.RepresentationToModel.toModel;
/**
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
@ -75,7 +74,7 @@ public class ResourceSetService {
return ErrorResponse.exists("Resource with name [" + resource.getName() + "] already exists.");
}
Resource model = Models.toModel(resource, this.resourceServer, authorization);
Resource model = toModel(resource, this.resourceServer, authorization);
ResourceRepresentation representation = new ResourceRepresentation();
@ -99,14 +98,7 @@ public class ResourceSetService {
return Response.status(Status.NOT_FOUND).build();
}
model.setName(resource.getName());
model.setType(resource.getType());
model.setUri(resource.getUri());
model.setIconUri(resource.getIconUri());
model.updateScopes(resource.getScopes().stream()
.map((ScopeRepresentation scope) -> Models.toModel(scope, this.resourceServer, authorization))
.collect(Collectors.toSet()));
toModel(resource, resourceServer, authorization);
return Response.noContent().build();
}

View file

@ -44,8 +44,8 @@ import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import static org.keycloak.authorization.admin.util.Models.toModel;
import static org.keycloak.authorization.admin.util.Models.toRepresentation;
import static org.keycloak.models.utils.ModelToRepresentation.toRepresentation;
import static org.keycloak.models.utils.RepresentationToModel.toModel;
/**
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
@ -88,8 +88,7 @@ public class ScopeService {
return Response.status(Status.NOT_FOUND).build();
}
model.setName(scope.getName());
model.setIconUri(scope.getIconUri());
toModel(scope, resourceServer, authorization);
return Response.noContent().build();
}

View file

@ -20,7 +20,6 @@ package org.keycloak.authorization.admin.representation;
import org.keycloak.authorization.AuthorizationProvider;
import org.keycloak.authorization.Decision.Effect;
import org.keycloak.authorization.admin.util.Models;
import org.keycloak.authorization.common.KeycloakIdentity;
import org.keycloak.authorization.model.Policy;
import org.keycloak.authorization.model.ResourceServer;
@ -28,6 +27,7 @@ import org.keycloak.authorization.model.Scope;
import org.keycloak.authorization.policy.evaluation.Result;
import org.keycloak.authorization.policy.evaluation.Result.PolicyResult;
import org.keycloak.authorization.util.Permissions;
import org.keycloak.models.utils.ModelToRepresentation;
import org.keycloak.representations.AccessToken;
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
@ -56,7 +56,7 @@ public class PolicyEvaluationResponse {
}
public static PolicyEvaluationResponse build(PolicyEvaluationRequest evaluationRequest, List<Result> results, ResourceServer resourceServer, AuthorizationProvider authorization, KeycloakIdentity identity) {
public static PolicyEvaluationResponse build(List<Result> results, ResourceServer resourceServer, AuthorizationProvider authorization, KeycloakIdentity identity) {
PolicyEvaluationResponse response = new PolicyEvaluationResponse();
List<EvaluationResultRepresentation> resultsRep = new ArrayList<>();
AccessToken accessToken = identity.getAccessToken();
@ -80,21 +80,16 @@ public class PolicyEvaluationResponse {
resultsRep.add(rep);
if (result.getPermission().getResource() != null) {
rep.setResource(Models.toRepresentation(result.getPermission().getResource(), resourceServer, authorization));
rep.setResource(ModelToRepresentation.toRepresentation(result.getPermission().getResource(), resourceServer, authorization));
} else {
ResourceRepresentation resource = new ResourceRepresentation();
resource.setName("Any Resource with Scopes " + result.getPermission().getScopes().stream().map(new Function<Scope, String>() {
@Override
public String apply(Scope scope) {
return scope.getName();
}
}).collect(Collectors.toList()));
resource.setName("Any Resource with Scopes " + result.getPermission().getScopes().stream().map(Scope::getName).collect(Collectors.toList()));
rep.setResource(resource);
}
rep.setScopes(result.getPermission().getScopes().stream().map(scope -> Models.toRepresentation(scope, authorization)).collect(Collectors.toList()));
rep.setScopes(result.getPermission().getScopes().stream().map(scope -> ModelToRepresentation.toRepresentation(scope, authorization)).collect(Collectors.toList()));
List<PolicyResultRepresentation> policies = new ArrayList<>();
@ -163,7 +158,7 @@ public class PolicyEvaluationResponse {
if (policy.getStatus().equals(Effect.DENY)) {
Policy policyModel = authorization.getStoreFactory().getPolicyStore().findById(policy.getPolicy().getId());
for (ScopeRepresentation scope : policyModel.getScopes().stream().map(scopeModel -> Models.toRepresentation(scopeModel, authorization)).collect(Collectors.toList())) {
for (ScopeRepresentation scope : policyModel.getScopes().stream().map(scopeModel -> ModelToRepresentation.toRepresentation(scopeModel, authorization)).collect(Collectors.toList())) {
if (!policy.getScopes().contains(scope)) {
policy.getScopes().add(scope);
}
@ -185,7 +180,7 @@ public class PolicyEvaluationResponse {
private static PolicyResultRepresentation toRepresentation(PolicyResult policy, AuthorizationProvider authorization) {
PolicyResultRepresentation policyResultRep = new PolicyResultRepresentation();
policyResultRep.setPolicy(Models.toRepresentation(policy.getPolicy(), authorization));
policyResultRep.setPolicy(ModelToRepresentation.toRepresentation(policy.getPolicy(), authorization));
policyResultRep.setStatus(policy.getStatus());
policyResultRep.setAssociatedPolicies(policy.getAssociatedPolicies().stream().map(result -> toRepresentation(result, authorization)).collect(Collectors.toList()));

View file

@ -1,321 +0,0 @@
/*
* JBoss, Home of Professional Open Source.
* Copyright 2016 Red Hat, Inc., and individual 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.
*/
package org.keycloak.authorization.admin.util;
import org.keycloak.authorization.AuthorizationProvider;
import org.keycloak.authorization.ErrorCode;
import org.keycloak.authorization.model.Policy;
import org.keycloak.authorization.model.Resource;
import org.keycloak.authorization.model.ResourceServer;
import org.keycloak.authorization.model.Scope;
import org.keycloak.authorization.store.PolicyStore;
import org.keycloak.authorization.store.ResourceServerStore;
import org.keycloak.authorization.store.ResourceStore;
import org.keycloak.authorization.store.StoreFactory;
import org.keycloak.models.ClientModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel;
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
import org.keycloak.representations.idm.authorization.ResourceOwnerRepresentation;
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
import org.keycloak.representations.idm.authorization.ResourceServerRepresentation;
import org.keycloak.representations.idm.authorization.ScopeRepresentation;
import org.keycloak.services.ErrorResponseException;
import org.keycloak.util.JsonSerialization;
import javax.ws.rs.core.Response.Status;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
/**
* Some utility methods to transform models to representations and vice-versa.
*
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
*/
public final class Models {
public static ScopeRepresentation toRepresentation(Scope model, AuthorizationProvider authorizationProvider) {
ScopeRepresentation scope = new ScopeRepresentation();
scope.setId(model.getId());
scope.setName(model.getName());
scope.setIconUri(model.getIconUri());
StoreFactory storeFactory = authorizationProvider.getStoreFactory();
scope.setResources(new ArrayList<>());
storeFactory.getResourceStore().findByScope(model.getId()).forEach(resource -> scope.getResources().add(toRepresentation(resource, resource.getResourceServer(), authorizationProvider)));
PolicyStore policyStore = storeFactory.getPolicyStore();
scope.setPolicies(new ArrayList<>());
policyStore.findByScopeIds(Arrays.asList(model.getId()), model.getResourceServer().getId()).forEach(policyModel -> {
PolicyRepresentation policy = new PolicyRepresentation();
policy.setId(policyModel.getId());
policy.setName(policyModel.getName());
policy.setType(policyModel.getType());
if (!scope.getPolicies().contains(policy)) {
scope.getPolicies().add(policy);
}
});
return scope;
}
public static Scope toModel(ScopeRepresentation scope, ResourceServer resourceServer, AuthorizationProvider authorization) {
StoreFactory storeFactory = authorization.getStoreFactory();
Scope model = storeFactory.getScopeStore().findByName(scope.getName(), resourceServer.getId());
if (model == null) {
model = storeFactory.getScopeStore().create(scope.getName(), resourceServer);
model.setIconUri(scope.getIconUri());
}
return model;
}
public static ResourceServerRepresentation toRepresentation(ResourceServer model, RealmModel realm) {
ResourceServerRepresentation server = new ResourceServerRepresentation();
server.setId(model.getId());
server.setClientId(model.getClientId());
ClientModel clientById = realm.getClientById(model.getClientId());
server.setName(clientById.getClientId());
server.setAllowRemoteResourceManagement(model.isAllowRemoteResourceManagement());
server.setPolicyEnforcementMode(model.getPolicyEnforcementMode());
return server;
}
public static ResourceServer toModel(ResourceServerRepresentation server, AuthorizationProvider authorization) {
RealmModel realm = authorization.getKeycloakSession().getContext().getRealm();
ClientModel client = realm.getClientById(server.getClientId());
if (client == null) {
throw new ErrorResponseException(ErrorCode.INVALID_CLIENT_ID, "Client with id [" + server.getClientId() + "] not found in realm [" + realm.getName() + "].", Status.BAD_REQUEST);
}
if (!client.isServiceAccountsEnabled()) {
throw new ErrorResponseException(ErrorCode.INVALID_CLIENT_ID, "Client with id [" + server.getClientId() + "] must have a service account.", Status.BAD_REQUEST);
}
ResourceServer existingResourceServer = authorization.getStoreFactory().getResourceServerStore().findByClient(client.getId());
if (existingResourceServer != null) {
throw new ErrorResponseException(ErrorCode.INVALID_CLIENT_ID, "Resource server already exists with client id [" + server.getClientId() + "].", Status.BAD_REQUEST);
}
if (server.getName() == null) {
server.setName(client.getName());
}
ResourceServer model = authorization.getStoreFactory().getResourceServerStore().create(client.getId());
model.setAllowRemoteResourceManagement(server.isAllowRemoteResourceManagement());
model.setPolicyEnforcementMode(server.getPolicyEnforcementMode());
return model;
}
public static PolicyRepresentation toRepresentation(Policy model, AuthorizationProvider authorization) {
PolicyRepresentation representation = new PolicyRepresentation();
representation.setId(model.getId());
representation.setName(model.getName());
representation.setDescription(model.getDescription());
representation.setType(model.getType());
representation.setDecisionStrategy(model.getDecisionStrategy());
representation.setLogic(model.getLogic());
representation.setConfig(new HashMap<>(model.getConfig()));
List<Policy> policies = authorization.getStoreFactory().getPolicyStore().findDependentPolicies(model.getId());
representation.setDependentPolicies(policies.stream().map(policy -> {
PolicyRepresentation representation1 = new PolicyRepresentation();
representation1.setId(policy.getId());
representation1.setName(policy.getName());
return representation1;
}).collect(Collectors.toList()));
List<PolicyRepresentation> associatedPolicies = new ArrayList<>();
List<String> obj = model.getAssociatedPolicies().stream().map(policy -> {
PolicyRepresentation representation1 = new PolicyRepresentation();
representation1.setId(policy.getId());
representation1.setName(policy.getName());
representation1.setType(policy.getType());
associatedPolicies.add(representation1);
return policy.getId();
}).collect(Collectors.toList());
representation.setAssociatedPolicies(associatedPolicies);
try {
representation.getConfig().put("applyPolicies", JsonSerialization.writeValueAsString(obj));
} catch (IOException e) {
e.printStackTrace();
}
return representation;
}
public static Policy toModel(PolicyRepresentation policy, ResourceServer resourceServer, AuthorizationProvider authorizationManager) {
Policy model = authorizationManager.getStoreFactory().getPolicyStore().create(policy.getName(), policy.getType(), resourceServer);
model.setDescription(policy.getDescription());
model.setDecisionStrategy(policy.getDecisionStrategy());
model.setLogic(policy.getLogic());
model.setConfig(policy.getConfig());
return model;
}
public static ResourceRepresentation toRepresentation(Resource model, ResourceServer resourceServer, AuthorizationProvider authorization) {
ResourceRepresentation resource = new ResourceRepresentation();
resource.setId(model.getId());
resource.setType(model.getType());
resource.setName(model.getName());
resource.setUri(model.getUri());
resource.setIconUri(model.getIconUri());
ResourceOwnerRepresentation owner = new ResourceOwnerRepresentation();
owner.setId(model.getOwner());
KeycloakSession keycloakSession = authorization.getKeycloakSession();
RealmModel realm = keycloakSession.getContext().getRealm();
if (owner.getId().equals(resourceServer.getClientId())) {
ClientModel clientModel = realm.getClientById(resourceServer.getClientId());
owner.setName(clientModel.getClientId());
} else {
UserModel userModel = keycloakSession.users().getUserById(owner.getId(), realm);
if (userModel == null) {
throw new ErrorResponseException("invalid_owner", "Could not find the user [" + owner.getId() + "] who owns the Resource [" + resource.getId() + "].", Status.BAD_REQUEST);
}
owner.setName(userModel.getUsername());
}
resource.setOwner(owner);
resource.setScopes(model.getScopes().stream().map(model1 -> {
ScopeRepresentation scope = new ScopeRepresentation();
scope.setId(model1.getId());
scope.setName(model1.getName());
String iconUri = model1.getIconUri();
if (iconUri != null) {
scope.setIconUri(iconUri);
}
return scope;
}).collect(Collectors.toSet()));
resource.setTypedScopes(new ArrayList<>());
if (resource.getType() != null) {
ResourceStore resourceStore = authorization.getStoreFactory().getResourceStore();
for (Resource typed : resourceStore.findByType(resource.getType())) {
if (typed.getOwner().equals(resourceServer.getClientId()) && !typed.getId().equals(resource.getId())) {
resource.setTypedScopes(typed.getScopes().stream().map(model1 -> {
ScopeRepresentation scope = new ScopeRepresentation();
scope.setId(model1.getId());
scope.setName(model1.getName());
String iconUri = model1.getIconUri();
if (iconUri != null) {
scope.setIconUri(iconUri);
}
return scope;
}).filter(scopeRepresentation -> !resource.getScopes().contains(scopeRepresentation)).collect(Collectors.toList()));
}
}
}
resource.setPolicies(new ArrayList<>());
Set<Policy> policies = new HashSet<>();
PolicyStore policyStore = authorization.getStoreFactory().getPolicyStore();
policies.addAll(policyStore.findByResource(resource.getId()));
policies.addAll(policyStore.findByResourceType(resource.getType(), resourceServer.getId()));
policies.addAll(policyStore.findByScopeIds(resource.getScopes().stream().map(scope -> scope.getId()).collect(Collectors.toList()), resourceServer.getId()));
for (Policy policyModel : policies) {
PolicyRepresentation policy = new PolicyRepresentation();
policy.setId(policyModel.getId());
policy.setName(policyModel.getName());
policy.setType(policyModel.getType());
if (!resource.getPolicies().contains(policy)) {
resource.getPolicies().add(policy);
}
}
return resource;
}
public static Resource toModel(ResourceRepresentation resource, ResourceServer resourceServer, AuthorizationProvider authorization) {
ResourceOwnerRepresentation owner = resource.getOwner();
if (owner == null) {
owner = new ResourceOwnerRepresentation();
owner.setId(resourceServer.getClientId());
}
if (owner.getId() == null) {
throw new ErrorResponseException("invalid_owner", "No owner specified for resource [" + resource.getName() + "].", Status.BAD_REQUEST);
}
ResourceStore resourceStore = authorization.getStoreFactory().getResourceStore();
Resource model = resourceStore.create(resource.getName(), resourceServer, owner.getId());
model.setType(resource.getType());
model.setUri(resource.getUri());
model.setIconUri(resource.getIconUri());
Set<ScopeRepresentation> scopes = resource.getScopes();
if (scopes != null) {
model.updateScopes(scopes.stream().map((Function<ScopeRepresentation, Scope>) scope -> toModel(scope, resourceServer, authorization)).collect(Collectors.toSet()));
}
return model;
}
}

View file

@ -19,12 +19,12 @@ package org.keycloak.authorization.protection.resource;
import org.keycloak.authorization.AuthorizationProvider;
import org.keycloak.authorization.admin.ResourceSetService;
import org.keycloak.authorization.admin.util.Models;
import org.keycloak.authorization.identity.Identity;
import org.keycloak.authorization.model.ResourceServer;
import org.keycloak.authorization.protection.resource.representation.UmaResourceRepresentation;
import org.keycloak.authorization.protection.resource.representation.UmaScopeRepresentation;
import org.keycloak.authorization.store.StoreFactory;
import org.keycloak.models.utils.ModelToRepresentation;
import org.keycloak.representations.idm.authorization.ResourceOwnerRepresentation;
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
import org.keycloak.representations.idm.authorization.ScopeRepresentation;
@ -133,25 +133,25 @@ public class ResourceService {
if ("name".equals(filterType)) {
resources.addAll(storeFactory.getResourceStore().findByResourceServer(this.resourceServer.getId()).stream().filter(description -> filterValue == null || filterValue.equals(description.getName())).collect(Collectors.toSet()).stream()
.map(resource -> Models.toRepresentation(resource, this.resourceServer, authorization))
.map(resource -> ModelToRepresentation.toRepresentation(resource, this.resourceServer, authorization))
.collect(Collectors.toList()));
} else if ("type".equals(filterType)) {
resources.addAll(storeFactory.getResourceStore().findByResourceServer(this.resourceServer.getId()).stream().filter(description -> filterValue == null || filterValue.equals(description.getType())).collect(Collectors.toSet()).stream()
.map(resource -> Models.toRepresentation(resource, this.resourceServer, authorization))
.map(resource -> ModelToRepresentation.toRepresentation(resource, this.resourceServer, authorization))
.collect(Collectors.toList()));
} else if ("uri".equals(filterType)) {
resources.addAll(storeFactory.getResourceStore().findByResourceServer(this.resourceServer.getId()).stream().filter(description -> filterValue == null || filterValue.equals(description.getUri())).collect(Collectors.toSet()).stream()
.map(resource -> Models.toRepresentation(resource, this.resourceServer, authorization))
.map(resource -> ModelToRepresentation.toRepresentation(resource, this.resourceServer, authorization))
.collect(Collectors.toList()));
} else if ("owner".equals(filterType)) {
resources.addAll(storeFactory.getResourceStore().findByResourceServer(this.resourceServer.getId()).stream().filter(description -> filterValue == null || filterValue.equals(description.getOwner())).collect(Collectors.toSet()).stream()
.map(resource -> Models.toRepresentation(resource, this.resourceServer, authorization))
.map(resource -> ModelToRepresentation.toRepresentation(resource, this.resourceServer, authorization))
.collect(Collectors.toList()));
}
}
} else {
resources = storeFactory.getResourceStore().findByOwner(identity.getId()).stream()
.map(resource -> Models.toRepresentation(resource, this.resourceServer, authorization))
.map(resource -> ModelToRepresentation.toRepresentation(resource, this.resourceServer, authorization))
.collect(Collectors.toSet());
}

View file

@ -22,17 +22,61 @@ import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.keycloak.authorization.AuthorizationProvider;
import org.keycloak.authorization.AuthorizationProviderFactory;
import org.keycloak.authorization.model.Policy;
import org.keycloak.authorization.model.ResourceServer;
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.common.Version;
import org.keycloak.common.util.Base64;
import org.keycloak.common.util.MultivaluedHashMap;
import org.keycloak.component.ComponentModel;
import org.keycloak.models.*;
import org.keycloak.models.ClientModel;
import org.keycloak.models.ClientTemplateModel;
import org.keycloak.models.FederatedIdentityModel;
import org.keycloak.models.GroupModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleContainerModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserConsentModel;
import org.keycloak.models.UserCredentialValueModel;
import org.keycloak.models.UserFederationManager;
import org.keycloak.models.UserModel;
import org.keycloak.models.utils.ModelToRepresentation;
import org.keycloak.representations.idm.*;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.ClientTemplateRepresentation;
import org.keycloak.representations.idm.ComponentExportRepresentation;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.FederatedIdentityRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.RoleRepresentation;
import org.keycloak.representations.idm.RolesRepresentation;
import org.keycloak.representations.idm.ScopeMappingRepresentation;
import org.keycloak.representations.idm.UserConsentRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
import org.keycloak.representations.idm.authorization.ResourceServerRepresentation;
import org.keycloak.representations.idm.authorization.ScopeRepresentation;
import org.keycloak.util.JsonSerialization;
import java.io.IOException;
import java.io.OutputStream;
import java.util.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import static org.keycloak.models.utils.ModelToRepresentation.toRepresentation;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
@ -58,7 +102,7 @@ public class ExportUtils {
List<ClientModel> clients = realm.getClients();
List<ClientRepresentation> clientReps = new ArrayList<>();
for (ClientModel app : clients) {
ClientRepresentation clientRep = exportClient(app);
ClientRepresentation clientRep = exportClient(session, app);
clientReps.add(clientRep);
}
rep.setClients(clientReps);
@ -207,12 +251,137 @@ public class ExportUtils {
* @param client
* @return full ApplicationRepresentation
*/
public static ClientRepresentation exportClient(ClientModel client) {
public static ClientRepresentation exportClient(KeycloakSession session, ClientModel client) {
ClientRepresentation clientRep = ModelToRepresentation.toRepresentation(client);
clientRep.setSecret(client.getSecret());
clientRep.setAuthorizationSettings(exportAuthorizationSettings(session,client));
return clientRep;
}
public static ResourceServerRepresentation exportAuthorizationSettings(KeycloakSession session, ClientModel client) {
AuthorizationProviderFactory providerFactory = (AuthorizationProviderFactory) session.getKeycloakSessionFactory().getProviderFactory(AuthorizationProvider.class);
AuthorizationProvider authorization = providerFactory.create(session, client.getRealm());
StoreFactory storeFactory = authorization.getStoreFactory();
ResourceServer settingsModel = authorization.getStoreFactory().getResourceServerStore().findByClient(client.getId());
if (settingsModel == null) {
return null;
}
ResourceServerRepresentation representation = toRepresentation(settingsModel, client);
representation.setId(null);
representation.setName(null);
representation.setClientId(null);
List<ResourceRepresentation> resources = storeFactory.getResourceStore().findByResourceServer(settingsModel.getId())
.stream().map(resource -> {
ResourceRepresentation rep = toRepresentation(resource, settingsModel, authorization);
if (rep.getOwner().getId().equals(settingsModel.getClientId())) {
rep.setOwner(null);
} else {
rep.getOwner().setId(null);
}
rep.setId(null);
rep.setPolicies(null);
rep.getScopes().forEach(scopeRepresentation -> {
scopeRepresentation.setId(null);
scopeRepresentation.setIconUri(null);
});
return rep;
}).collect(Collectors.toList());
representation.setResources(resources);
List<PolicyRepresentation> policies = new ArrayList<>();
PolicyStore policyStore = storeFactory.getPolicyStore();
policies.addAll(policyStore.findByResourceServer(settingsModel.getId())
.stream().filter(policy -> !policy.getType().equals("resource") && !policy.getType().equals("scope"))
.map(policy -> createPolicyRepresentation(authorization, policy)).collect(Collectors.toList()));
policies.addAll(policyStore.findByResourceServer(settingsModel.getId())
.stream().filter(policy -> policy.getType().equals("resource") || policy.getType().equals("scope"))
.map(policy -> createPolicyRepresentation(authorization, policy)).collect(Collectors.toList()));
representation.setPolicies(policies);
List<ScopeRepresentation> scopes = storeFactory.getScopeStore().findByResourceServer(settingsModel.getId()).stream().map(scope -> {
ScopeRepresentation rep = toRepresentation(scope, authorization);
rep.setId(null);
rep.setPolicies(null);
rep.setResources(null);
return rep;
}).collect(Collectors.toList());
representation.setScopes(scopes);
return representation;
}
private static PolicyRepresentation createPolicyRepresentation(AuthorizationProvider authorizationProvider, Policy policy) {
KeycloakSession session = authorizationProvider.getKeycloakSession();
RealmModel realm = authorizationProvider.getRealm();
StoreFactory storeFactory = authorizationProvider.getStoreFactory();
try {
PolicyRepresentation rep = toRepresentation(policy, authorizationProvider);
rep.setId(null);
rep.setDependentPolicies(null);
Map<String, String> config = rep.getConfig();
String roles = config.get("roles");
if (roles != null && !roles.isEmpty()) {
List<Map> rolesMap = JsonSerialization.readValue(roles, List.class);
config.put("roles", JsonSerialization.writeValueAsString(rolesMap.stream().map(roleMap -> {
roleMap.put("id", realm.getRoleById(roleMap.get("id").toString()).getName());
return roleMap;
}).collect(Collectors.toList())));
}
String users = config.get("users");
if (users != null && !users.isEmpty()) {
UserFederationManager userManager = session.users();
List<String> userIds = JsonSerialization.readValue(users, List.class);
config.put("users", JsonSerialization.writeValueAsString(userIds.stream().map(userId -> userManager.getUserById(userId, realm).getUsername()).collect(Collectors.toList())));
}
String scopes = config.get("scopes");
if (scopes != null && !scopes.isEmpty()) {
ScopeStore scopeStore = storeFactory.getScopeStore();
List<String> scopeIds = JsonSerialization.readValue(scopes, List.class);
config.put("scopes", JsonSerialization.writeValueAsString(scopeIds.stream().map(scopeId -> scopeStore.findById(scopeId).getName()).collect(Collectors.toList())));
}
String policyResources = config.get("resources");
if (policyResources != null && !policyResources.isEmpty()) {
ResourceStore resourceStore = storeFactory.getResourceStore();
List<String> resourceIds = JsonSerialization.readValue(policyResources, List.class);
config.put("resources", JsonSerialization.writeValueAsString(resourceIds.stream().map(resourceId -> resourceStore.findById(resourceId).getName()).collect(Collectors.toList())));
}
Set<Policy> associatedPolicies = policy.getAssociatedPolicies();
if (!associatedPolicies.isEmpty()) {
config.put("applyPolicies", JsonSerialization.writeValueAsString(associatedPolicies.stream().map(associated -> associated.getName()).collect(Collectors.toList())));
}
rep.setAssociatedPolicies(null);
return rep;
} catch (Exception e) {
throw new RuntimeException("Error while exporting policy [" + policy.getName() + "].", e);
}
}
public static List<RoleRepresentation> exportRoles(Collection<RoleModel> roles) {
List<RoleRepresentation> roleReps = new ArrayList<RoleRepresentation>();

View file

@ -733,7 +733,7 @@ public class AccountTest extends TestRealmKeycloakTest {
Assert.assertTrue(applicationsPage.isCurrent());
Map<String, AccountApplicationsPage.AppEntry> apps = applicationsPage.getApplications();
Assert.assertEquals(3, apps.size());
Assert.assertEquals(4, apps.size());
AccountApplicationsPage.AppEntry accountEntry = apps.get("Account");
Assert.assertEquals(2, accountEntry.getRolesAvailable().size());

View file

@ -21,12 +21,16 @@ import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.junit.Test;
import org.keycloak.admin.client.resource.AuthorizationResource;
import org.keycloak.admin.client.resource.ClientResource;
import org.keycloak.admin.client.resource.ClientsResource;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
import org.keycloak.testsuite.adapter.AbstractExampleAdapterTest;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
@ -67,6 +71,21 @@ public abstract class AbstractDefaultAuthzConfigAdapterTest extends AbstractExam
assertTrue(this.driver.getPageSource().contains("Your permissions are"));
assertTrue(this.driver.getPageSource().contains("Default Resource"));
boolean hasDefaultPermission = false;
boolean hasDefaultPolicy = false;
for (PolicyRepresentation policy : getAuthorizationResource().policies().policies()) {
if ("Default Policy".equals(policy.getName())) {
hasDefaultPolicy = true;
}
if ("Default Permission".equals(policy.getName())) {
hasDefaultPermission = true;
}
}
assertTrue(hasDefaultPermission);
assertTrue(hasDefaultPolicy);
} finally {
this.deployer.undeploy(RESOURCE_SERVER_ID);
}
@ -95,4 +114,14 @@ public abstract class AbstractDefaultAuthzConfigAdapterTest extends AbstractExam
// enable authorization services in order to generate the default config and continue with tests
clients.get(client.getId()).update(client);
}
private AuthorizationResource getAuthorizationResource() throws FileNotFoundException {
return getClientResource(RESOURCE_SERVER_ID).authorization();
}
private ClientResource getClientResource(String clientId) {
ClientsResource clients = this.realmsResouce().realm(REALM_NAME).clients();
ClientRepresentation resourceServer = clients.findByClientId(clientId).get(0);
return clients.get(resourceServer.getId());
}
}

View file

@ -17,6 +17,7 @@
package org.keycloak.testsuite.admin;
import org.jboss.logging.Logger;
import org.keycloak.admin.client.resource.AuthorizationResource;
import org.keycloak.admin.client.resource.ClientResource;
import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.admin.client.resource.RoleResource;
@ -192,4 +193,13 @@ public class ApiUtil {
}
return contains;
}
public static AuthorizationResource findAuthorizationSettings(RealmResource realm, String clientId) {
for (ClientRepresentation c : realm.clients().findAll()) {
if (c.getClientId().equals(clientId)) {
return realm.clients().get(c.getId()).authorization();
}
}
return null;
}
}

View file

@ -814,7 +814,7 @@ public class UserTest extends AbstractAdminTest {
// List realm roles
assertNames(roles.realmLevel().listAll(), "realm-role", "realm-composite", "user", "offline_access", Constants.AUTHZ_UMA_AUTHORIZATION);
assertNames(roles.realmLevel().listAvailable(), "admin");
assertNames(roles.realmLevel().listAvailable(), "admin", "customer-user-premium");
assertNames(roles.realmLevel().listEffective(), "realm-role", "realm-composite", "realm-child", "user", "offline_access", Constants.AUTHZ_UMA_AUTHORIZATION);
// List client roles

View file

@ -432,7 +432,7 @@ public class GroupTest extends AbstractGroupTest {
// List realm roles
assertNames(roles.realmLevel().listAll(), "realm-role", "realm-composite");
assertNames(roles.realmLevel().listAvailable(), "admin", "offline_access", Constants.AUTHZ_UMA_AUTHORIZATION, "user");
assertNames(roles.realmLevel().listAvailable(), "admin", "offline_access", Constants.AUTHZ_UMA_AUTHORIZATION, "user", "customer-user-premium");
assertNames(roles.realmLevel().listEffective(), "realm-role", "realm-composite", "realm-child");
// List client roles

View file

@ -17,14 +17,18 @@
package org.keycloak.testsuite.exportimport;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Predicate;
import org.junit.Assert;
import org.keycloak.admin.client.Keycloak;
import org.keycloak.admin.client.resource.AuthorizationResource;
import org.keycloak.admin.client.resource.ClientResource;
import org.keycloak.admin.client.resource.ClientTemplateResource;
import org.keycloak.admin.client.resource.RealmResource;
@ -50,6 +54,10 @@ import org.keycloak.representations.idm.RoleRepresentation;
import org.keycloak.representations.idm.UserFederationMapperRepresentation;
import org.keycloak.representations.idm.UserFederationProviderRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
import org.keycloak.representations.idm.authorization.ResourceServerRepresentation;
import org.keycloak.representations.idm.authorization.ScopeRepresentation;
import org.keycloak.testsuite.admin.ApiUtil;
import org.keycloak.testsuite.client.KeycloakTestingClient;
import org.keycloak.testsuite.util.RealmRepUtil;
@ -86,7 +94,7 @@ public class ExportImportUtil {
Assert.assertEquals(0, userRsc.getFederatedIdentity().size());
List<ClientRepresentation> resources = realmRsc.clients().findAll();
Assert.assertEquals(8, resources.size());
Assert.assertEquals(9, resources.size());
// Test applications imported
ClientRepresentation application = ApiUtil.findClientByClientId(realmRsc, "Application").toRepresentation();
@ -97,7 +105,7 @@ public class ExportImportUtil {
Assert.assertNotNull(otherApp);
Assert.assertNull(nonExisting);
List<ClientRepresentation> clients = realmRsc.clients().findAll();
Assert.assertEquals(8, clients.size());
Assert.assertEquals(9, clients.size());
Assert.assertTrue(hasClient(clients, application));
Assert.assertTrue(hasClient(clients, otherApp));
Assert.assertTrue(hasClient(clients, accountApp));
@ -366,6 +374,8 @@ public class ExportImportUtil {
UserRepresentation linked = testingClient.testing().getUserByServiceAccountClient(realm.getRealm(), otherApp.getClientId());//session.users().getUserByServiceAccountClient(otherApp);
Assert.assertNotNull(linked);
Assert.assertEquals("my-service-user", linked.getUsername());
assertAuthorizationSettings(realmRsc);
}
private static boolean isProtocolMapperGranted(Map<String, Object> consent, ProtocolMapperRepresentation mapperRep) {
@ -544,4 +554,89 @@ public class ExportImportUtil {
return false;
}
private static void assertAuthorizationSettings(RealmResource realmRsc) {
AuthorizationResource authzResource = ApiUtil.findAuthorizationSettings(realmRsc, "test-app-authz");
Assert.assertNotNull(authzResource);
List<ResourceRepresentation> resources = authzResource.resources().resources();
Assert.assertEquals(4, resources.size());
ResourceServerRepresentation authzSettings = authzResource.getSettings();
List<Predicate<ResourceRepresentation>> resourcePredicates = new ArrayList<>();
resourcePredicates.add(resourceRep -> {
if ("Admin Resource".equals(resourceRep.getName())) {
Assert.assertEquals(authzSettings.getClientId(), resourceRep.getOwner().getId());
Assert.assertEquals("/protected/admin/*", resourceRep.getUri());
Assert.assertEquals("http://test-app-authz/protected/admin", resourceRep.getType());
Assert.assertEquals("http://icons.com/icon-admin", resourceRep.getIconUri());
Assert.assertEquals(1, resourceRep.getScopes().size());
return true;
}
return false;
});
resourcePredicates.add(resourceRep -> {
if ("Protected Resource".equals(resourceRep.getName())) {
Assert.assertEquals(authzSettings.getClientId(), resourceRep.getOwner().getId());
Assert.assertEquals("/*", resourceRep.getUri());
Assert.assertEquals("http://test-app-authz/protected/resource", resourceRep.getType());
Assert.assertEquals("http://icons.com/icon-resource", resourceRep.getIconUri());
Assert.assertEquals(1, resourceRep.getScopes().size());
return true;
}
return false;
});
resourcePredicates.add(resourceRep -> {
if ("Premium Resource".equals(resourceRep.getName())) {
Assert.assertEquals(authzSettings.getClientId(), resourceRep.getOwner().getId());
Assert.assertEquals("/protected/premium/*", resourceRep.getUri());
Assert.assertEquals("urn:test-app-authz:protected:resource", resourceRep.getType());
Assert.assertEquals("http://icons.com/icon-premium", resourceRep.getIconUri());
Assert.assertEquals(1, resourceRep.getScopes().size());
return true;
}
return false;
});
resourcePredicates.add(resourceRep -> {
if ("Main Page".equals(resourceRep.getName())) {
Assert.assertEquals(authzSettings.getClientId(), resourceRep.getOwner().getId());
Assert.assertNull(resourceRep.getUri());
Assert.assertEquals("urn:test-app-authz:protected:resource", resourceRep.getType());
Assert.assertEquals("http://icons.com/icon-main-page", resourceRep.getIconUri());
Assert.assertEquals(3, resourceRep.getScopes().size());
return true;
}
return false;
});
assertPredicate(resources, resourcePredicates);
List<ScopeRepresentation> scopes = authzResource.scopes().scopes();
Assert.assertEquals(6, scopes.size());
List<Predicate<ScopeRepresentation>> scopePredicates = new ArrayList<>();
scopePredicates.add(scopeRepresentation -> "admin-access".equals(scopeRepresentation.getName()));
scopePredicates.add(scopeRepresentation -> "resource-access".equals(scopeRepresentation.getName()));
scopePredicates.add(scopeRepresentation -> "premium-access".equals(scopeRepresentation.getName()));
scopePredicates.add(scopeRepresentation -> "urn:test-app-authz:page:main:actionForAdmin".equals(scopeRepresentation.getName()));
scopePredicates.add(scopeRepresentation -> "urn:test-app-authz:page:main:actionForUser".equals(scopeRepresentation.getName()));
scopePredicates.add(scopeRepresentation -> "urn:test-app-authz:page:main:actionForPremiumUser".equals(scopeRepresentation.getName()));
assertPredicate(scopes, scopePredicates);
List<PolicyRepresentation> policies = authzResource.policies().policies();
Assert.assertEquals(10, policies.size());
List<Predicate<PolicyRepresentation>> policyPredicates = new ArrayList<>();
policyPredicates.add(policyRepresentation -> "Any Admin Policy".equals(policyRepresentation.getName()));
policyPredicates.add(policyRepresentation -> "Any User Policy".equals(policyRepresentation.getName()));
policyPredicates.add(policyRepresentation -> "Only Premium User Policy".equals(policyRepresentation.getName()));
policyPredicates.add(policyRepresentation -> "All Users Policy".equals(policyRepresentation.getName()));
policyPredicates.add(policyRepresentation -> "Premium Resource Permission".equals(policyRepresentation.getName()));
policyPredicates.add(policyRepresentation -> "Administrative Resource Permission".equals(policyRepresentation.getName()));
policyPredicates.add(policyRepresentation -> "Protected Resource Permission".equals(policyRepresentation.getName()));
policyPredicates.add(policyRepresentation -> "Action 1 on Main Page Resource Permission".equals(policyRepresentation.getName()));
policyPredicates.add(policyRepresentation -> "Action 2 on Main Page Resource Permission".equals(policyRepresentation.getName()));
policyPredicates.add(policyRepresentation -> "Action 3 on Main Page Resource Permission".equals(policyRepresentation.getName()));
assertPredicate(policies, policyPredicates);
}
private static <D> void assertPredicate(List<D> source, List<Predicate<D>> predicate) {
Assert.assertTrue(!source.stream().filter(object -> !predicate.stream().filter(predicate1 -> predicate1.test(object)).findFirst().isPresent()).findAny().isPresent());
}
}

View file

@ -204,6 +204,168 @@
}
}
]
},
{
"clientId": "test-app-authz",
"enabled": true,
"baseUrl": "/test-app-authz",
"adminUrl": "/test-app-authz",
"bearerOnly": false,
"authorizationSettings": {
"allowRemoteResourceManagement": true,
"policyEnforcementMode": "ENFORCING",
"resources": [
{
"name": "Admin Resource",
"uri": "/protected/admin/*",
"type": "http://test-app-authz/protected/admin",
"icon_uri" : "http://icons.com/icon-admin",
"scopes": [
{
"name": "admin-access"
}
]
},
{
"name": "Protected Resource",
"uri": "/*",
"type": "http://test-app-authz/protected/resource",
"icon_uri" : "http://icons.com/icon-resource",
"scopes": [
{
"name": "resource-access"
}
]
},
{
"name": "Premium Resource",
"uri": "/protected/premium/*",
"type": "urn:test-app-authz:protected:resource",
"icon_uri" : "http://icons.com/icon-premium",
"scopes": [
{
"name": "premium-access"
}
]
},
{
"name": "Main Page",
"type": "urn:test-app-authz:protected:resource",
"icon_uri" : "http://icons.com/icon-main-page",
"scopes": [
{
"name": "urn:test-app-authz:page:main:actionForAdmin"
},
{
"name": "urn:test-app-authz:page:main:actionForUser"
},
{
"name": "urn:test-app-authz:page:main:actionForPremiumUser"
}
]
}
],
"policies": [
{
"name": "Any Admin Policy",
"description": "Defines that adminsitrators can do something",
"type": "role",
"config": {
"roles": "[{\"id\":\"admin\"}]"
}
},
{
"name": "Any User Policy",
"description": "Defines that any user can do something",
"type": "role",
"config": {
"roles": "[{\"id\":\"user\"}]"
}
},
{
"name": "Only Premium User Policy",
"description": "Defines that only premium users can do something",
"type": "role",
"logic": "POSITIVE",
"config": {
"roles": "[{\"id\":\"customer-user-premium\"}]"
}
},
{
"name": "All Users Policy",
"description": "Defines that all users can do something",
"type": "aggregate",
"decisionStrategy": "AFFIRMATIVE",
"config": {
"applyPolicies": "[\"Any User Policy\",\"Any Admin Policy\",\"Only Premium User Policy\"]"
}
},
{
"name": "Premium Resource Permission",
"description": "A policy that defines access to premium resources",
"type": "resource",
"decisionStrategy": "UNANIMOUS",
"config": {
"resources": "[\"Premium Resource\"]",
"applyPolicies": "[\"Only Premium User Policy\"]"
}
},
{
"name": "Administrative Resource Permission",
"description": "A policy that defines access to administrative resources",
"type": "resource",
"decisionStrategy": "UNANIMOUS",
"config": {
"resources": "[\"Admin Resource\"]",
"applyPolicies": "[\"Any Admin Policy\"]"
}
},
{
"name": "Protected Resource Permission",
"description": "A policy that defines access to any protected resource",
"type": "resource",
"decisionStrategy": "AFFIRMATIVE",
"config": {
"resources": "[\"Protected Resource\"]",
"applyPolicies": "[\"All Users Policy\"]"
}
},
{
"name": "Action 1 on Main Page Resource Permission",
"description": "A policy that defines access to action 1 on the main page",
"type": "scope",
"decisionStrategy": "AFFIRMATIVE",
"config": {
"scopes": "[\"urn:test-app-authz:page:main:actionForAdmin\"]",
"applyPolicies": "[\"Any Admin Policy\"]"
}
},
{
"name": "Action 2 on Main Page Resource Permission",
"description": "A policy that defines access to action 2 on the main page",
"type": "scope",
"decisionStrategy": "AFFIRMATIVE",
"config": {
"scopes": "[\"urn:test-app-authz:page:main:actionForUser\"]",
"applyPolicies": "[\"Any User Policy\"]"
}
},
{
"name": "Action 3 on Main Page Resource Permission",
"description": "A policy that defines access to action 3 on the main page",
"type": "scope",
"decisionStrategy": "AFFIRMATIVE",
"config": {
"scopes": "[\"urn:test-app-authz:page:main:actionForPremiumUser\"]",
"applyPolicies": "[\"Only Premium User Policy\"]"
}
}
]
},
"redirectUris": [
"/test-app-authz/*"
],
"secret": "secret"
}
],
"oauthClients" : [
@ -239,6 +401,13 @@
"realm" : [
{
"name": "admin"
},
{
"name": "user"
},
{
"name": "customer-user-premium",
"description": "Have User Premium privileges"
}
],
"application" : {

View file

@ -117,6 +117,164 @@
"http://localhost:8180/auth/realms/master/app/*"
],
"secret": "password"
},
{
"clientId": "test-app-authz",
"enabled": true,
"baseUrl": "/test-app-authz",
"adminUrl": "/test-app-authz",
"bearerOnly": false,
"authorizationSettings": {
"allowRemoteResourceManagement": true,
"policyEnforcementMode": "ENFORCING",
"resources": [
{
"name": "Admin Resource",
"uri": "/protected/admin/*",
"type": "http://test-app-authz/protected/admin",
"scopes": [
{
"name": "admin-access"
}
]
},
{
"name": "Protected Resource",
"uri": "/*",
"type": "http://test-app-authz/protected/resource",
"scopes": [
{
"name": "resource-access"
}
]
},
{
"name": "Premium Resource",
"uri": "/protected/premium/*",
"type": "urn:test-app-authz:protected:resource",
"scopes": [
{
"name": "premium-access"
}
]
},
{
"name": "Main Page",
"type": "urn:test-app-authz:protected:resource",
"scopes": [
{
"name": "urn:test-app-authz:page:main:actionForAdmin"
},
{
"name": "urn:test-app-authz:page:main:actionForUser"
},
{
"name": "urn:test-app-authz:page:main:actionForPremiumUser"
}
]
}
],
"policies": [
{
"name": "Any Admin Policy",
"description": "Defines that adminsitrators can do something",
"type": "role",
"config": {
"roles": "[{\"id\":\"admin\"}]"
}
},
{
"name": "Any User Policy",
"description": "Defines that any user can do something",
"type": "role",
"config": {
"roles": "[{\"id\":\"user\"}]"
}
},
{
"name": "Only Premium User Policy",
"description": "Defines that only premium users can do something",
"type": "role",
"logic": "POSITIVE",
"config": {
"roles": "[{\"id\":\"customer-user-premium\"}]"
}
},
{
"name": "All Users Policy",
"description": "Defines that all users can do something",
"type": "aggregate",
"decisionStrategy": "AFFIRMATIVE",
"config": {
"applyPolicies": "[\"Any User Policy\",\"Any Admin Policy\",\"Only Premium User Policy\"]"
}
},
{
"name": "Premium Resource Permission",
"description": "A policy that defines access to premium resources",
"type": "resource",
"decisionStrategy": "UNANIMOUS",
"config": {
"resources": "[\"Premium Resource\"]",
"applyPolicies": "[\"Only Premium User Policy\"]"
}
},
{
"name": "Administrative Resource Permission",
"description": "A policy that defines access to administrative resources",
"type": "resource",
"decisionStrategy": "UNANIMOUS",
"config": {
"resources": "[\"Admin Resource\"]",
"applyPolicies": "[\"Any Admin Policy\"]"
}
},
{
"name": "Protected Resource Permission",
"description": "A policy that defines access to any protected resource",
"type": "resource",
"decisionStrategy": "AFFIRMATIVE",
"config": {
"resources": "[\"Protected Resource\"]",
"applyPolicies": "[\"All Users Policy\"]"
}
},
{
"name": "Action 1 on Main Page Resource Permission",
"description": "A policy that defines access to action 1 on the main page",
"type": "scope",
"decisionStrategy": "AFFIRMATIVE",
"config": {
"scopes": "[\"urn:test-app-authz:page:main:actionForAdmin\"]",
"applyPolicies": "[\"Any Admin Policy\"]"
}
},
{
"name": "Action 2 on Main Page Resource Permission",
"description": "A policy that defines access to action 2 on the main page",
"type": "scope",
"decisionStrategy": "AFFIRMATIVE",
"config": {
"scopes": "[\"urn:test-app-authz:page:main:actionForUser\"]",
"applyPolicies": "[\"Any User Policy\"]"
}
},
{
"name": "Action 3 on Main Page Resource Permission",
"description": "A policy that defines access to action 3 on the main page",
"type": "scope",
"decisionStrategy": "AFFIRMATIVE",
"config": {
"scopes": "[\"urn:test-app-authz:page:main:actionForPremiumUser\"]",
"applyPolicies": "[\"Only Premium User Policy\"]"
}
}
]
},
"redirectUris": [
"/test-app-authz/*"
],
"secret": "secret"
}
],
"roles" : {
@ -128,6 +286,10 @@
{
"name": "admin",
"description": "Have Administrator privileges"
},
{
"name": "customer-user-premium",
"description": "Have User Premium privileges"
}
],
"client" : {