Asymmetric JWT & JWKS
ligero-auth verifies and signs JWTs with the asymmetric RS256 and
ES256 algorithms in addition to HS256 — so a Ligero service can act as an
OIDC resource server, validating tokens issued by an external identity
provider (Auth0, Keycloak, Cognito, Google, …) against its public keys.
Install with the CLI
ligero add auth
implementation "com.ligeroframework:ligero-auth:$ligeroVersion"
Verify tokens from an identity provider (JWKS)
An OIDC provider publishes its public keys at a jwks_uri. Fetch that document
yourself and hand it to Jwks.parse — it returns JDK public keys by kid:
// 1. fetch the JWKS (cache it; refresh periodically)
String jwksJson = httpClient.send(
HttpRequest.newBuilder(URI.create(issuer + "/.well-known/jwks.json")).build(),
HttpResponse.BodyHandlers.ofString()).body();
Jwks jwks = Jwks.parse(jwksJson, bodyMapper);
// 2. verify a bearer token with the key named in its header (kid)
PublicKey key = jwks.key(kidFromTokenHeader).orElseThrow();
Map<String, Object> claims = Jwt.rs256Verifier(key, bodyMapper).verify(bearerToken);
Jwks.parse supports RSA (kty=RSA) and EC P-256 (kty=EC,
crv=P-256) keys — the key types behind RS256 and ES256.
Sign and verify yourself
KeyPair keys = /* your RSA or EC key pair */;
Jwt jwt = Jwt.rs256(keys.getPrivate(), keys.getPublic(), bodyMapper);
String token = jwt.sign(Map.of("sub", "ada"), Duration.ofHours(1));
Map<String, Object> claims = jwt.verify(token);
API
| Factory | Use |
|---|---|
Jwt.hs256(secret, mapper) | symmetric (issue + verify yourself) |
Jwt.rs256(priv, pub, mapper) / Jwt.es256(...) | asymmetric sign + verify |
Jwt.rs256Verifier(pub, mapper) / es256Verifier(...) | verify-only (resource server) |
Jwks.parse(json, mapper) → key(kid) | public keys from a JWKS document |
Security notes
- The verifier pins the algorithm it was created with, rejecting tokens with
a different
alg— this defends against algorithm-confusion and thenonealgorithm attack. expandnbfare always enforced.- Cache the JWKS and refresh it periodically (e.g. hourly, or on an unknown
kid); don't fetch it per request.