Skip to content

Commit 310d8bd

Browse files
authored
Merge pull request auth0#102 from auth0/rm-pub-claims-from-header
Remove Header's public claims once parsed from the tree
2 parents d8064d2 + cd6b822 commit 310d8bd

File tree

4 files changed

+121
-110
lines changed

4 files changed

+121
-110
lines changed

lib/src/main/java/com/auth0/jwt/impl/HeaderDeserializer.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,19 @@ public HeaderImpl deserialize(JsonParser p, DeserializationContext ctxt) throws
2727
if (tree == null) {
2828
throw new JWTDecodeException("Parsing the Header's JSON resulted on a Null map");
2929
}
30-
return new HeaderImpl(tree);
30+
31+
String algorithm = getString(tree, PublicClaims.ALGORITHM);
32+
String type = getString(tree, PublicClaims.TYPE);
33+
String contentType = getString(tree, PublicClaims.CONTENT_TYPE);
34+
String keyId = getString(tree, PublicClaims.KEY_ID);
35+
return new HeaderImpl(algorithm, type, contentType, keyId, tree);
36+
}
37+
38+
String getString(Map<String, JsonNode> tree, String claimName) {
39+
JsonNode node = tree.remove(claimName);
40+
if (node == null || node.isNull()) {
41+
return null;
42+
}
43+
return node.asText(null);
3144
}
3245
}

lib/src/main/java/com/auth0/jwt/impl/HeaderImpl.java

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,22 @@
99
import java.util.Map;
1010

1111
import static com.auth0.jwt.impl.ClaimImpl.extractClaim;
12-
import static com.auth0.jwt.impl.PublicClaims.*;
1312

