or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.mdio-utilities.mdjwt-operations.mdsecurity-jwk.mdtypes.md

types.mddocs/

0

# Types and Interfaces

1

2

This document covers the core JWT types including Claims, Headers, and token interfaces that represent parsed JWT content in JJWT API.

3

4

## JWT Token Types

5

6

### Base JWT Interface

7

8

```java { .api }

9

public interface Jwt<H, P> {

10

// Core Methods

11

H getHeader();

12

P getPayload();

13

<T> T accept(JwtVisitor<T> visitor);

14

15

// Static Visitor Constants for Unsecured JWTs

16

JwtVisitor<Jwt<Header, byte[]>> UNSECURED_CONTENT = /* visitor implementation */;

17

JwtVisitor<Jwt<Header, Claims>> UNSECURED_CLAIMS = /* visitor implementation */;

18

}

19

```

20

21

### Protected JWT Interface

22

23

```java { .api }

24

public interface ProtectedJwt<H extends ProtectedHeader, P> extends Jwt<H, P> {

25

// Base interface for cryptographically-protected JWTs (JWS and JWE)

26

}

27

```

28

29

### JSON Web Signature (JWS) Interface

30

31

```java { .api }

32

public interface Jws<P> extends ProtectedJwt<JwsHeader, P> {

33

// JWS-specific method

34

String getDigest();

35

36

// Static Visitor Constants for JWS

37

JwtVisitor<Jws<byte[]>> CONTENT = /* visitor implementation */;

38

JwtVisitor<Jws<Claims>> CLAIMS = /* visitor implementation */;

39

}

40

```

41

42

### JSON Web Encryption (JWE) Interface

43

44

```java { .api }

45

public interface Jwe<P> extends ProtectedJwt<JweHeader, P> {

46

// JWE extends ProtectedJwt but doesn't add specific methods

47

// All functionality inherited from base interfaces

48

}

49

```

50

51

### JWT Token Usage Examples

52

53

```java

54

import io.jsonwebtoken.*;

55

56

// Parse different JWT types and access content

57

JwtParser parser = Jwts.parser().verifyWith(key).build();

58

59

// Parse generic JWT (auto-detects type)

60

Jwt<?, ?> jwt = parser.parse(jwtString);

61

System.out.println("JWT type: " + jwt.getClass().getSimpleName());

62

63

// Parse specific JWS with Claims

64

Jws<Claims> jws = parser.parseSignedClaims(jwtString);

65

JwsHeader header = jws.getHeader();

66

Claims claims = jws.getPayload();

67

String signature = jws.getDigest();

68

69

System.out.println("Algorithm: " + header.getAlgorithm());

70

System.out.println("Subject: " + claims.getSubject());

71

System.out.println("Signature: " + signature);

72

73

// Use visitor pattern for type-safe processing

74

String result = jwt.accept(new JwtVisitor<String>() {

75

@Override

76

public String visit(Jwt<Header, byte[]> jwt) {

77

return "Unsecured JWT with " + jwt.getPayload().length + " bytes";

78

}

79

80

@Override

81

public String visit(Jwt<Header, Claims> jwt) {

82

return "Unsecured JWT with subject: " + jwt.getPayload().getSubject();

83

}

84

85

@Override

86

public String visit(Jws<byte[]> jws) {

87

return "Signed JWT with " + jws.getPayload().length + " bytes";

88

}

89

90

@Override

91

public String visit(Jws<Claims> jws) {

92

return "Signed JWT with subject: " + jws.getPayload().getSubject();

93

}

94

95

@Override

96

public String visit(Jwe<byte[]> jwe) {

97

return "Encrypted JWT with " + jwe.getPayload().length + " bytes";

98

}

99

100

@Override

101

public String visit(Jwe<Claims> jwe) {

102

return "Encrypted JWT with subject: " + jwe.getPayload().getSubject();

103

}

104

});

105

```

106

107

## Header Types

108

109

### Base Header Interface

110

111

