|
3 | 3 | import com.auth0.jwt.algorithms.Algorithm;
|
4 | 4 | import com.auth0.jwt.interfaces.ECDSAKeyProvider;
|
5 | 5 | import com.auth0.jwt.interfaces.RSAKeyProvider;
|
6 |
| -import com.fasterxml.jackson.core.JsonProcessingException; |
7 | 6 | import com.fasterxml.jackson.databind.ObjectMapper;
|
| 7 | +import com.fasterxml.jackson.databind.node.ObjectNode; |
8 | 8 | import org.junit.Rule;
|
9 | 9 | import org.junit.Test;
|
10 | 10 | import org.junit.rules.ExpectedException;
|
@@ -1010,4 +1010,51 @@ public void shouldCreatePayloadWithNullForList() {
|
1010 | 1010 | assertThat(jwt, is(notNullValue()));
|
1011 | 1011 | assertTrue(JWT.decode(jwt).getClaim("name").isNull());
|
1012 | 1012 | }
|
| 1013 | + |
| 1014 | + @Test |
| 1015 | + public void shouldPreserveInsertionOrder() throws Exception { |
| 1016 | + String taxonomyJson = "{\"class\": \"mammalia\", \"order\": \"carnivora\", \"family\": \"canidae\", \"genus\": \"vulpes\"}"; |
| 1017 | + List<String> taxonomyClaims = Arrays.asList("class", "order", "family", "genus"); |
| 1018 | + List<String> headerInsertionOrder = new ArrayList<>(taxonomyClaims); |
| 1019 | + Map<String, Object> header = new LinkedHashMap<>(); |
| 1020 | + for (int i = 0; i < 10; i++) { |
| 1021 | + String key = "h" + i; |
| 1022 | + header.put(key, "v" + 1); |
| 1023 | + headerInsertionOrder.add(key); |
| 1024 | + } |
| 1025 | + |
| 1026 | + List<String> payloadInsertionOrder = new ArrayList<>(taxonomyClaims); |
| 1027 | + JWTCreator.Builder builder = JWTCreator.init() |
| 1028 | + .withHeader(taxonomyJson) |
| 1029 | + .withHeader(header) |
| 1030 | + .withPayload(taxonomyJson); |
| 1031 | + for (int i = 0; i < 10; i++) { |
| 1032 | + String name = "c" + i; |
| 1033 | + builder = builder.withClaim(name, "v" + i); |
| 1034 | + payloadInsertionOrder.add(name); |
| 1035 | + } |
| 1036 | + String signed = builder.sign(Algorithm.HMAC256("secret")); |
| 1037 | + |
| 1038 | + assertThat(signed, is(notNullValue())); |
| 1039 | + String[] parts = signed.split("\\."); |
| 1040 | + Base64.Decoder urlDecoder = Base64.getUrlDecoder(); |
| 1041 | + String headerJson = new String(urlDecoder.decode(parts[0]), StandardCharsets.UTF_8); |
| 1042 | + String payloadJson = new String(urlDecoder.decode(parts[1]), StandardCharsets.UTF_8); |
| 1043 | + |
| 1044 | + ObjectMapper objectMapper = new ObjectMapper(); |
| 1045 | + |
| 1046 | + List<String> headerFields = new ArrayList<>(); |
| 1047 | + objectMapper.readValue(headerJson, ObjectNode.class) |
| 1048 | + .fieldNames().forEachRemaining(headerFields::add); |
| 1049 | + headerFields.retainAll(headerInsertionOrder); |
| 1050 | + assertThat("Header insertion order should be preserved", |
| 1051 | + headerFields, is(equalTo(headerInsertionOrder))); |
| 1052 | + |
| 1053 | + List<String> payloadFields = new ArrayList<>(); |
| 1054 | + objectMapper.readValue(payloadJson, ObjectNode.class) |
| 1055 | + .fieldNames().forEachRemaining(payloadFields::add); |
| 1056 | + payloadFields.retainAll(payloadInsertionOrder); |
| 1057 | + assertThat("Claim insertion order should be preserved", |
| 1058 | + payloadFields, is(equalTo(payloadInsertionOrder))); |
| 1059 | + } |
1013 | 1060 | }
|
0 commit comments