Do not export ids when exporting authorization settings
Closes #25975 Co-authored-by: 박시준 <sjpark@logblack.com> Signed-off-by: Pedro Igor <pigor.craveiro@gmail.com>
This commit is contained in:
parent
ebeb001fe9
commit
8fb6d43e07
4 changed files with 100 additions and 99 deletions
|
@ -34,3 +34,8 @@ For users of the `keycloak-authz-client` library, calling `AuthorizationResource
|
||||||
Previously, it would return a `List<Map>` at runtime, even though the method declaration advertised `List<Permission>`.
|
Previously, it would return a `List<Map>` at runtime, even though the method declaration advertised `List<Permission>`.
|
||||||
|
|
||||||
This fix will break code that relied on casting the List or its contents to `List<Map>`. If you have used this method in any capacity, you are likely to have done this and be affected.
|
This fix will break code that relied on casting the List or its contents to `List<Map>`. If you have used this method in any capacity, you are likely to have done this and be affected.
|
||||||
|
|
||||||
|
= IDs are no longer set when exporting authorization settings for a client
|
||||||
|
|
||||||
|
When exporting the authorization settings for a client, the IDs for resources, scopes, and policies are no longer set. As a
|
||||||
|
result, you can now import the settings from a client to another client.
|
||||||
|
|
|
@ -1119,6 +1119,8 @@ public class ModelToRepresentation {
|
||||||
.stream().map(resource -> {
|
.stream().map(resource -> {
|
||||||
ResourceRepresentation rep = toRepresentation(resource, settingsModel, authorization);
|
ResourceRepresentation rep = toRepresentation(resource, settingsModel, authorization);
|
||||||
|
|
||||||
|
rep.setId(null);
|
||||||
|
|
||||||
if (rep.getOwner().getId().equals(settingsModel.getClientId())) {
|
if (rep.getOwner().getId().equals(settingsModel.getClientId())) {
|
||||||
rep.setOwner((ResourceOwnerRepresentation) null);
|
rep.setOwner((ResourceOwnerRepresentation) null);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1139,16 +1141,25 @@ public class ModelToRepresentation {
|
||||||
|
|
||||||
policies.addAll(policyStore.findByResourceServer(settingsModel)
|
policies.addAll(policyStore.findByResourceServer(settingsModel)
|
||||||
.stream().filter(policy -> !policy.getType().equals("resource") && !policy.getType().equals("scope") && policy.getOwner() == null)
|
.stream().filter(policy -> !policy.getType().equals("resource") && !policy.getType().equals("scope") && policy.getOwner() == null)
|
||||||
.map(policy -> toRepresentation(authorization, policy)).collect(Collectors.toList()));
|
.map(policy -> {
|
||||||
|
PolicyRepresentation rep = toRepresentation(authorization, policy);
|
||||||
|
rep.setId(null);
|
||||||
|
return rep;
|
||||||
|
}).collect(Collectors.toList()));
|
||||||
policies.addAll(policyStore.findByResourceServer(settingsModel)
|
policies.addAll(policyStore.findByResourceServer(settingsModel)
|
||||||
.stream().filter(policy -> (policy.getType().equals("resource") || policy.getType().equals("scope") && policy.getOwner() == null))
|
.stream().filter(policy -> (policy.getType().equals("resource") || policy.getType().equals("scope") && policy.getOwner() == null))
|
||||||
.map(policy -> toRepresentation(authorization, policy)).collect(Collectors.toList()));
|
.map(policy -> {
|
||||||
|
PolicyRepresentation rep = toRepresentation(authorization, policy);
|
||||||
|
rep.setId(null);
|
||||||
|
return rep;
|
||||||
|
}).collect(Collectors.toList()));
|
||||||
|
|
||||||
representation.setPolicies(policies);
|
representation.setPolicies(policies);
|
||||||
|
|
||||||
List<ScopeRepresentation> scopes = storeFactory.getScopeStore().findByResourceServer(settingsModel).stream().map(scope -> {
|
List<ScopeRepresentation> scopes = storeFactory.getScopeStore().findByResourceServer(settingsModel).stream().map(scope -> {
|
||||||
ScopeRepresentation rep = toRepresentation(scope);
|
ScopeRepresentation rep = toRepresentation(scope);
|
||||||
|
|
||||||
|
rep.setId(null);
|
||||||
rep.setPolicies(null);
|
rep.setPolicies(null);
|
||||||
rep.setResources(null);
|
rep.setResources(null);
|
||||||
|
|
||||||
|
|
|
@ -20,12 +20,19 @@ package org.keycloak.testsuite.authz.admin;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.keycloak.admin.client.resource.AuthorizationResource;
|
import org.keycloak.admin.client.resource.AuthorizationResource;
|
||||||
import org.keycloak.admin.client.resource.ClientsResource;
|
import org.keycloak.admin.client.resource.ClientsResource;
|
||||||
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
import org.keycloak.representations.idm.ClientRepresentation;
|
import org.keycloak.representations.idm.ClientRepresentation;
|
||||||
import org.keycloak.representations.idm.authorization.DecisionStrategy;
|
import org.keycloak.representations.idm.authorization.DecisionStrategy;
|
||||||
import org.keycloak.representations.idm.authorization.PolicyEnforcementMode;
|
import org.keycloak.representations.idm.authorization.PolicyEnforcementMode;
|
||||||
|
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.util.ClientBuilder;
|
||||||
import org.keycloak.util.JsonSerialization;
|
import org.keycloak.util.JsonSerialization;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
|
@ -96,4 +103,57 @@ public class ResourceServerManagementTest extends AbstractAuthorizationTest {
|
||||||
// expected
|
// expected
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testImportSettingsToDifferentClient() throws Exception {
|
||||||
|
ClientsResource clientsResource = testRealmResource().clients();
|
||||||
|
ClientRepresentation clientRep = JsonSerialization.readValue(getClass().getResourceAsStream("/authorization-test/client-with-authz-settings.json"), ClientRepresentation.class);
|
||||||
|
clientRep.setClientId(KeycloakModelUtils.generateId());
|
||||||
|
clientsResource.create(clientRep).close();
|
||||||
|
List<ClientRepresentation> clients = clientsResource.findByClientId(clientRep.getClientId());
|
||||||
|
assertFalse(clients.isEmpty());
|
||||||
|
String clientId = clients.get(0).getId();
|
||||||
|
AuthorizationResource authorization = clientsResource.get(clientId).authorization();
|
||||||
|
ResourceServerRepresentation settings = authorization.exportSettings();
|
||||||
|
assertEquals(PolicyEnforcementMode.PERMISSIVE, settings.getPolicyEnforcementMode());
|
||||||
|
assertEquals(DecisionStrategy.UNANIMOUS, settings.getDecisionStrategy());
|
||||||
|
assertFalse(authorization.resources().findByName("Resource 1").isEmpty());
|
||||||
|
assertFalse(authorization.resources().findByName("Resource 15").isEmpty());
|
||||||
|
assertFalse(authorization.resources().findByName("Resource 20").isEmpty());
|
||||||
|
assertNotNull(authorization.permissions().resource().findByName("Resource 15 Permission"));
|
||||||
|
assertNotNull(authorization.policies().role().findByName("Resource 1 Policy"));
|
||||||
|
settings.getPolicies().removeIf(p -> "js".equals(p.getType()));
|
||||||
|
|
||||||
|
ClientRepresentation anotherClientRep = ClientBuilder.create().clientId(KeycloakModelUtils.generateId()).secret("secret").authorizationServicesEnabled(true).serviceAccount().enabled(true).build();
|
||||||
|
clientsResource.create(anotherClientRep).close();
|
||||||
|
clients = clientsResource.findByClientId(anotherClientRep.getClientId());
|
||||||
|
assertFalse(clients.isEmpty());
|
||||||
|
ClientRepresentation anotherClient = clients.get(0);
|
||||||
|
authorization = clientsResource.get(anotherClient.getId()).authorization();
|
||||||
|
authorization.importSettings(settings);
|
||||||
|
ResourceServerRepresentation anotherSettings = authorization.exportSettings();
|
||||||
|
assertEquals(PolicyEnforcementMode.PERMISSIVE, anotherSettings.getPolicyEnforcementMode());
|
||||||
|
assertEquals(DecisionStrategy.UNANIMOUS, anotherSettings.getDecisionStrategy());
|
||||||
|
assertFalse(authorization.resources().findByName("Resource 1").isEmpty());
|
||||||
|
assertFalse(authorization.resources().findByName("Resource 15").isEmpty());
|
||||||
|
assertFalse(authorization.resources().findByName("Resource 20").isEmpty());
|
||||||
|
assertNotNull(authorization.permissions().resource().findByName("Resource 15 Permission"));
|
||||||
|
assertNotNull(authorization.policies().role().findByName("Resource 1 Policy"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testExportSettings() throws Exception {
|
||||||
|
ClientsResource clientsResource = testRealmResource().clients();
|
||||||
|
ClientRepresentation clientRep = JsonSerialization.readValue(getClass().getResourceAsStream("/authorization-test/client-with-authz-settings.json"), ClientRepresentation.class);
|
||||||
|
clientRep.setClientId(KeycloakModelUtils.generateId());
|
||||||
|
clientsResource.create(clientRep).close();
|
||||||
|
List<ClientRepresentation> clients = clientsResource.findByClientId(clientRep.getClientId());
|
||||||
|
assertFalse(clients.isEmpty());
|
||||||
|
String clientId = clients.get(0).getId();
|
||||||
|
AuthorizationResource authorization = clientsResource.get(clientId).authorization();
|
||||||
|
ResourceServerRepresentation settings = authorization.exportSettings();
|
||||||
|
assertFalse(settings.getResources().stream().map(ResourceRepresentation::getId).anyMatch(Objects::nonNull));
|
||||||
|
assertFalse(settings.getScopes().stream().map(ScopeRepresentation::getId).anyMatch(Objects::nonNull));
|
||||||
|
assertFalse(settings.getPolicies().stream().map(PolicyRepresentation::getId).anyMatch(Objects::nonNull));
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -447,202 +447,127 @@
|
||||||
"name": "Resource 1 Policy",
|
"name": "Resource 1 Policy",
|
||||||
"type": "role",
|
"type": "role",
|
||||||
"logic": "POSITIVE",
|
"logic": "POSITIVE",
|
||||||
"decisionStrategy": "UNANIMOUS",
|
"decisionStrategy": "UNANIMOUS"
|
||||||
"config": {
|
|
||||||
"roles": "[{\"id\":\"authz-client/uma_protection\",\"required\":false}]"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Resource 2 Policy",
|
"name": "Resource 2 Policy",
|
||||||
"type": "role",
|
"type": "role",
|
||||||
"logic": "POSITIVE",
|
"logic": "POSITIVE",
|
||||||
"decisionStrategy": "UNANIMOUS",
|
"decisionStrategy": "UNANIMOUS"
|
||||||
"config": {
|
|
||||||
"roles": "[{\"id\":\"authz-client/uma_protection\",\"required\":false}]"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Resource 3 Policy",
|
"name": "Resource 3 Policy",
|
||||||
"type": "role",
|
"type": "role",
|
||||||
"logic": "POSITIVE",
|
"logic": "POSITIVE",
|
||||||
"decisionStrategy": "UNANIMOUS",
|
"decisionStrategy": "UNANIMOUS"
|
||||||
"config": {
|
|
||||||
"roles": "[{\"id\":\"authz-client/uma_protection\",\"required\":false}]"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Resource 4 Policy",
|
"name": "Resource 4 Policy",
|
||||||
"type": "role",
|
"type": "role",
|
||||||
"logic": "POSITIVE",
|
"logic": "POSITIVE",
|
||||||
"decisionStrategy": "UNANIMOUS",
|
"decisionStrategy": "UNANIMOUS"
|
||||||
"config": {
|
|
||||||
"roles": "[{\"id\":\"authz-client/uma_protection\",\"required\":false}]"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Resource 5 Policy",
|
"name": "Resource 5 Policy",
|
||||||
"type": "role",
|
"type": "role",
|
||||||
"logic": "POSITIVE",
|
"logic": "POSITIVE",
|
||||||
"decisionStrategy": "UNANIMOUS",
|
"decisionStrategy": "UNANIMOUS"
|
||||||
"config": {
|
|
||||||
"roles": "[{\"id\":\"authz-client/uma_protection\",\"required\":false}]"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Resource 6 Policy",
|
"name": "Resource 6 Policy",
|
||||||
"type": "role",
|
"type": "role",
|
||||||
"logic": "POSITIVE",
|
"logic": "POSITIVE",
|
||||||
"decisionStrategy": "UNANIMOUS",
|
"decisionStrategy": "UNANIMOUS"
|
||||||
"config": {
|
|
||||||
"roles": "[{\"id\":\"authz-client/uma_protection\",\"required\":false}]"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Resource 7 Policy",
|
"name": "Resource 7 Policy",
|
||||||
"type": "role",
|
"type": "role",
|
||||||
"logic": "POSITIVE",
|
"logic": "POSITIVE",
|
||||||
"decisionStrategy": "UNANIMOUS",
|
"decisionStrategy": "UNANIMOUS"
|
||||||
"config": {
|
|
||||||
"roles": "[{\"id\":\"authz-client/uma_protection\",\"required\":false}]"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Resource 8 Policy",
|
"name": "Resource 8 Policy",
|
||||||
"type": "role",
|
"type": "role",
|
||||||
"logic": "POSITIVE",
|
"logic": "POSITIVE",
|
||||||
"decisionStrategy": "UNANIMOUS",
|
"decisionStrategy": "UNANIMOUS"
|
||||||
"config": {
|
|
||||||
"roles": "[{\"id\":\"authz-client/uma_protection\",\"required\":false}]"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Resource 9 Policy",
|
"name": "Resource 9 Policy",
|
||||||
"type": "role",
|
"type": "role",
|
||||||
"logic": "POSITIVE",
|
"logic": "POSITIVE",
|
||||||
"decisionStrategy": "UNANIMOUS",
|
"decisionStrategy": "UNANIMOUS"
|
||||||
"config": {
|
|
||||||
"roles": "[{\"id\":\"authz-client/uma_protection\",\"required\":false}]"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Resource 10 Policy",
|
"name": "Resource 10 Policy",
|
||||||
"type": "role",
|
"type": "role",
|
||||||
"logic": "POSITIVE",
|
"logic": "POSITIVE",
|
||||||
"decisionStrategy": "UNANIMOUS",
|
"decisionStrategy": "UNANIMOUS"
|
||||||
"config": {
|
|
||||||
"roles": "[{\"id\":\"authz-client/uma_protection\",\"required\":false}]"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Resource 11 Policy",
|
"name": "Resource 11 Policy",
|
||||||
"type": "role",
|
"type": "role",
|
||||||
"logic": "POSITIVE",
|
"logic": "POSITIVE",
|
||||||
"decisionStrategy": "UNANIMOUS",
|
"decisionStrategy": "UNANIMOUS"
|
||||||
"config": {
|
|
||||||
"roles": "[{\"id\":\"authz-client/uma_protection\",\"required\":false}]"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Resource 12 Policy",
|
"name": "Resource 12 Policy",
|
||||||
"type": "role",
|
"type": "role",
|
||||||
"logic": "POSITIVE",
|
"logic": "POSITIVE",
|
||||||
"decisionStrategy": "UNANIMOUS",
|
"decisionStrategy": "UNANIMOUS"
|
||||||
"config": {
|
|
||||||
"roles": "[{\"id\":\"authz-client/uma_protection\",\"required\":false}]"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Resource 13 Policy",
|
"name": "Resource 13 Policy",
|
||||||
"type": "role",
|
"type": "role",
|
||||||
"logic": "POSITIVE",
|
"logic": "POSITIVE",
|
||||||
"decisionStrategy": "UNANIMOUS",
|
"decisionStrategy": "UNANIMOUS"
|
||||||
"config": {
|
|
||||||
"roles": "[{\"id\":\"authz-client/uma_protection\",\"required\":false}]"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Resource 14 Policy",
|
"name": "Resource 14 Policy",
|
||||||
"type": "role",
|
"type": "role",
|
||||||
"logic": "POSITIVE",
|
"logic": "POSITIVE",
|
||||||
"decisionStrategy": "UNANIMOUS",
|
"decisionStrategy": "UNANIMOUS"
|
||||||
"config": {
|
|
||||||
"roles": "[{\"id\":\"authz-client/uma_protection\",\"required\":false}]"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Resource 15 Policy",
|
"name": "Resource 15 Policy",
|
||||||
"type": "role",
|
"type": "role",
|
||||||
"logic": "POSITIVE",
|
"logic": "POSITIVE",
|
||||||
"decisionStrategy": "UNANIMOUS",
|
"decisionStrategy": "UNANIMOUS"
|
||||||
"config": {
|
|
||||||
"roles": "[{\"id\":\"authz-client/uma_protection\",\"required\":false}]"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Resource 16 Policy",
|
"name": "Resource 16 Policy",
|
||||||
"type": "role",
|
"type": "role",
|
||||||
"logic": "POSITIVE",
|
"logic": "POSITIVE",
|
||||||
"decisionStrategy": "UNANIMOUS",
|
"decisionStrategy": "UNANIMOUS"
|
||||||
"config": {
|
|
||||||
"roles": "[{\"id\":\"authz-client/uma_protection\",\"required\":false}]"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Resource 17 Policy",
|
"name": "Resource 17 Policy",
|
||||||
"type": "role",
|
"type": "role",
|
||||||
"logic": "POSITIVE",
|
"logic": "POSITIVE",
|
||||||
"decisionStrategy": "UNANIMOUS",
|
"decisionStrategy": "UNANIMOUS"
|
||||||
"config": {
|
|
||||||
"roles": "[{\"id\":\"authz-client/uma_protection\",\"required\":false}]"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Resource 18 Policy",
|
"name": "Resource 18 Policy",
|
||||||
"type": "role",
|
"type": "role",
|
||||||
"logic": "POSITIVE",
|
"logic": "POSITIVE",
|
||||||
"decisionStrategy": "UNANIMOUS",
|
"decisionStrategy": "UNANIMOUS"
|
||||||
"config": {
|
|
||||||
"roles": "[{\"id\":\"authz-client/uma_protection\",\"required\":false}]"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Resource 19 Policy",
|
"name": "Resource 19 Policy",
|
||||||
"type": "role",
|
"type": "role",
|
||||||
"logic": "POSITIVE",
|
"logic": "POSITIVE",
|
||||||
"decisionStrategy": "UNANIMOUS",
|
"decisionStrategy": "UNANIMOUS"
|
||||||
"config": {
|
|
||||||
"roles": "[{\"id\":\"authz-client/uma_protection\",\"required\":false}]"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Resource 20 Policy",
|
"name": "Resource 20 Policy",
|
||||||
"type": "role",
|
"type": "role",
|
||||||
"logic": "POSITIVE",
|
"logic": "POSITIVE",
|
||||||
"decisionStrategy": "UNANIMOUS",
|
"decisionStrategy": "UNANIMOUS"
|
||||||
"config": {
|
|
||||||
"roles": "[{\"id\":\"authz-client/uma_protection\",\"required\":false}]"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Default Permission",
|
|
||||||
"description": "A permission that applies to the default resource type",
|
|
||||||
"type": "resource",
|
|
||||||
"logic": "POSITIVE",
|
|
||||||
"decisionStrategy": "UNANIMOUS",
|
|
||||||
"config": {
|
|
||||||
"defaultResourceType": "urn:authz-client:resources:default",
|
|
||||||
"applyPolicies": "[\"Default Policy\"]"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Resource 1 Permission",
|
"name": "Resource 1 Permission",
|
||||||
"type": "resource",
|
"type": "resource",
|
||||||
"logic": "POSITIVE",
|
"logic": "POSITIVE",
|
||||||
"decisionStrategy": "UNANIMOUS",
|
"decisionStrategy": "UNANIMOUS"
|
||||||
"config": {
|
|
||||||
"resources": "[\"Resource 1\"]",
|
|
||||||
"applyPolicies": "[\"Resource 1 Policy\"]"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Resource 2 Permission",
|
"name": "Resource 2 Permission",
|
||||||
|
|
Loading…
Reference in a new issue