```java { .api }

112

public interface Header extends Map<String, Object> {

113

// Standard Header Parameters

114

String getType();

115

String getContentType();

116

String getAlgorithm();

117

String getCompressionAlgorithm();

118

119

// Standard Header Parameter Names

120

String TYPE = "typ";

121

String CONTENT_TYPE = "cty";

122

String ALGORITHM = "alg";

123

String COMPRESSION_ALGORITHM = "zip";

124

}

125

```

126

127

### Protected Header Interface

128

129

```java { .api }

130

public interface ProtectedHeader extends Header, X509Accessor {

131

// Additional Protected Header Parameters

132

String getKeyId();

133

Set<String> getCritical();

134

135

// Additional Parameter Names

136

String KEY_ID = "kid";

137

String CRITICAL = "crit";

138

}

139

```

140

141

### JWS Header Interface

142

143

```java { .api }

144

public interface JwsHeader extends ProtectedHeader {

145

// RFC 7797 Unencoded Payload Support

146

boolean isPayloadEncoded();

147

148

// Parameter Name

149

String PAYLOAD_ENCODED = "b64";

150

}

151

```

152

153

### JWE Header Interface

154

155

```java { .api }

156

public interface JweHeader extends ProtectedHeader {

157

// JWE-specific Header Parameters

158

String getEncryptionAlgorithm();

159

String getInitializationVector();

160

String getAuthenticationTag();

161

String getEphemeralPublicKey();

162

String getAgreementPartyUInfo();

163

String getAgreementPartyVInfo();

164

Integer getPbes2Count();

165

String getPbes2Salt();

166

167

// JWE Parameter Names

168

String ENCRYPTION_ALGORITHM = "enc";

169

String INITIALIZATION_VECTOR = "iv";

170

String AUTHENTICATION_TAG = "tag";

171

String EPHEMERAL_PUBLIC_KEY = "epk";

172

String AGREEMENT_PARTY_U_INFO = "apu";

173

String AGREEMENT_PARTY_V_INFO = "apv";

174

String PBES2_COUNT = "p2c";

175

String PBES2_SALT = "p2s";

176

}

177

```

178

179

### Header Usage Examples

180

181

```java

182

import io.jsonwebtoken.*;

183

184

// Access header information from parsed JWT

185

Jws<Claims> jws = parser.parseSignedClaims(jwtString);

186

JwsHeader header = jws.getHeader();

187

188

// Standard header parameters

189

String algorithm = header.getAlgorithm(); // "RS256"

190

String type = header.getType(); // "JWT"

191

String keyId = header.getKeyId(); // "key-1"

192

String contentType = header.getContentType(); // null (typically)

193

194

// Check for RFC 7797 unencoded payload

195

boolean isPayloadEncoded = header.isPayloadEncoded(); // true (default)

196

197

// Access custom header parameters

198

Object customParam = header.get("custom");

199

200

// JWE header example

201

Jwe<Claims> jwe = parser.parseEncryptedClaims(jweString);

202

JweHeader jweHeader = jwe.getHeader();

203

204

String encAlgorithm = jweHeader.getEncryptionAlgorithm(); // "A256GCM"

205

String keyAlgorithm = jweHeader.getAlgorithm(); // "RSA-OAEP"

206

```

207

208

## Claims Interface

209

210

### Core Claims Interface

211

212

```java { .api }

213

public interface Claims extends Map<String, Object> {

214

// Standard Claims Accessors

215

String getIssuer();

216

String getSubject();

217

Set<String> getAudience();

218

Date getExpiration();

219

Date getNotBefore();

220

Date getIssuedAt();

221

String getId();

222

223

// Type-safe Claim Access

224

<T> T get(String claimName, Class<T> requiredType);

225

226

// Standard Claim Names

227

String ISSUER = "iss";

228

String SUBJECT = "sub";

229

String AUDIENCE = "aud";

230

String EXPIRATION = "exp";

231

String NOT_BEFORE = "nbf";

232

String ISSUED_AT = "iat";

233

String ID = "jti";

234

}

235

```

236

237

### Claims Builder Interface

238

239

```java { .api }

240

public interface ClaimsBuilder extends MapMutator<String, Object, ClaimsBuilder>, ClaimsMutator<ClaimsBuilder> {

241

// Inherits methods from MapMutator and ClaimsMutator

242

Claims build();

243

}

244

```