1413
/**
1514
* The HeaderImpl class implements the Header interface.
1615
*/
1716
class HeaderImpl implements Header {
17+
private final String algorithm;
18+
private final String type;
19+
private final String contentType;
20+
private final String keyId;
1821
private final Map<String, JsonNode> tree;
1922

20-
HeaderImpl(Map<String, JsonNode> tree) {
23+
HeaderImpl(String algorithm, String type, String contentType, String keyId, Map<String, JsonNode> tree) {
24+
this.algorithm = algorithm;
25+
this.type = type;
26+
this.contentType = contentType;
27+
this.keyId = keyId;
2128
this.tree = Collections.unmodifiableMap(tree == null ? new HashMap<String, JsonNode>() : tree);
2229
}
2330

@@ -27,22 +34,22 @@ Map<String, JsonNode> getTree() {
2734

2835
@Override
2936
public String getAlgorithm() {
30-
return extractClaim(ALGORITHM, tree).asString();
37+
return algorithm;
3138
}
3239

3340
@Override
3441
public String getType() {
35-
return extractClaim(TYPE, tree).asString();
42+
return type;
3643
}
3744

3845
@Override
3946
public String getContentType() {
40-
return extractClaim(CONTENT_TYPE, tree).asString();
47+
return contentType;
4148
}
4249

4350
@Override
4451
public String getKeyId() {
45-
return extractClaim(KEY_ID, tree).asString();
52+
return keyId;
4653
}
4754

4855
@Override

lib/src/test/java/com/auth0/jwt/impl/HeaderDeserializerTest.java

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,28 @@
11
package com.auth0.jwt.impl;
22

33
import com.auth0.jwt.exceptions.JWTDecodeException;
4+
import com.auth0.jwt.interfaces.Header;
5+
import com.fasterxml.jackson.core.JsonFactory;
46
import com.fasterxml.jackson.core.JsonParser;
57
import com.fasterxml.jackson.core.ObjectCodec;
68
import com.fasterxml.jackson.core.type.TypeReference;
79
import com.fasterxml.jackson.databind.DeserializationContext;
810
import com.fasterxml.jackson.databind.JsonDeserializer;
11+
import com.fasterxml.jackson.databind.JsonNode;
12+
import com.fasterxml.jackson.databind.ObjectMapper;
13+
import com.fasterxml.jackson.databind.node.NullNode;
14+
import com.fasterxml.jackson.databind.node.TextNode;
15+
import org.junit.Before;
916
import org.junit.Rule;
1017
import org.junit.Test;
1118
import org.junit.rules.ExpectedException;
1219

20+
import java.io.StringReader;
21+
import java.util.HashMap;
22+
import java.util.Map;
23+
24+
import static org.hamcrest.Matchers.*;
25+
import static org.junit.Assert.assertThat;
1326
import static org.mockito.ArgumentMatchers.any;
1427
import static org.mockito.ArgumentMatchers.eq;
1528
import static org.mockito.Mockito.mock;
@@ -19,6 +32,13 @@ public class HeaderDeserializerTest {
1932

2033
@Rule
2134
public ExpectedException exception = ExpectedException.none();
35+
private HeaderDeserializer deserializer;
36+
37+
38+
@Before
39+
public void setUp() throws Exception {
40+
deserializer = new HeaderDeserializer();
41+
}
2242

2343
@Test
2444
public void shouldThrowOnNullTree() throws Exception {
@@ -36,4 +56,63 @@ public void shouldThrowOnNullTree() throws Exception {
3656
deserializer.deserialize(parser, context);
3757
}
3858

59+
60+
@Test
61+
public void shouldRemoveKnownPublicClaimsFromTree() throws Exception {
62+
String headerJSON = "{\n" +
63+
" \"alg\": \"HS256\",\n" +
64+
" \"typ\": \"jws\",\n" +
65+
" \"cty\": \"content\",\n" +
66+
" \"kid\": \"key\",\n" +
67+
" \"roles\": \"admin\"\n" +
68+
"}";
69+
StringReader reader = new StringReader(headerJSON);
70+
JsonParser jsonParser = new JsonFactory().createParser(reader);
71+
ObjectMapper mapper = new ObjectMapper();
72+
jsonParser.setCodec(mapper);
73+
74+
Header header = deserializer.deserialize(jsonParser, mapper.getDeserializationContext());
75+
76+
assertThat(header, is(notNullValue()));
77+
assertThat(header.getAlgorithm(), is("HS256"));
78+
assertThat(header.getType(), is("jws"));
79+
assertThat(header.getContentType(), is("content"));
80+
assertThat(header.getKeyId(), is("key"));
81+
82+
assertThat(header.getHeaderClaim("roles").asString(), is("admin"));
83+
assertThat(header.getHeaderClaim("alg").isNull(), is(true));
84+
assertThat(header.getHeaderClaim("typ").isNull(), is(true));
85+
assertThat(header.getHeaderClaim("cty").isNull(), is(true));
86+
assertThat(header.getHeaderClaim("kid").isNull(), is(true));
87+
}
88+
89+
@Test
90+
public void shouldGetNullStringWhenParsingNullNode() throws Exception {
91+
Map<String, JsonNode> tree = new HashMap<>();
92+
NullNode node = NullNode.getInstance();
93+
tree.put("key", node);
94+
95+
String text = deserializer.getString(tree, "key");
96+
assertThat(text, is(nullValue()));
97+
}
98+
99+
@Test
100+
public void shouldGetNullStringWhenParsingNull() throws Exception {
101+
Map<String, JsonNode> tree = new HashMap<>();
102+
tree.put("key", null);
103+
104+
String text = deserializer.getString(tree, "key");
105+
assertThat(text, is(nullValue()));
106+
}
107+
108+
@Test
109+
public void shouldGetStringWhenParsingTextNode() throws Exception {
110+
Map<String, JsonNode> tree = new HashMap<>();
111+
TextNode node = new TextNode("something here");
112+
tree.put("key", node);
113+
114+
String text = deserializer.getString(tree, "key");
115+
assertThat(text, is(notNullValue()));
116+
assertThat(text, is("something here"));
117+
}
39118
}

lib/src/test/java/com/auth0/jwt/impl/HeaderImplTest.java

Lines changed: 15 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,14 @@ public class HeaderImplTest {
2323
@Test
2424
public void shouldHaveUnmodifiableTreeWhenInstantiatedWithNonNullTree() throws Exception {
2525
exception.expect(UnsupportedOperationException.class);
26-
HeaderImpl header = new HeaderImpl(new HashMap<String, JsonNode>());
26+
HeaderImpl header = new HeaderImpl(null, null, null, null, new HashMap<String, JsonNode>());
2727
header.getTree().put("something", null);
2828
}
2929

3030
@Test
3131
public void shouldHaveUnmodifiableTreeWhenInstantiatedWithNullTree() throws Exception {
3232
exception.expect(UnsupportedOperationException.class);
33-
HeaderImpl header = new HeaderImpl(null);
33+
HeaderImpl header = new HeaderImpl(null, null, null, null, null);
3434
header.getTree().put("something", null);
3535
}
3636

@@ -39,111 +39,32 @@ public void shouldHaveTree() throws Exception {
3939
HashMap<String, JsonNode> map = new HashMap<>();
4040
JsonNode node = NullNode.getInstance();
4141
map.put("key", node);
42-
HeaderImpl header = new HeaderImpl(map);
42+
HeaderImpl header = new HeaderImpl(null, null, null, null, map);
4343

4444
assertThat(header.getTree(), is(notNullValue()));
4545
assertThat(header.getTree(), is(IsMapContaining.hasEntry("key", node)));
4646
}
4747

4848
@Test
49-
public void shouldGetHS256Algorithm() throws Exception {
50-
JsonNode algNode = new TextNode("HS256");
51-
HashMap<String, JsonNode> tree = new HashMap<>();
52-
tree.put("alg", algNode);
53-
HeaderImpl header = new HeaderImpl(tree);
49+
public void shouldGetAlgorithm() throws Exception {
50+
HeaderImpl header = new HeaderImpl("HS256", null, null, null, null);
5451

5552
assertThat(header, is(notNullValue()));
5653
assertThat(header.getAlgorithm(), is(notNullValue()));
5754
assertThat(header.getAlgorithm(), is("HS256"));
5855
}
5956

60-
@Test
61-
public void shouldGetHS384Algorithm() throws Exception {
62-
JsonNode algNode = new TextNode("HS384");
63-
HashMap<String, JsonNode> tree = new HashMap<>();
64-
tree.put("alg", algNode);
65-
HeaderImpl header = new HeaderImpl(tree);
66-
67-
assertThat(header, is(notNullValue()));
68-
assertThat(header.getAlgorithm(), is(notNullValue()));
69-
assertThat(header.getAlgorithm(), is("HS384"));
70-
}
71-
72-
@Test
73-
public void shouldGetHS512Algorithm() throws Exception {
74-
JsonNode algNode = new TextNode("HS512");
75-
HashMap<String, JsonNode> tree = new HashMap<>();
76-
tree.put("alg", algNode);
77-
HeaderImpl header = new HeaderImpl(tree);
78-
79-
assertThat(header, is(notNullValue()));
80-
assertThat(header.getAlgorithm(), is(notNullValue()));
81-
assertThat(header.getAlgorithm(), is("HS512"));
82-
}
83-
84-
@Test
85-
public void shouldGetRS256Algorithm() throws Exception {
86-
JsonNode algNode = new TextNode("RS256");
87-
HashMap<String, JsonNode> tree = new HashMap<>();
88-
tree.put("alg", algNode);
89-
HeaderImpl header = new HeaderImpl(tree);
90-
91-
assertThat(header, is(notNullValue()));
92-
assertThat(header.getAlgorithm(), is(notNullValue()));
93-
assertThat(header.getAlgorithm(), is("RS256"));
94-
}
95-
96-
@Test
97-
public void shouldGetRS384Algorithm() throws Exception {
98-
JsonNode algNode = new TextNode("RS384");
99-
HashMap<String, JsonNode> tree = new HashMap<>();
100-
tree.put("alg", algNode);
101-
HeaderImpl header = new HeaderImpl(tree);
102-
103-
assertThat(header, is(notNullValue()));
104-
assertThat(header.getAlgorithm(), is(notNullValue()));
105-
assertThat(header.getAlgorithm(), is("RS384"));
106-
}
107-
108-
@Test
109-
public void shouldGetRS512Algorithm() throws Exception {
110-
JsonNode algNode = new TextNode("RS512");
111-
HashMap<String, JsonNode> tree = new HashMap<>();
112-
tree.put("alg", algNode);
113-
HeaderImpl header = new HeaderImpl(tree);
114-
115-
assertThat(header, is(notNullValue()));
116-
assertThat(header.getAlgorithm(), is(notNullValue()));
117-
assertThat(header.getAlgorithm(), is("RS512"));
118-
}
119-
120-
@Test
121-
public void shouldGetNoneAlgorithm() throws Exception {
122-
JsonNode algNode = new TextNode("none");
123-
HashMap<String, JsonNode> tree = new HashMap<>();
124-
tree.put("alg", algNode);
125-
HeaderImpl header = new HeaderImpl(tree);
126-
127-
assertThat(header, is(notNullValue()));
128-
assertThat(header.getAlgorithm(), is(notNullValue()));
129-
assertThat(header.getAlgorithm(), is("none"));
130-
}
131-
13257
@Test
13358
public void shouldGetNullAlgorithmIfMissing() throws Exception {
134-
HashMap<String, JsonNode> tree = new HashMap<>();
135-
HeaderImpl header = new HeaderImpl(tree);
59+
HeaderImpl header = new HeaderImpl(null, null, null, null, null);
13660

13761
assertThat(header, is(notNullValue()));
13862
assertThat(header.getAlgorithm(), is(nullValue()));
13963
}
14064

14165
@Test
14266
public void shouldGetType() throws Exception {
143-
JsonNode typNode = new TextNode("jwt");
144-
HashMap<String, JsonNode> tree = new HashMap<>();
145-
tree.put("typ", typNode);
146-
HeaderImpl header = new HeaderImpl(tree);
67+
HeaderImpl header = new HeaderImpl(null, "jwt", null, null, null);
14768

14869
assertThat(header, is(notNullValue()));
14970
assertThat(header.getType(), is(notNullValue()));
@@ -152,40 +73,32 @@ public void shouldGetType() throws Exception {
15273

15374
@Test
15475
public void shouldGetNullTypeIfMissing() throws Exception {
155-
HashMap<String, JsonNode> tree = new HashMap<>();
156-
HeaderImpl header = new HeaderImpl(tree);
76+
HeaderImpl header = new HeaderImpl(null, null, null, null, null);
15777

15878
assertThat(header, is(notNullValue()));
15979
assertThat(header.getType(), is(nullValue()));
16080
}
16181

16282
@Test
16383
public void shouldGetContentType() throws Exception {
164-
JsonNode ctyNode = new TextNode("jws");
165-
HashMap<String, JsonNode> tree = new HashMap<>();
166-
tree.put("cty", ctyNode);
167-
HeaderImpl header = new HeaderImpl(tree);
84+
HeaderImpl header = new HeaderImpl(null, null, "content", null, null);
16885

16986
assertThat(header, is(notNullValue()));
17087
assertThat(header.getContentType(), is(notNullValue()));
171-
assertThat(header.getContentType(), is("jws"));
88+
assertThat(header.getContentType(), is("content"));
17289
}
17390

17491
@Test
17592
public void shouldGetNullContentTypeIfMissing() throws Exception {
176-
HashMap<String, JsonNode> tree = new HashMap<>();
177-
HeaderImpl header = new HeaderImpl(tree);
93+
HeaderImpl header = new HeaderImpl(null, null, null, null, null);
17894

17995
assertThat(header, is(notNullValue()));
18096
assertThat(header.getContentType(), is(nullValue()));
18197
}
18298

18399
@Test
184100
public void shouldGetKeyId() throws Exception {
185-
JsonNode kidNode = new TextNode("key");
186-
HashMap<String, JsonNode> tree = new HashMap<>();
187-
tree.put("kid", kidNode);
188-
HeaderImpl header = new HeaderImpl(tree);
101+
HeaderImpl header = new HeaderImpl(null, null, null, "key", null);
189102

190103
assertThat(header, is(notNullValue()));
191104
assertThat(header.getKeyId(), is(notNullValue()));
@@ -194,8 +107,7 @@ public void shouldGetKeyId() throws Exception {
194107

195108
@Test
196109
public void shouldGetNullKeyIdIfMissing() throws Exception {
197-
HashMap<String, JsonNode> tree = new HashMap<>();
198-
HeaderImpl header = new HeaderImpl(tree);
110+
HeaderImpl header = new HeaderImpl(null, null, null, null, null);
199111

200112
assertThat(header, is(notNullValue()));
201113
assertThat(header.getKeyId(), is(nullValue()));
@@ -205,7 +117,7 @@ public void shouldGetNullKeyIdIfMissing() throws Exception {
205117
public void shouldGetExtraClaim() throws Exception {
206118
Map<String, JsonNode> tree = new HashMap<>();
207119
tree.put("extraClaim", new TextNode("extraValue"));
208-
HeaderImpl header = new HeaderImpl(tree);
120+
HeaderImpl header = new HeaderImpl(null, null, null, null, tree);
209121

210122
assertThat(header, is(notNullValue()));
211123
assertThat(header.getHeaderClaim("extraClaim"), is(instanceOf(ClaimImpl.class)));
@@ -215,7 +127,7 @@ public void shouldGetExtraClaim() throws Exception {
215127
@Test
216128
public void shouldGetNotNullExtraClaimIfMissing() throws Exception {
217129
Map<String, JsonNode> tree = new HashMap<>();
218-
HeaderImpl header = new HeaderImpl(tree);
130+
HeaderImpl header = new HeaderImpl(null, null, null, null, tree);
219131

220132
assertThat(header, is(notNullValue()));
221133
assertThat(header.getHeaderClaim("missing"), is(notNullValue()));

0 commit comments

Comments
 (0)