0
# JWT Building
1
2
The JWT Building functionality in JJWT Implementation is centered around the `DefaultJwtBuilder` class, which provides a fluent API for creating JWT (unsecured), JWS (signed), and JWE (encrypted) tokens. This comprehensive builder supports all standard JWT operations with type-safe configuration.
3
4
## Core Builder Classes
5
6
### DefaultJwtBuilder
7
8
The main factory for creating all types of JWT tokens.
9
10
```java { .api }
11
import io.jsonwebtoken.Jwts;
12
import io.jsonwebtoken.JwtBuilder;
13
import io.jsonwebtoken.Claims;
14
import javax.crypto.SecretKey;
15
import java.security.KeyPair;
16
import java.security.Provider;
17
import java.security.SecureRandom;
18
import java.util.Date;
19
import java.util.Map;
20
21
// Basic builder creation
22
JwtBuilder builder = Jwts.builder();
23
24
// Builder with provider configuration
25
JwtBuilder configuredBuilder = Jwts.builder()
26
.provider(myJcaProvider)
27
.random(mySecureRandom);
28
```
29
30
### Key Builder Methods
31
32
```java { .api }
33
// Header configuration
34
JwtBuilder headerBuilder = Jwts.builder()
35
.header()
36
.keyId("my-key-id")
37
.type("JWT")
38
.contentType("application/json")
39
.add("custom-header", "value")
40
.and();
41
42
// Claims configuration
43
JwtBuilder claimsBuilder = Jwts.builder()
44
.claims()
45
.subject("john.doe")
46
.issuer("my-service")
47
.audience().add("api-clients").and()
48
.issuedAt(new Date())
49
.expiration(new Date(System.currentTimeMillis() + 3600000))
50
.id(UUID.randomUUID().toString())
51
.add("role", "admin")
52
.add("permissions", Arrays.asList("read", "write", "delete"))
53
.and();
54
55
// Content setting (for content JWTs)
56
JwtBuilder contentBuilder = Jwts.builder()
57
.content("Plain text payload")
58
.header().contentType("text/plain").and();
59
60
// Binary content
61
byte[] binaryData = "Binary payload".getBytes(StandardCharsets.UTF_8);
62
JwtBuilder binaryBuilder = Jwts.builder()
63
.content(binaryData)
64
.header().contentType("application/octet-stream").and();
65
66
// Stream content (for large payloads)
67
InputStream largeStream = new FileInputStream("large-file.json");
68
JwtBuilder streamBuilder = Jwts.builder()
69
.content(largeStream)
70
.header().contentType("application/json").and();
71
```
72
73
## JWT Creation (Unsecured)
74
75
```java { .api }
76
// Simple unsecured JWT with claims
77
String unsecuredJwt = Jwts.builder()
78
.subject("user123")
79
.issuer("my-app")
80
.issuedAt(new Date())
81
.compact();
82
83
// Unsecured JWT with content payload
84
String contentJwt = Jwts.builder()
85
.content("{\"message\": \"Hello World\"}")
86
.header()
87
.contentType("application/json")
88
.and()
89
.compact();
90
91
// Custom claims JWT
92
Map<String, Object> customClaims = new HashMap<>();
93
customClaims.put("userId", 12345);
94
customClaims.put("roles", Arrays.asList("user", "admin"));
95
customClaims.put("metadata", Map.of("department", "engineering"));
96
97
String customJwt = Jwts.builder()
98
.claims(customClaims)
99
.subject("john.doe")
100
.compact();
101
```
102
103
## JWS Creation (Signed)
104
105
### HMAC Signatures
106
107
```java { .api }
108
import io.jsonwebtoken.security.SecureDigestAlgorithm;
109
110
// Generate HMAC key
111
SecretKey hmacKey = Jwts.SIG.HS256.key().build();
112
113
// Create signed JWT with HMAC
114
String hmacJws = Jwts.builder()
115
.subject("authenticated-user")
116
.signWith(hmacKey) // Algorithm auto-detected
117
.compact();
118
119
// Explicit algorithm specification
120
String explicitHmacJws = Jwts.builder()
121
.claims()
122
.subject("user")
123
.issuer("auth-service")
124
.and()
125
.signWith(hmacKey, Jwts.SIG.HS512)
126
.compact();
127
128
// Using different HMAC strengths
129
SecretKey hs384Key = Jwts.SIG.HS384.key().build();
130
SecretKey hs512Key = Jwts.SIG.HS512.key().build();
131
132
String hs384Jws = Jwts.builder()
133
.subject("user")
134
.signWith(hs384Key)
135
.compact();
136
```
137
138
### RSA Signatures
139
140
```java { .api }
141
import java.security.KeyPair;
142
import java.security.PrivateKey;
143
144
// Generate RSA key pair
145
KeyPair rsaKeyPair = Jwts.SIG.RS256.keyPair().build();
146
PrivateKey rsaPrivateKey = rsaKeyPair.getPrivate();
147
148
// Create RSA-signed JWT
149
String rsaJws = Jwts.builder()
150
.subject("enterprise-user")
151
.issuer("corporate-sso")
152
.signWith(rsaPrivateKey)
153
.compact();
154
155
// Different RSA signature algorithms
156
KeyPair rs384Pair = Jwts.SIG.RS384.keyPair().build();
157
KeyPair rs512Pair = Jwts.SIG.RS512.keyPair().build();
158
159
String rs384Jws = Jwts.builder()
160
.subject("user")
161
.signWith(rs384Pair.getPrivate(), Jwts.SIG.RS384)
162
.compact();
163
164
// RSA-PSS signatures
165
KeyPair ps256Pair = Jwts.SIG.PS256.keyPair().build();
166
String psJws = Jwts.builder()
167
.subject("user")
168
.signWith(ps256Pair.getPrivate(), Jwts.SIG.PS256)
169
.compact();
170
```
171
172
### Elliptic Curve Signatures
173
174
```java { .api }
175
// Generate EC key pairs for different curves
176
KeyPair ecP256Pair = Jwts.SIG.ES256.keyPair().build();
177
KeyPair ecP384Pair = Jwts.SIG.ES384.keyPair().build();
178
KeyPair ecP521Pair = Jwts.SIG.ES512.keyPair().build();
179
180
// ES256 (P-256 curve)
181
String es256Jws = Jwts.builder()
182
.subject("mobile-user")
183
.signWith(ecP256Pair.getPrivate())
184
.compact();
185
186
// ES384 (P-384 curve)
187
String es384Jws = Jwts.builder()
188
.subject("api-client")
189
.signWith(ecP384Pair.getPrivate(), Jwts.SIG.ES384)
190
.compact();
191
192
// EdDSA signatures (Ed25519)
193
KeyPair ed25519Pair = Jwts.SIG.EdDSA.keyPair().build();
194
String eddsaJws = Jwts.builder()
195
.subject("iot-device")
196
.signWith(ed25519Pair.getPrivate())
197
.compact();
198
```
199
200
## JWE Creation (Encrypted)
201
202
### Direct Encryption
203
204
```java { .api }
205
import io.jsonwebtoken.security.AeadAlgorithm;
206
207
// Generate content encryption key
208
SecretKey cek = Jwts.ENC.A256GCM.key().build();
209
210
// Direct encryption (key used directly)
211
String directJwe = Jwts.builder()
212
.subject("confidential-user")
213
.claim("ssn", "123-45-6789")
214
.claim("salary", 150000)
215
.encryptWith(cek, Jwts.KEY.DIRECT, Jwts.ENC.A256GCM)
216
.compact();
217
218
// Different content encryption algorithms
219
SecretKey a128Key = Jwts.ENC.A128GCM.key().build();
220
SecretKey a192Key = Jwts.ENC.A192GCM.key().build();
221
222
String a128Jwe = Jwts.builder()
223
.subject("user")
224
.encryptWith(a128Key, Jwts.KEY.DIRECT, Jwts.ENC.A128GCM)
225
.compact();
226
```
227
228
### Key Wrapping Encryption
229
230
```java { .api }
231
import io.jsonwebtoken.security.KeyAlgorithm;
232
233
// AES Key Wrap
234
SecretKey kekKey = Jwts.KEY.A256KW.key().build();
235
236
String aesKwJwe = Jwts.builder()
237
.subject("wrapped-content-user")
238
.claim("confidential", "sensitive data")
239
.encryptWith(kekKey, Jwts.KEY.A256KW, Jwts.ENC.A256GCM)
240
.compact();
241
242
// Different key wrap strengths
243
SecretKey a128kwKey = Jwts.KEY.A128KW.key().build();
244
SecretKey a192kwKey = Jwts.KEY.A192KW.key().build();
245
246
String a128kwJwe = Jwts.builder()
247
.subject("user")
248
.encryptWith(a128kwKey, Jwts.KEY.A128KW, Jwts.ENC.A128GCM)
249
.compact();
250
```
251
252
### RSA Encryption
253
254
```java { .api }
255
// RSA key encryption
256
KeyPair rsaEncPair = Jwts.KEY.RSA1_5.keyPair().build();
257
258
String rsaJwe = Jwts.builder()
259
.subject("enterprise-confidential")
260
.claim("department", "R&D")
261
.claim("clearance", "SECRET")
262
.encryptWith(rsaEncPair.getPublic(), Jwts.KEY.RSA1_5, Jwts.ENC.A256GCM)
263
.compact();
264
265
// RSA-OAEP encryption
266
KeyPair rsaOaepPair = Jwts.KEY.RSA_OAEP.keyPair().build();
267
268
String rsaOaepJwe = Jwts.builder()
269
.subject("user")
270
.encryptWith(rsaOaepPair.getPublic(), Jwts.KEY.RSA_OAEP, Jwts.ENC.A256GCM)
271
.compact();
272
273
// RSA-OAEP-256
274
KeyPair rsaOaep256Pair = Jwts.KEY.RSA_OAEP_256.keyPair().build();
275
String rsaOaep256Jwe = Jwts.builder()
276
.subject("user")
277
.encryptWith(rsaOaep256Pair.getPublic(), Jwts.KEY.RSA_OAEP_256, Jwts.ENC.A256GCM)
278
.compact();
279
```
280
281
### ECDH-ES Encryption
282
283
```java { .api }
284
// Elliptic Curve Diffie-Hellman Ephemeral Static
285
KeyPair ecdhPair = Jwts.KEY.ECDH_ES.keyPair().build();
286
287
String ecdhJwe = Jwts.builder()
288
.subject("mobile-secure-user")
289
.claim("deviceId", "mobile-123")
290
.encryptWith(ecdhPair.getPublic(), Jwts.KEY.ECDH_ES, Jwts.ENC.A256GCM)
291
.compact();
292
293
// ECDH-ES with key wrapping
294
KeyPair ecdh128Pair = Jwts.KEY.ECDH_ES_A128KW.keyPair().build();
295
296
String ecdhKwJwe = Jwts.builder()
297
.subject("user")
298
.encryptWith(ecdh128Pair.getPublic(), Jwts.KEY.ECDH_ES_A128KW, Jwts.ENC.A256GCM)
299
.compact();
300
```
301
302
## Advanced Building Features
303
304
### Compression
305
306
```java { .api }
307
import io.jsonwebtoken.CompressionAlgorithm;
308
309
// DEFLATE compression (standard)
310
String compressedJwt = Jwts.builder()
311
.subject("user-with-large-claims")
312
.claim("permissions", Arrays.asList(/* many permissions */))
313
.claim("metadata", largeMetadataMap)
314
.compressWith(Jwts.ZIP.DEF)
315
.signWith(secretKey)
316
.compact();
317
318
// GZIP compression (non-standard but supported)
319
String gzipJwt = Jwts.builder()
320
.subject("user")
321
.claim("largeData", veryLargeString)
322
.compressWith(Jwts.ZIP.GZIP)
323
.signWith(secretKey)
324
.compact();
325
326
// Compression with encryption
327
String compressedJwe = Jwts.builder()
328
.subject("user")
329
.claim("bigPayload", massiveDataStructure)
330
.compressWith(Jwts.ZIP.DEF)
331
.encryptWith(kekKey, Jwts.KEY.A256KW, Jwts.ENC.A256GCM)
332
.compact();
333
```
334
335
### Provider Configuration
336
337
```java { .api }
338
import java.security.Provider;
339
import java.security.SecureRandom;
340
341
// Custom JCA Provider
342
Provider customProvider = new BouncyCastleProvider();
343
SecureRandom customRandom = SecureRandom.getInstanceStrong();
344
345
String providerJwt = Jwts.builder()
346
.provider(customProvider)
347
.random(customRandom)
348
.subject("provider-specific-user")
349
.signWith(secretKey)
350
.compact();
351
352
// Provider-specific key generation
353
SecretKey providerKey = Jwts.SIG.HS256.key()
354
.provider(customProvider)
355
.random(customRandom)
356
.build();
357
```
358
359
### JSON Serialization
360
361
```java { .api }
362
import io.jsonwebtoken.io.Serializer;
363
import io.jsonwebtoken.jackson.io.JacksonSerializer;
364
365
// Custom JSON serializer
366
Serializer<Map<String, ?>> jsonSerializer = new JacksonSerializer<>();
367
368
String customSerializedJwt = Jwts.builder()
369
.json(jsonSerializer)
370
.subject("user")
371
.claim("complexObject", customObjectWithSpecialSerialization)
372
.signWith(secretKey)
373
.compact();
374
```
375
376
## Header Builders
377
378
### JWT Header Builder
379
380
```java { .api }
381
import io.jsonwebtoken.impl.DefaultJwtHeaderBuilder;
382
383
// Rich header configuration
384
String headerJwt = Jwts.builder()
385
.header()
386
.type("JWT")
387
.contentType("application/json")
388
.add("custom", "header-value")
389
.add("version", "1.0")
390
.and()
391
.subject("user")
392
.signWith(secretKey)
393
.compact();
394
```
395
396
### JWE Header Builder
397
398
```java { .api }
399
import io.jsonwebtoken.impl.DefaultJweHeaderBuilder;
400
401
// JWE-specific headers
402
String jweWithHeaders = Jwts.builder()
403
.subject("encrypted-user")
404
.encryptWith(kekKey, Jwts.KEY.A256KW, Jwts.ENC.A256GCM)
405
.compact();
406
// Note: JWE headers are automatically managed by the encryption process
407
```
408
409
## Claims Builders
410
411
### DefaultClaimsBuilder
412
413
```java { .api }
414
import io.jsonwebtoken.impl.DefaultClaimsBuilder;
415
import java.time.Instant;
416
import java.time.temporal.ChronoUnit;
417
418
// Comprehensive claims building
419
String richClaimsJwt = Jwts.builder()
420
.claims()
421
// Standard claims
422
.issuer("https://auth.example.com")
423
.subject("user@example.com")
424
.audience()
425
.add("https://api.example.com")
426
.add("https://mobile.example.com")
427
.and()
428
.expiration(Date.from(Instant.now().plus(1, ChronoUnit.HOURS)))
429
.notBefore(Date.from(Instant.now().minus(5, ChronoUnit.MINUTES)))
430
.issuedAt(new Date())
431
.id(UUID.randomUUID().toString())
432
433
// Custom claims
434
.add("role", "administrator")
435
.add("permissions", Set.of("read", "write", "delete"))
436
.add("profile", Map.of(
437
"name", "John Doe",
438
"email", "john@example.com",
439
"department", "Engineering"
440
))
441
.add("features", Arrays.asList("feature-a", "feature-b"))
442
443
.and()
444
.signWith(secretKey)
445
.compact();
446
447
// Bulk claims addition
448
Map<String, Object> bulkClaims = new HashMap<>();
449
bulkClaims.put("organizationId", "org-123");
450
bulkClaims.put("tenantId", "tenant-456");
451
bulkClaims.put("scope", "api:read api:write");
452
453
String bulkClaimsJwt = Jwts.builder()
454
.claims(bulkClaims)
455
.subject("service-account")
456
.signWith(secretKey)
457
.compact();
458
```
459
460
## Builder Patterns and Reuse
461
462
### Builder Reuse
463
464
```java { .api }
465
// Create a base builder template
466
JwtBuilder baseBuilder = Jwts.builder()
467
.issuer("my-service")
468
.issuedAt(new Date())
469
.header()
470
.type("JWT")
471
.and();
472
473
// Reuse for multiple tokens (note: each compact() creates new instance)
474
String userToken = baseBuilder
475
.subject("user-123")
476
.signWith(userKey)
477
.compact();
478
479
String adminToken = Jwts.builder()
480
.issuer("my-service")
481
.issuedAt(new Date())
482
.header()
483
.type("JWT")
484
.and()
485
.subject("admin-456")
486
.claim("role", "admin")
487
.signWith(adminKey)
488
.compact();
489
```
490
491
### Factory Methods
492
493
```java { .api }
494
// Create factory methods for common patterns
495
public static String createUserToken(String userId, String role, SecretKey key) {
496
return Jwts.builder()
497
.subject(userId)
498
.issuer("user-service")
499
.issuedAt(new Date())
500
.expiration(new Date(System.currentTimeMillis() + 3600000))
501
.claim("role", role)
502
.signWith(key)
503
.compact();
504
}
505
506
public static String createServiceToken(String serviceId, List<String> scopes, SecretKey key) {
507
return Jwts.builder()
508
.subject(serviceId)
509
.issuer("service-registry")
510
.audience().add("api-gateway").and()
511
.issuedAt(new Date())
512
.expiration(new Date(System.currentTimeMillis() + 7200000)) // 2 hours
513
.claim("scopes", scopes)
514
.signWith(key)
515
.compact();
516
}
517
518
// Usage
519
String token1 = createUserToken("john.doe", "user", hmacKey);
520
String token2 = createServiceToken("payment-service", Arrays.asList("payments:read", "payments:write"), serviceKey);
521
```
522
523
The JWT Building functionality provides a comprehensive, type-safe, and fluent API for creating any type of JWT token with full control over headers, claims, security algorithms, and advanced features like compression and custom serialization.