245

246

### Claims Mutator Interface

247

248

```java { .api }

249

public interface ClaimsMutator<T> {

250

// Standard Claims Mutators

251

T issuer(String iss);

252

T subject(String sub);

253

T audience(String aud);

254

T audiences(String... audiences);

255

T expiration(Date exp);

256

T notBefore(Date nbf);

257

T issuedAt(Date iat);

258

T id(String jti);

259

}

260

```

261

262

### Claims Usage Examples

263

264

```java

265

import io.jsonwebtoken.*;

266

import java.util.Date;

267

import java.util.Set;

268

269

// Parse JWT and access claims

270

Jws<Claims> jws = parser.parseSignedClaims(jwtString);

271

Claims claims = jws.getPayload();

272

273

// Standard claims

274

String issuer = claims.getIssuer(); // "https://auth.example.com"

275

String subject = claims.getSubject(); // "user123"

276

Set<String> audience = claims.getAudience(); // ["web-app", "mobile-app"]

277

Date expiration = claims.getExpiration(); // expiration timestamp

278

Date notBefore = claims.getNotBefore(); // not-before timestamp

279

Date issuedAt = claims.getIssuedAt(); // issued-at timestamp

280

String jti = claims.getId(); // "unique-token-id"

281

282

// Type-safe custom claim access

283

String role = claims.get("role", String.class);

284

Integer userId = claims.get("user_id", Integer.class);

285

List<String> permissions = claims.get("permissions", List.class);

286

287

// Check for claim existence

288

if (claims.containsKey("department")) {

289

String department = claims.get("department", String.class);

290

}

291

292

// Iterate over all claims

293

for (Map.Entry<String, Object> entry : claims.entrySet()) {

294

System.out.println(entry.getKey() + ": " + entry.getValue());

295

}

296

297

// Create claims using builder

298

Claims customClaims = Jwts.claims()

299

.issuer("myapp")

300

.subject("user456")

301

.audience("api")

302

.expiration(new Date(System.currentTimeMillis() + 3600000))

303

.add("role", "admin")

304

.add("permissions", Arrays.asList("read", "write", "delete"))

305

.build();

306

```

307

308

## Visitor Pattern Support

309

310

### JWT Visitor Interface

311

312

```java { .api }

313

public interface JwtVisitor<T> {

314

T visit(Jwt<Header, byte[]> jwt);

315

T visit(Jwt<Header, Claims> jwt);

316

T visit(Jws<byte[]> jws);

317

T visit(Jws<Claims> jws);

318

T visit(Jwe<byte[]> jwe);

319

T visit(Jwe<Claims> jwe);

320

}

321

```

322

323

### Supported JWT Visitor

324

325

```java { .api }

326

public class SupportedJwtVisitor<T> implements JwtVisitor<T> {

327

// Base implementation that throws UnsupportedJwtException for unsupported types

328

// Subclasses override only methods for supported JWT types

329

}

330

```

331

332

### JWT Handler Interface (Alternative Pattern)

333

334

```java { .api }

335

public interface JwtHandler<T> {

336

T onUnsecuredContent(Jwt<Header, byte[]> jwt);

337

T onUnsecuredClaims(Jwt<Header, Claims> jwt);

338

T onSignedContent(Jws<byte[]> jws);

339

T onSignedClaims(Jws<Claims> jws);

340

T onEncryptedContent(Jwe<byte[]> jwe);

341

T onEncryptedClaims(Jwe<Claims> jwe);

342

}

343

```

344

345

### JWT Handler Adapter

346

347

```java { .api }

348

public class JwtHandlerAdapter<T> implements JwtHandler<T> {

349

// Default implementation that throws UnsupportedJwtException

350

// Subclasses override only methods for supported JWT types

351

}

352

```

353

354

### Visitor Pattern Examples

355

356

