[KEYCLOAK-10015] - CIP not properly resolving objects from JSON request body

This commit is contained in:
Pedro Igor 2019-04-09 10:56:10 -03:00 committed by Bruno Oliveira da Silva
parent 5b47df8979
commit c8970c95d5
3 changed files with 76 additions and 3 deletions

View file

@ -16,11 +16,13 @@
*/
package org.keycloak.adapters.authorization.util;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import com.fasterxml.jackson.databind.JsonNode;
import org.keycloak.util.JsonSerialization;
/**
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
@ -38,14 +40,25 @@ public class JsonUtils {
Iterator<JsonNode> iterator = jsonNode.iterator();
while (iterator.hasNext()) {
String value = iterator.next().textValue();
JsonNode node = iterator.next();
String value;
if (node.isObject()) {
try {
value = JsonSerialization.writeValueAsString(node);
} catch (IOException e) {
throw new RuntimeException(e);
}
} else {
value = node.asText();
}
if (value != null) {
values.add(value);
}
}
} else {
String value = jsonNode.textValue();
String value = jsonNode.asText();
if (value != null) {
values.add(value);

View file

@ -44,6 +44,7 @@ import io.undertow.server.handlers.form.FormParserFactory;
import org.apache.http.impl.client.HttpClients;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.keycloak.KeycloakSecurityContext;
import org.keycloak.adapters.KeycloakDeployment;
@ -197,7 +198,7 @@ public class ClaimInformationPointProviderTest extends AbstractKeycloakTest {
headers.put("Content-Type", Arrays.asList("application/json"));
ObjectMapper mapper = JsonSerialization.mapper;
JsonParser parser = mapper.getFactory().createParser("{\"a\": {\"b\": {\"c\": \"c-value\"}}, \"d\": [\"d-value1\", \"d-value2\"]}");
JsonParser parser = mapper.getFactory().createParser("{\"a\": {\"b\": {\"c\": \"c-value\"}}, \"d\": [\"d-value1\", \"d-value2\"], \"e\": {\"number\": 123}}");
TreeNode treeNode = mapper.readTree(parser);
HttpFacade httpFacade = createHttpFacade(headers, new ByteArrayInputStream(treeNode.toString().getBytes()));
@ -205,6 +206,48 @@ public class ClaimInformationPointProviderTest extends AbstractKeycloakTest {
assertEquals("c-value", claims.get("claim-from-json-body-object").get(0));
assertEquals("d-value2", claims.get("claim-from-json-body-array").get(0));
assertEquals("123", claims.get("claim-from-json-body-number").get(0));
}
@Test
public void testBodyJsonObjectClaim() throws Exception {
Map<String, List<String>> headers = new HashMap<>();
headers.put("Content-Type", Arrays.asList("application/json"));
ObjectMapper mapper = JsonSerialization.mapper;
JsonParser parser = mapper.getFactory().createParser("{\"Individual\" : {\n"
+ "\n"
+ " \"Name\": \"John\",\n"
+ "\n"
+ " \"Lastname\": \"Doe\",\n"
+ "\n"
+ " \"individualRoles\" : [ {\n"
+ "\n"
+ " \"roleSpec\": 2342,\n"
+ "\n"
+ " \"roleId\": 4234},\n"
+ "\n"
+ "{\n"
+ "\n"
+ " \"roleSpec\": 4223,\n"
+ "\n"
+ " \"roleId\": 523\n"
+ "\n"
+ " }\n"
+ "\n"
+ " ]\n"
+ "\n"
+ "}}");
TreeNode treeNode = mapper.readTree(parser);
HttpFacade httpFacade = createHttpFacade(headers, new ByteArrayInputStream(treeNode.toString().getBytes()));
Map<String, List<String>> claims = getClaimInformationProviderForPath("/claims-from-body-json-object", "claims").resolve(httpFacade);
assertEquals(1, claims.size());
assertEquals(2, claims.get("individualRoles").size());
assertEquals("{\"roleSpec\":2342,\"roleId\":4234}", claims.get("individualRoles").get(0));
assertEquals("{\"roleSpec\":4223,\"roleId\":523}", claims.get("individualRoles").get(1));
}
@Test

View file

@ -32,6 +32,7 @@
"claim-from-secure": "{request.secure}",
"claim-from-json-body-object": "{request.body['/a/b/c']}",
"claim-from-json-body-array": "{request.body['/d/1']}",
"claim-from-json-body-number": "{request.body['/e/number']}",
"claim-from-body": "{request.body}",
"claim-from-static-value": "static value",
"claim-from-multiple-static-value": ["static", "value"],
@ -39,6 +40,22 @@
}
}
},
{
"path": "/claims-from-body-json-object",
"methods": [
{
"method": "POST",
"scopes": [
"create"
]
}
],
"claim-information-point": {
"claims": {
"individualRoles": "{request.body['/Individual/individualRoles']}"
}
}
},
{
"path": "/http-post-claim-provider",
"claim-information-point": {