0
# Claim Access
1
2
Type-safe claim access system providing comprehensive methods for reading and converting JWT header and payload claims with automatic type conversion and null safety.
3
4
## Capabilities
5
6
### Claim Interface
7
8
Generic interface for accessing claim values with type-safe conversion methods and null checking.
9
10
```java { .api }
11
/**
12
* Generic claim value interface providing type-safe access to JWT claim values
13
*/
14
public interface Claim {
15
/**
16
* Whether this Claim has a null value or not.
17
* @return true if the Claim has a null value, false otherwise
18
*/
19
boolean isNull();
20
21
/**
22
* Whether this Claim is missing or not.
23
* @return true if the Claim is missing (not present in the JWT), false otherwise
24
*/
25
boolean isMissing();
26
27
/**
28
* Get this Claim as a Boolean.
29
* @return the Claim value as a Boolean or null if it can't be converted
30
*/
31
Boolean asBoolean();
32
33
/**
34
* Get this Claim as an Integer.
35
* @return the Claim value as an Integer or null if it can't be converted
36
*/
37
Integer asInt();
38
39
/**
40
* Get this Claim as a Long.
41
* @return the Claim value as a Long or null if it can't be converted
42
*/
43
Long asLong();
44
45
/**
46
* Get this Claim as a Double.
47
* @return the Claim value as a Double or null if it can't be converted
48
*/
49
Double asDouble();
50
51
/**
52
* Get this Claim as a String.
53
* @return the Claim value as a String or null if it can't be converted
54
*/
55
String asString();
56
57
/**
58
* Get this Claim as a Date.
59
* @return the Claim value as a Date or null if it can't be converted
60
*/
61
Date asDate();
62
63
/**
64
* Get this Claim as an Instant.
65
* @return the Claim value as an Instant or null if it can't be converted
66
*/
67
Instant asInstant();
68
69
/**
70
* Get this Claim as an Array of the given type.
71
* @param clazz the expected type of the array elements
72
* @return the Claim value as an Array or null if it can't be converted
73
*/
74
<T> T[] asArray(Class<T> clazz);
75
76
/**
77
* Get this Claim as a List of the given type.
78
* @param clazz the expected type of the list elements
79
* @return the Claim value as a List or null if it can't be converted
80
*/
81
<T> List<T> asList(Class<T> clazz);
82
83
/**
84
* Get this Claim as a Map of String to Object.
85
* @return the Claim value as a Map or null if it can't be converted
86
*/
87
Map<String, Object> asMap();
88
89
/**
90
* Get this Claim as a custom type using Jackson deserialization.
91
* @param clazz the expected type to deserialize to
92
* @return the Claim value as the requested type or null if it can't be converted
93
*/
94
<T> T as(Class<T> clazz);
95
}
96
```
97
98
**Usage Examples:**
99
100
```java
101
import com.auth0.jwt.interfaces.Claim;
102
import java.time.Instant;
103
import java.util.Date;
104
import java.util.List;
105
import java.util.Map;
106
107
DecodedJWT jwt = JWT.decode(token);
108
109
// Basic claim access with null checking
110
Claim roleClaim = jwt.getClaim("role");
111
if (!roleClaim.isMissing() && !roleClaim.isNull()) {
112
String role = roleClaim.asString();
113
System.out.println("User role: " + role);
114
}
115
116
// Type conversion examples
117
Claim ageClaim = jwt.getClaim("age");
118
Integer age = ageClaim.asInt(); // null if not convertible
119
120
Claim activeClaim = jwt.getClaim("isActive");
121
Boolean isActive = activeClaim.asBoolean(); // null if not convertible
122
123
Claim scoreClaim = jwt.getClaim("score");
124
Double score = scoreClaim.asDouble(); // null if not convertible
125
126
// Date handling
127
Claim lastLoginClaim = jwt.getClaim("lastLogin");
128
Date lastLoginDate = lastLoginClaim.asDate();
129
Instant lastLoginInstant = lastLoginClaim.asInstant();
130
131
// Array and List conversion
132
Claim rolesClaim = jwt.getClaim("roles");
133
String[] rolesArray = rolesClaim.asArray(String.class);
134
List<String> rolesList = rolesClaim.asList(String.class);
135
136
Claim scoresClaim = jwt.getClaim("scores");
137
Integer[] scoresArray = scoresClaim.asArray(Integer.class);
138
List<Integer> scoresList = scoresClaim.asList(Integer.class);
139
140
// Map conversion for complex objects
141
Claim metadataClaim = jwt.getClaim("metadata");
142
Map<String, Object> metadata = metadataClaim.asMap();
143
if (metadata != null) {
144
String region = (String) metadata.get("region");
145
Integer tier = (Integer) metadata.get("tier");
146
}
147
148
// Custom type deserialization
149
Claim userClaim = jwt.getClaim("user");
150
User user = userClaim.as(User.class); // Requires User to be JSON-deserializable
151
```
152
153
### Standard Payload Claims
154
155
Access standard JWT registered claims as defined in RFC 7519.
156
157
```java { .api }
158
/**
159
* Getter for the Issuer "iss" claim contained in the Payload.
160
* @return the Issuer value or null if it's not defined in the Payload
161
*/
162
String getIssuer();
163
164
/**
165
* Getter for the Subject "sub" claim contained in the Payload.
166
* @return the Subject value or null if it's not defined in the Payload
167
*/
168
String getSubject();
169
170
/**
171
* Getter for the Audience "aud" claim contained in the Payload.
172
* @return the Audience value as a List or an empty list if it's not defined in the Payload
173
*/
174
List<String> getAudience();
175
176
/**
177
* Getter for the Expires At "exp" claim contained in the Payload.
178
* @return the Expires At value as a Date or null if it's not defined in the Payload
179
*/
180
Date getExpiresAt();
181
182
/**
183
* Getter for the Expires At "exp" claim contained in the Payload as an Instant.
184
* @return the Expires At value as an Instant or null if it's not defined in the Payload
185
*/
186
Instant getExpiresAtAsInstant();
187
188
/**
189
* Getter for the Not Before "nbf" claim contained in the Payload.
190
* @return the Not Before value as a Date or null if it's not defined in the Payload
191
*/
192
Date getNotBefore();
193
194
/**
195
* Getter for the Not Before "nbf" claim contained in the Payload as an Instant.
196
* @return the Not Before value as an Instant or null if it's not defined in the Payload
197
*/
198
Instant getNotBeforeAsInstant();
199
200
/**
201
* Getter for the Issued At "iat" claim contained in the Payload.
202
* @return the Issued At value as a Date or null if it's not defined in the Payload
203
*/
204
Date getIssuedAt();
205
206
/**
207
* Getter for the Issued At "iat" claim contained in the Payload as an Instant.
208
* @return the Issued At value as an Instant or null if it's not defined in the Payload
209
*/
210
Instant getIssuedAtAsInstant();
211
212
/**
213
* Getter for the JWT ID "jti" claim contained in the Payload.
214
* @return the JWT ID value or null if it's not defined in the Payload
215
*/
216
String getId();
217
```
218
219
**Usage Examples:**
220
221
```java
222
DecodedJWT jwt = JWT.decode(token);
223
224
// Standard registered claims
225
String issuer = jwt.getIssuer(); // "iss" - who issued the token
226
String subject = jwt.getSubject(); // "sub" - token subject (usually user ID)
227
List<String> audience = jwt.getAudience(); // "aud" - intended audience
228
String jwtId = jwt.getId(); // "jti" - unique token identifier
229
230
System.out.println("Token issued by: " + issuer);
231
System.out.println("Token subject: " + subject);
232
System.out.println("Token audiences: " + audience);
233
234
// Time-based claims with Date
235
Date expiresAt = jwt.getExpiresAt(); // "exp" - expiration time
236
Date notBefore = jwt.getNotBefore(); // "nbf" - not valid before
237
Date issuedAt = jwt.getIssuedAt(); // "iat" - issued at time
238
239
if (expiresAt != null) {
240
System.out.println("Token expires at: " + expiresAt);
241
boolean isExpired = expiresAt.before(new Date());
242
System.out.println("Token expired: " + isExpired);
243
}
244
245
// Time-based claims with Instant (preferred for modern Java)
246
Instant expiresAtInstant = jwt.getExpiresAtAsInstant();
247
Instant notBeforeInstant = jwt.getNotBeforeAsInstant();
248
Instant issuedAtInstant = jwt.getIssuedAtAsInstant();
249
250
if (expiresAtInstant != null) {
251
boolean isExpired = expiresAtInstant.isBefore(Instant.now());
252
long secondsUntilExpiry = Duration.between(Instant.now(), expiresAtInstant).getSeconds();
253
System.out.println("Seconds until expiry: " + secondsUntilExpiry);
254
}
255
```
256
257
### Custom Claims Access
258
259
Access custom claims from the JWT payload with type-safe conversion.
260
261
```java { .api }
262
/**
263
* Get a custom Claim given its name from the Payload.
264
* @param name the name of the Claim to retrieve
265
* @return a valid Claim instance if the Claim was found or a NullClaim if not
266
*/
267
Claim getClaim(String name);
268
269
/**
270
* Get all Claims contained in the Payload.
271
* @return a Map containing all the custom Claims defined in the token
272
*/
273
Map<String, Claim> getClaims();
274
```
275
276
**Usage Examples:**
277
278
```java
279
DecodedJWT jwt = JWT.decode(token);
280
281
// Single custom claim access
282
Claim roleClaim = jwt.getClaim("role");
283
Claim departmentClaim = jwt.getClaim("department");
284
Claim permissionsClaim = jwt.getClaim("permissions");
285
286
// Safe access with validation
287
if (!roleClaim.isMissing()) {
288
String role = roleClaim.asString();
289
System.out.println("User role: " + role);
290
}
291
292
// Complex custom claim handling
293
Claim levelClaim = jwt.getClaim("level");
294
if (!levelClaim.isMissing() && !levelClaim.isNull()) {
295
Integer level = levelClaim.asInt();
296
if (level != null && level >= 5) {
297
System.out.println("User has administrator privileges");
298
}
299
}
300
301
// Array claims
302
Claim rolesClaim = jwt.getClaim("roles");
303
if (!rolesClaim.isMissing()) {
304
List<String> roles = rolesClaim.asList(String.class);
305
if (roles != null && roles.contains("admin")) {
306
System.out.println("User is an administrator");
307
}
308
}
309
310
// Get all claims for inspection
311
Map<String, Claim> allClaims = jwt.getClaims();
312
System.out.println("Token contains " + allClaims.size() + " claims:");
313
314
for (Map.Entry<String, Claim> entry : allClaims.entrySet()) {
315
String claimName = entry.getKey();
316
Claim claimValue = entry.getValue();
317
318
if (!claimValue.isMissing() && !claimValue.isNull()) {
319
// Convert to string for display (may not always be appropriate)
320
String displayValue = claimValue.asString();
321
System.out.println(" " + claimName + ": " + displayValue);
322
}
323
}
324
```
325
326
### Header Claims Access
327
328
Access JWT header claims including standard header parameters and custom header claims.
329
330
```java { .api }
331
/**
332
* Getter for the Algorithm "alg" claim contained in the Header.
333
* @return the Algorithm defined or null if it's not defined in the Header
334
*/
335
String getAlgorithm();
336
337
/**
338
* Getter for the Type "typ" claim contained in the Header.
339
* @return the Type defined or null if it's not defined in the Header
340
*/
341
String getType();
342
343
/**
344
* Getter for the Content Type "cty" claim contained in the Header.
345
* @return the Content Type defined or null if it's not defined in the Header
346
*/
347
String getContentType();
348
349
/**
350
* Getter for the Key Id "kid" claim contained in the Header.
351
* @return the Key Id defined or null if it's not defined in the Header
352
*/
353
String getKeyId();
354
355
/**
356
* Get a custom Claim given its name from the Header.
357
* @param name the name of the Claim to retrieve
358
* @return a valid Claim instance if the Claim was found or a NullClaim if not
359
*/
360
Claim getHeaderClaim(String name);
361
```
362
363
**Usage Examples:**
364
365
```java
366
DecodedJWT jwt = JWT.decode(token);
367
368
// Standard header claims
369
String algorithm = jwt.getAlgorithm(); // "alg" - signing algorithm
370
String type = jwt.getType(); // "typ" - token type (usually "JWT")
371
String contentType = jwt.getContentType(); // "cty" - content type
372
String keyId = jwt.getKeyId(); // "kid" - key identifier
373
374
System.out.println("Token algorithm: " + algorithm);
375
System.out.println("Token type: " + type);
376
System.out.println("Key ID: " + keyId);
377
378
// Custom header claims
379
Claim customHeaderClaim = jwt.getHeaderClaim("custom");
380
if (!customHeaderClaim.isMissing()) {
381
String customValue = customHeaderClaim.asString();
382
System.out.println("Custom header claim: " + customValue);
383
}
384
385
// Application-specific header claims
386
Claim versionClaim = jwt.getHeaderClaim("version");
387
Claim instanceClaim = jwt.getHeaderClaim("instance");
388
389
if (!versionClaim.isMissing()) {
390
String version = versionClaim.asString();
391
System.out.println("Token version: " + version);
392
}
393
```
394
395
### Claim Validation Patterns
396
397
Common patterns for safely validating and processing claims.
398
399
**Usage Examples:**
400
401
```java
402
DecodedJWT jwt = JWT.decode(token);
403
404
// Safe string claim validation
405
public String getValidatedRole(DecodedJWT jwt) {
406
Claim roleClaim = jwt.getClaim("role");
407
if (roleClaim.isMissing() || roleClaim.isNull()) {
408
return "guest"; // default role
409
}
410
411
String role = roleClaim.asString();
412
if (role == null || role.trim().isEmpty()) {
413
return "guest";
414
}
415
416
// Validate against allowed roles
417
Set<String> allowedRoles = Set.of("admin", "user", "guest", "moderator");
418
return allowedRoles.contains(role) ? role : "guest";
419
}
420
421
// Safe numeric claim validation
422
public int getValidatedLevel(DecodedJWT jwt) {
423
Claim levelClaim = jwt.getClaim("level");
424
if (levelClaim.isMissing() || levelClaim.isNull()) {
425
return 0;
426
}
427
428
Integer level = levelClaim.asInt();
429
if (level == null) {
430
return 0;
431
}
432
433
// Ensure level is within valid range
434
return Math.max(0, Math.min(level, 10));
435
}
436
437
// Safe array claim validation
438
public List<String> getValidatedPermissions(DecodedJWT jwt) {
439
Claim permissionsClaim = jwt.getClaim("permissions");
440
if (permissionsClaim.isMissing() || permissionsClaim.isNull()) {
441
return Collections.emptyList();
442
}
443
444
List<String> permissions = permissionsClaim.asList(String.class);
445
if (permissions == null) {
446
return Collections.emptyList();
447
}
448
449
// Filter out null/empty permissions and validate against allowed set
450
Set<String> allowedPermissions = Set.of("read", "write", "delete", "admin");
451
return permissions.stream()
452
.filter(Objects::nonNull)
453
.filter(p -> !p.trim().isEmpty())
454
.filter(allowedPermissions::contains)
455
.collect(Collectors.toList());
456
}
457
458
// Safe date claim validation
459
public Instant getValidatedLastLogin(DecodedJWT jwt) {
460
Claim lastLoginClaim = jwt.getClaim("lastLogin");
461
if (lastLoginClaim.isMissing() || lastLoginClaim.isNull()) {
462
return null;
463
}
464
465
Instant lastLogin = lastLoginClaim.asInstant();
466
if (lastLogin == null) {
467
return null;
468
}
469
470
// Ensure date is not in the future and not too old
471
Instant now = Instant.now();
472
Instant oneYearAgo = now.minus(365, ChronoUnit.DAYS);
473
474
if (lastLogin.isAfter(now) || lastLogin.isBefore(oneYearAgo)) {
475
return null; // Invalid date range
476
}
477
478
return lastLogin;
479
}
480
```
481
482
## Claim Constants
483
484
Constants for standard JWT claim names and header parameters.
485
486
```java { .api }
487
/**
488
* Standard JWT claim names from RFC 7519
489
*/
490
public class RegisteredClaims {
491
public static final String ISSUER = "iss";
492
public static final String SUBJECT = "sub";
493
public static final String AUDIENCE = "aud";
494
public static final String EXPIRES_AT = "exp";
495
public static final String NOT_BEFORE = "nbf";
496
public static final String ISSUED_AT = "iat";
497
public static final String JWT_ID = "jti";
498
}
499
500
/**
501
* JWT header parameter constants
502
*/
503
public class HeaderParams {
504
public static final String ALGORITHM = "alg";
505
public static final String CONTENT_TYPE = "cty";
506
public static final String TYPE = "typ";
507
public static final String KEY_ID = "kid";
508
}
509
```
510
511
**Usage Examples:**
512
513
```java
514
import static com.auth0.jwt.RegisteredClaims.*;
515
import static com.auth0.jwt.HeaderParams.*;
516
517
// Use constants for claim names
518
DecodedJWT jwt = JWT.decode(token);
519
520
String issuer = jwt.getClaim(ISSUER).asString();
521
String subject = jwt.getClaim(SUBJECT).asString();
522
List<String> audience = jwt.getClaim(AUDIENCE).asList(String.class);
523
524
// Use constants for header parameters
525
String algorithm = jwt.getHeaderClaim(ALGORITHM).asString();
526
String keyId = jwt.getHeaderClaim(KEY_ID).asString();
527
528
// Better for consistency and avoiding typos
529
Claim expClaim = jwt.getClaim(EXPIRES_AT);
530
Claim iatClaim = jwt.getClaim(ISSUED_AT);
531
```
532
533
## Types
534
535
```java { .api }
536
/**
537
* JWT payload interface providing access to payload claims
538
*/
539
public interface Payload {
540
String getIssuer();
541
String getSubject();
542
List<String> getAudience();
543
Date getExpiresAt();
544
Instant getExpiresAtAsInstant();
545
Date getNotBefore();
546
Instant getNotBeforeAsInstant();
547
Date getIssuedAt();
548
Instant getIssuedAtAsInstant();
549
String getId();
550
Claim getClaim(String name);
551
Map<String, Claim> getClaims();
552
}
553
554
/**
555
* JWT header interface providing access to header claims
556
*/
557
public interface Header {
558
String getAlgorithm();
559
String getType();
560
String getContentType();
561
String getKeyId();
562
Claim getHeaderClaim(String name);
563
}
564
565
/**
566
* Generic claim value interface with type-safe conversion methods
567
*/
568
public interface Claim {
569
boolean isNull();
570
boolean isMissing();
571
Boolean asBoolean();
572
Integer asInt();
573
Long asLong();
574
Double asDouble();
575
String asString();
576
Date asDate();
577
Instant asInstant();
578
<T> T[] asArray(Class<T> clazz);
579
<T> List<T> asList(Class<T> clazz);
580
Map<String, Object> asMap();
581
<T> T as(Class<T> clazz);
582
}
583
```