```java

357

import io.jsonwebtoken.*;

358

359

// Custom visitor to extract information

360

public class JwtInfoVisitor implements JwtVisitor<String> {

361

@Override

362

public String visit(Jwt<Header, byte[]> jwt) {

363

return "Unsecured JWT with byte payload, size: " + jwt.getPayload().length;

364

}

365

366

@Override

367

public String visit(Jwt<Header, Claims> jwt) {

368

Claims claims = jwt.getPayload();

369

return "Unsecured JWT, subject: " + claims.getSubject();

370

}

371

372

@Override

373

public String visit(Jws<byte[]> jws) {

374

return "Signed JWT (" + jws.getHeader().getAlgorithm() + ") with byte payload";

375

}

376

377

@Override

378

public String visit(Jws<Claims> jws) {

379

Claims claims = jws.getPayload();

380

return "Signed JWT, subject: " + claims.getSubject() +

381

", algorithm: " + jws.getHeader().getAlgorithm();

382

}

383

384

@Override

385

public String visit(Jwe<byte[]> jwe) {

386

return "Encrypted JWT with byte payload";

387

}

388

389

@Override

390

public String visit(Jwe<Claims> jwe) {

391

Claims claims = jwe.getPayload();

392

return "Encrypted JWT, subject: " + claims.getSubject();

393

}

394

}

395

396

// Use the visitor

397

Jwt<?, ?> jwt = parser.parse(jwtString);

398

String info = jwt.accept(new JwtInfoVisitor());

399

System.out.println(info);

400

401

// Using SupportedJwtVisitor for specific JWT types only

402

public class ClaimsExtractor extends SupportedJwtVisitor<Claims> {

403

@Override

404

public Claims visit(Jwt<Header, Claims> jwt) {

405

return jwt.getPayload();

406

}

407

408

@Override

409

public Claims visit(Jws<Claims> jws) {

410

return jws.getPayload();

411

}

412

413

@Override

414

public Claims visit(Jwe<Claims> jwe) {

415

return jwe.getPayload();

416

}

417

418

// Byte payload visits will throw UnsupportedJwtException

419

}

420

421

// Extract claims regardless of JWT type

422

Claims claims = jwt.accept(new ClaimsExtractor());

423

```

424

425

## Utility Interfaces

426

427

### Locator Interface

428

429

```java { .api }

430

public interface Locator<T> {

431

T locate(Header header);

432

}

433

```

434

435

### Locator Adapter

436

437

```java { .api }

438

public abstract class LocatorAdapter<T> implements Locator<T> {

439

@Override

440

public T locate(Header header) {

441

return null; // Default implementation

442

}

443

}

444

```

445

446

### Key Resolution Examples

447

448

```java

449

import io.jsonwebtoken.security.SigningKeyResolver;

450

451

// Dynamic key resolution based on header information

452

public class CustomKeyLocator implements Locator<Key> {

453

private final KeyService keyService;

454

455

public CustomKeyLocator(KeyService keyService) {

456

this.keyService = keyService;

457

}

458

459

@Override

460

public Key locate(Header header) {

461

String keyId = header instanceof ProtectedHeader

462

? ((ProtectedHeader) header).getKeyId()

463

: null;

464

465

String algorithm = header.getAlgorithm();

466

467

if (keyId != null) {

468

return keyService.getKeyById(keyId);

469

} else if ("HS256".equals(algorithm)) {

470

return keyService.getDefaultHmacKey();

471

} else {

472

throw new IllegalArgumentException("Cannot locate key for algorithm: " + algorithm);

473

}

474

}

475

}

476

477

// Use with parser

478

JwtParser parser = Jwts.parser()

479

.keyLocator(new CustomKeyLocator(keyService))

480

.build();

481

```

482

483

## Exception Types

484

485

### Claim-Related Exceptions

486

487

