Skip to content

Commit 2050c03

Browse files
committed
Preserve insertion order for claims
1 parent b610b66 commit 2050c03

File tree

2 files changed

+45
-2
lines changed

2 files changed

+45
-2
lines changed

lib/src/main/java/com/auth0/jwt/JWTCreator.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ public static class Builder {
7171
private final Map<String, Object> headerClaims;
7272

7373
Builder() {
74-
this.payloadClaims = new HashMap<>();
75-
this.headerClaims = new HashMap<>();
74+
this.payloadClaims = new LinkedHashMap<>();
75+
this.headerClaims = new LinkedHashMap<>();
7676
}
7777

7878
/**

lib/src/test/java/com/auth0/jwt/JWTCreatorTest.java

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import com.auth0.jwt.interfaces.ECDSAKeyProvider;
55
import com.auth0.jwt.interfaces.RSAKeyProvider;
66
import com.fasterxml.jackson.databind.ObjectMapper;
7+
import com.fasterxml.jackson.databind.node.ObjectNode;
78
import org.junit.Rule;
89
import org.junit.Test;
910
import org.junit.rules.ExpectedException;
@@ -938,4 +939,46 @@ public void shouldCreatePayloadWithNullForList() {
938939
assertThat(jwt, is(notNullValue()));
939940
assertTrue(JWT.decode(jwt).getClaim("name").isNull());
940941
}
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+
}
941984
}

0 commit comments

Comments
 (0)