Skip to content

Commit 973f989

Browse files
committed
allow to get Claim as custom class
1 parent e53d31d commit 973f989

File tree

6 files changed

+62
-9
lines changed

6 files changed

+62
-9
lines changed

README.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -286,8 +286,6 @@ JWT.require(Algorithm.HMAC256("secret"))
286286
.verify("my.jwt.token");
287287
```
288288

289-
> The value of the custom Claim in all the cases must be of a `Integer`, `Double`, `Date`, `String`, or `Boolean` class.
290-
291289

292290
### Claim Class
293291
The Claim class is a wrapper for the Claim values. It allows you to get the Claim as different class types. The available helpers are:
@@ -299,13 +297,14 @@ The Claim class is a wrapper for the Claim values. It allows you to get the Clai
299297
* **asString()**: Returns the String value or null if it can't be converted.
300298
* **asDate()**: Returns the Date value or null if it can't be converted. This must be a NumericDate (Unix Epoch/Timestamp). Note that the [JWT Standard](https://tools.ietf.org/html/rfc7519#section-2) specified that all the *NumericDate* values must be in seconds.
301299

302-
#### Collections
300+
#### Custom Class and Collections
303301
To obtain a Claim as a Collection you'll need to provide the **Class Type** of the contents to convert from.
304302

303+
* **as(class)**: Returns the value parsed as **Class Type**.
305304
* **asArray(class)**: Returns the value parsed as an Array of elements of type **Class Type**, or null if the value isn't a JSON Array.
306305
* **asList(class)**: Returns the value parsed as a List of elements of type **Class Type**, or null if the value isn't a JSON Array.
307306

308-
If the values inside the JSON Array can't be converted to the given **Class Type**, a `JWTDecodeException` will raise.
307+
If the values can't be converted to the given **Class Type** a `JWTDecodeException` will raise.
309308

310309

311310

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,16 @@ public <T> List<T> asList(Class<T> tClazz) throws JWTDecodeException {
8989
return list;
9090
}
9191

92+
@Override
93+
public <T> T as(Class<T> tClazz) throws JWTDecodeException {
94+
ObjectMapper mapper = new ObjectMapper();
95+
try {
96+
return mapper.treeToValue(data, tClazz);
97+
} catch (JsonProcessingException e) {
98+
throw new JWTDecodeException("Couldn't map the Claim value to " + tClazz.getSimpleName(), e);
99+
}
100+
}
101+
92102
@Override
93103
public boolean isNull() {
94104
return !(data.isArray() || data.canConvertToLong() || data.isTextual() || data.isNumber() || data.isBoolean());

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,9 @@ public <T> T[] asArray(Class<T> tClazz) throws JWTDecodeException {
4949
public <T> List<T> asList(Class<T> tClazz) throws JWTDecodeException {
5050
return null;
5151
}
52+
53+
@Override
54+
public <T> T as(Class<T> tClazz) throws JWTDecodeException {
55+
return null;
56+
}
5257
}

lib/src/main/java/com/auth0/jwt/interfaces/Claim.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,12 @@ public interface Claim {
6969
* @throws JWTDecodeException if the values inside the List can't be converted to a class T.
7070
*/
7171
<T> List<T> asList(Class<T> tClazz) throws JWTDecodeException;
72+
73+
/**
74+
* Get this Claim as a custom type T.
75+
*
76+
* @return the value as instance of T.
77+
* @throws JWTDecodeException if the value can't be converted to a class T.
78+
*/
79+
<T> T as(Class<T> tClazz) throws JWTDecodeException;
7280
}

lib/src/test/java/com/auth0/jwt/impl/HeaderImplTest.java renamed to lib/src/test/java/com/auth0/jwt/impl/BasicHeaderTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
import static org.hamcrest.MatcherAssert.assertThat;
1515
import static org.hamcrest.Matchers.*;
1616

17-
public class HeaderImplTest {
17+
public class BasicHeaderTest {
1818

1919
@Rule
2020
public ExpectedException exception = ExpectedException.none();

lib/src/test/java/com/auth0/jwt/impl/ClaimImplTest.java renamed to lib/src/test/java/com/auth0/jwt/impl/JsonNodeClaimTest.java

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,22 @@
77
import com.fasterxml.jackson.databind.ObjectMapper;
88
import com.fasterxml.jackson.databind.node.MissingNode;
99
import com.fasterxml.jackson.databind.node.NullNode;
10+
import org.hamcrest.collection.IsMapContaining;
1011
import org.junit.Before;
1112
import org.junit.Rule;
1213
import org.junit.Test;
1314
import org.junit.rules.ExpectedException;
1415

15-
import java.util.Arrays;
16-
import java.util.Date;
16+
import java.util.*;
1717

18-
import static com.auth0.jwt.impl.JsonNodeClaim.claimFromNode;
1918
import static com.auth0.jwt.impl.JWTParser.getDefaultObjectMapper;
19+
import static com.auth0.jwt.impl.JsonNodeClaim.claimFromNode;
2020
import static org.hamcrest.Matchers.*;
2121
import static org.hamcrest.core.IsNull.notNullValue;
2222
import static org.hamcrest.core.IsNull.nullValue;
2323
import static org.junit.Assert.assertThat;
2424

25-
public class ClaimImplTest {
25+
public class JsonNodeClaimTest {
2626

2727
private ObjectMapper mapper;
2828
@Rule
@@ -204,6 +204,37 @@ public void shouldThrowIfListClassMismatch() throws Exception {
204204
claim.asList(UserPojo.class);
205205
}
206206

207+
@Test
208+
public void shouldGetCustomClassValue() throws Exception {
209+
JsonNode value = mapper.valueToTree(new UserPojo("john", 123));
210+
Claim claim = claimFromNode(value);
211+
212+
assertThat(claim, is(notNullValue()));
213+
assertThat(claim.as(UserPojo.class).getName(), is("john"));
214+
assertThat(claim.as(UserPojo.class).getId(), is(123));
215+
}
216+
217+
@Test
218+
public void shouldThrowIfCustomClassMismatch() throws Exception {
219+
JsonNode value = mapper.valueToTree(new UserPojo("john", 123));
220+
Claim claim = claimFromNode(value);
221+
222+
exception.expect(JWTDecodeException.class);
223+
claim.as(String.class);
224+
}
225+
226+
@SuppressWarnings("unchecked")
227+
@Test
228+
public void shouldGetAsMapValue() throws Exception {
229+
JsonNode value = mapper.valueToTree(Collections.singletonMap("key", new UserPojo("john", 123)));
230+
Claim claim = claimFromNode(value);
231+
232+
assertThat(claim, is(notNullValue()));
233+
Map map = claim.as(Map.class);
234+
assertThat(((HashMap<String, Object>) map.get("key")), IsMapContaining.hasEntry("name", "john"));
235+
assertThat(((HashMap<String, Object>) map.get("key")), IsMapContaining.hasEntry("id", 123));
236+
}
237+
207238
@Test
208239
public void shouldReturnBaseClaimWhenParsingMissingNode() throws Exception {
209240
JsonNode value = MissingNode.getInstance();

0 commit comments

Comments
 (0)