```java { .api }

488

public class ClaimJwtException extends JwtException {

489

// Base exception for claim validation failures

490

public ClaimJwtException(Header header, Claims claims, String message);

491

public ClaimJwtException(Header header, Claims claims, String message, Throwable cause);

492

493

public Header getHeader();

494

public Claims getClaims();

495

}

496

497

public class IncorrectClaimException extends ClaimJwtException {

498

// Claim has incorrect value

499

public IncorrectClaimException(Header header, Claims claims, String claimName, Object expectedValue, Object actualValue);

500

501

public String getClaimName();

502

public Object getExpectedValue();

503

public Object getActualValue();

504

}

505

506

public class MissingClaimException extends ClaimJwtException {

507

// Required claim is missing

508

public MissingClaimException(Header header, Claims claims, String claimName);

509

510

public String getClaimName();

511

}

512

513

public class InvalidClaimException extends ClaimJwtException {

514

// Claim value is invalid (e.g., malformed date)

515

public InvalidClaimException(Header header, Claims claims, String message);

516

}

517

```

518

519

### JWT Validation Exceptions

520

521

```java { .api }

522

public class ExpiredJwtException extends ClaimJwtException {

523

// JWT has expired

524

public ExpiredJwtException(Header header, Claims claims, String message);

525

}

526

527

public class PrematureJwtException extends ClaimJwtException {

528

// JWT is not yet valid (nbf claim)

529

public PrematureJwtException(Header header, Claims claims, String message);

530

}

531

532

public class RequiredTypeException extends JwtException {

533

// Type conversion failed

534

public RequiredTypeException(String message);

535

}

536

```

537

538

### Exception Handling Examples

539

540

```java

541

import io.jsonwebtoken.*;

542

543

try {

544

Jws<Claims> jws = parser.parseSignedClaims(jwtString);

545

Claims claims = jws.getPayload();

546

547

// JWT is valid, process claims

548

processValidJwt(claims);

549

550

} catch (ExpiredJwtException e) {

551

System.err.println("JWT expired at: " + e.getClaims().getExpiration());

552

// Handle expired token

553

554

} catch (PrematureJwtException e) {

555

System.err.println("JWT not valid until: " + e.getClaims().getNotBefore());

556

// Handle premature token

557

558

} catch (MissingClaimException e) {

559

System.err.println("Missing required claim: " + e.getClaimName());

560

// Handle missing claim

561

562

} catch (IncorrectClaimException e) {

563

System.err.println("Incorrect claim '" + e.getClaimName() +

564

"': expected '" + e.getExpectedValue() +

565

"', got '" + e.getActualValue() + "'");

566

// Handle incorrect claim

567

568

} catch (SignatureException e) {

569

System.err.println("JWT signature validation failed");

570

// Handle signature failure

571

572

} catch (MalformedJwtException e) {

573

System.err.println("JWT is malformed: " + e.getMessage());

574

// Handle malformed JWT

575

576

} catch (JwtException e) {

577

System.err.println("JWT processing failed: " + e.getMessage());

578

// Handle other JWT exceptions

579

}

580

```

581

582

## Type Conversion Utilities

583

584

### Safe Type Extraction

585

586

```java

587

import io.jsonwebtoken.Claims;

588

589

public class ClaimsUtils {

590

public static <T> T getClaimSafely(Claims claims, String claimName, Class<T> type, T defaultValue) {

591

try {

592

T value = claims.get(claimName, type);

593

return value != null ? value : defaultValue;

594

} catch (RequiredTypeException e) {

595

return defaultValue;

596

}

597

}

598

599

public static List<String> getStringList(Claims claims, String claimName) {

600

Object value = claims.get(claimName);

601

if (value instanceof List) {

602

List<?> list = (List<?>) value;

603

return list.stream()

604

.filter(String.class::isInstance)

605

.map(String.class::cast)

606

.collect(Collectors.toList());

607

}

608

return Collections.emptyList();

609

}

610

611

public static Date getDateClaim(Claims claims, String claimName) {

612

Object value = claims.get(claimName);

613

if (value instanceof Date) {

614

return (Date) value;

615

} else if (value instanceof Number) {

616

return new Date(((Number) value).longValue() * 1000);

617

}

618

return null;

619

}

620

}

621

622

// Usage

623

Claims claims = jws.getPayload();

624

String role = ClaimsUtils.getClaimSafely(claims, "role", String.class, "user");

625

List<String> permissions = ClaimsUtils.getStringList(claims, "permissions");

626

Date customDate = ClaimsUtils.getDateClaim(claims, "custom_date");

627

```