[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; package org.keycloak.adapters.authorization.util;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import org.keycloak.util.JsonSerialization;
/** /**
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a> * @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
@ -38,14 +40,25 @@ public class JsonUtils {
Iterator<JsonNode> iterator = jsonNode.iterator(); Iterator<JsonNode> iterator = jsonNode.iterator();
while (iterator.hasNext()) { 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) { if (value != null) {
values.add(value); values.add(value);
} }
} }
} else { } else {
String value = jsonNode.textValue(); String value = jsonNode.asText();
if (value != null) { if (value != null) {
values.add(value); 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.apache.http.impl.client.HttpClients;
import org.junit.AfterClass; import org.junit.AfterClass;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import org.keycloak.KeycloakSecurityContext; import org.keycloak.KeycloakSecurityContext;
import org.keycloak.adapters.KeycloakDeployment; import org.keycloak.adapters.KeycloakDeployment;
@ -197,7 +198,7 @@ public class ClaimInformationPointProviderTest extends AbstractKeycloakTest {
headers.put("Content-Type", Arrays.asList("application/json")); headers.put("Content-Type", Arrays.asList("application/json"));
ObjectMapper mapper = JsonSerialization.mapper; 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); TreeNode treeNode = mapper.readTree(parser);
HttpFacade httpFacade = createHttpFacade(headers, new ByteArrayInputStream(treeNode.toString().getBytes())); 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("c-value", claims.get("claim-from-json-body-object").get(0));
assertEquals("d-value2", claims.get("claim-from-json-body-array").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 @Test

View file

@ -32,6 +32,7 @@
"claim-from-secure": "{request.secure}", "claim-from-secure": "{request.secure}",
"claim-from-json-body-object": "{request.body['/a/b/c']}", "claim-from-json-body-object": "{request.body['/a/b/c']}",
"claim-from-json-body-array": "{request.body['/d/1']}", "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-body": "{request.body}",
"claim-from-static-value": "static value", "claim-from-static-value": "static value",
"claim-from-multiple-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", "path": "/http-post-claim-provider",
"claim-information-point": { "claim-information-point": {