|
4 | 4 | import com.auth0.jwt.interfaces.ECDSAKeyProvider; |
5 | 5 | import com.auth0.jwt.interfaces.RSAKeyProvider; |
6 | 6 | import com.fasterxml.jackson.databind.ObjectMapper; |
| 7 | +import com.fasterxml.jackson.databind.node.ObjectNode; |
7 | 8 | import org.junit.Rule; |
8 | 9 | import org.junit.Test; |
9 | 10 | import org.junit.rules.ExpectedException; |
@@ -938,4 +939,46 @@ public void shouldCreatePayloadWithNullForList() { |
938 | 939 | assertThat(jwt, is(notNullValue())); |
939 | 940 | assertTrue(JWT.decode(jwt).getClaim("name").isNull()); |
940 | 941 | } |
| 942 | + |
| 943 | + @Test |
| 944 | + public void shouldPreserveInsertionOrder() throws Exception { |
| 945 | + List<String> headerInsertionOrder = new ArrayList<>(); |
| 946 | + Map<String, Object> header = new LinkedHashMap<>(); |
| 947 | + for (int i = 0; i < 10; i++) { |
| 948 | + String key = "h" + i; |
| 949 | + header.put(key, "v" + 1); |
| 950 | + headerInsertionOrder.add(key); |
| 951 | + } |
| 952 | + |
| 953 | + List<String> payloadInsertionOrder = new ArrayList<>(); |
| 954 | + JWTCreator.Builder builder = JWTCreator.init().withHeader(header); |
| 955 | + for (int i = 0; i < 10; i++) { |
| 956 | + String name = "c" + i; |
| 957 | + builder = builder.withClaim(name, "v" + i); |
| 958 | + payloadInsertionOrder.add(name); |
| 959 | + } |
| 960 | + String signed = builder.sign(Algorithm.HMAC256("secret")); |
| 961 | + |
| 962 | + assertThat(signed, is(notNullValue())); |
| 963 | + String[] parts = signed.split("\\."); |
| 964 | + Base64.Decoder urlDecoder = Base64.getUrlDecoder(); |
| 965 | + String headerJson = new String(urlDecoder.decode(parts[0]), StandardCharsets.UTF_8); |
| 966 | + String payloadJson = new String(urlDecoder.decode(parts[1]), StandardCharsets.UTF_8); |
| 967 | + |
| 968 | + ObjectMapper objectMapper = new ObjectMapper(); |
| 969 | + |
| 970 | + List<String> headerFields = new ArrayList<>(); |
| 971 | + objectMapper.readValue(headerJson, ObjectNode.class) |
| 972 | + .fieldNames().forEachRemaining(headerFields::add); |
| 973 | + headerFields.retainAll(headerInsertionOrder); |
| 974 | + assertThat("Header insertion order should be preserved", |
| 975 | + headerFields, is(equalTo(headerInsertionOrder))); |
| 976 | + |
| 977 | + List<String> payloadFields = new ArrayList<>(); |
| 978 | + objectMapper.readValue(payloadJson, ObjectNode.class) |
| 979 | + .fieldNames().forEachRemaining(payloadFields::add); |
| 980 | + payloadFields.retainAll(payloadInsertionOrder); |
| 981 | + assertThat("Claim insertion order should be preserved", |
| 982 | + payloadFields, is(equalTo(payloadInsertionOrder))); |
| 983 | + } |
941 | 984 | } |
0 commit comments