Skip to content
Flag of Europe
Made in the European Union · Independently built · Released under EUPL 1.2

00.77.00

Available on Maven Central. The first OAuth2 client release: a framework-light, JOSE-isolated OAuth2 Relying Party wired through the existing fluent .oauth2(...) bootstrap, built on the 00.76 jSentinel-jwt foundation. Additive — three new opt-in modules; every 00.74–00.76 app compiles and boots identically. No migration. The current release is 00.79.41 (OIDC followed in 00.78.00).

Release date: 2026-06-26 Previous release: 00.76.10 Maven coordinates (parent): com.svenruppert.jsentinel:jSentinel-parent:00.77.00 Full changelog: GitHub release v00.77.00

Headline — the full OAuth2 RP protocol surface

Three new modules (jSentinel-oauth2, jSentinel-oauth2-vaadin, jSentinel-oauth2-rest) implement the Relying-Party side of:

  • Authorization-Code flow + PKCE (RFC 6749 / 7636) — builds the S256 authorization URI, binds a single-use CSPRNG state + PKCE verifier in a StateStore, and exchanges the code on callback. PKCE is S256-onlyplain is unrepresentable.
  • Token endpoint + client authentication (RFC 6749 / 7523) — client_secret_basic, client_secret_post, none (public + PKCE), private_key_jwt and client_secret_jwt. JWT client assertions are built and signed via the new JwtSigner SPI (resolved through ServiceLoader, so jSentinel-oauth2 never imports a JOSE library).
  • Refresh-token rotation with reuse-detection (RFC 9700 §4.13.2) — a replayed (already-rotated) refresh token revokes the whole family; only token hashes are stored.
  • Introspection (RFC 7662) — a bounded, TTL’d, SHA-256-keyed decision cache.
  • Revocation (RFC 7009).
  • Device Authorization Grant (RFC 8628) — with interval / slow_down back-off handling; demo-standalone ships a browserless device-code login reference.

New: JWT signing (JwtSigner)

00.76 only validated JWTs; signing client assertions needs the other direction. New JOSE-free JwtSigner + JwtSigningKey SPIs in jSentinel-core, with a Nimbus-backed NimbusJwtSigner in jSentinel-jwt (RSA/EC via Nimbus, EdDSA via the JDK). The signing key is masked in toString() and validated against the algorithm family.

Bootstrap — .oauth2(...)

A declarative .oauth2(...) sub-builder on all three adapter facades. The DX layer only records + STRICT-validates the RP configuration (codes such as oauth2/missing-client-id, oauth2/missing-token-endpoint, oauth2/redirect-uri-not-https); the HTTP clients are assembled adapter-side, so jSentinel-dx stays free of any JOSE / HTTP-client compile dependency. JSentinelDiagnostics.inspect() gains a non-secret [OAuth2] contribution (never a client id, endpoint or secret).

Security properties

HTTPS enforced on every endpoint (a http://localhost* carve-out only with -Djsentinel.dev=true); response bodies capped at 1 MiB; non-2xx never echoes the server’s error_description; opaque tokens never logged or rendered; client-secret byte arrays zeroed after use; PKCE S256-only; refresh reuse-detection revokes the family before a replayed token is forwarded; client assertions carry a fresh 128-bit jti, a bounded exp and the endpoint aud. Seven new non-secret JSentinel-events types (OAuth2TokenObtained / Failed, RefreshTokenReuseDetected, the device-grant events, OAuth2StateInvalid).

A multi-reviewer exit pass fixed four findings in-cycle — most notably reuse-detection now runs before the AS call (R-EXIT-1, High) and a documented integrator requirement that a REST integrator MUST bind state to the caller’s session (R-EXIT-4); the Vaadin VaadinSessionStateStore does this automatically.

Quality

Full reactor (43 modules) clean install green; -Pstatic-analysis verify (Checkstyle + SpotBugs/FindSecBugs) green on every touched module. No mocks throughout — every flow tested against a real JDK HttpServer with real crypto (RSA/EC keypairs, HMAC, SHA-256): token exchange, PKCE + single-use state, refresh rotation + reuse, introspection cache, client-assertion signatures and the device-grant poll loop. jSentinel-oauth2 first PIT pass: 62 % (184/299) mutation / 80 % line; a targeted lift is a 00.77.x follow-up.

What it does not do

No OIDC ID-token / nonce validation or full OIDC-RP login (00.78), no Stable-API promotion — all 00.77 public types are @ExperimentalJSentinelApi (promotion no earlier than 00.79).

Migration

None. The OAuth2 RP is opt-in; apps that don’t call .oauth2(...) pull no new dependency. Just bump the version to 00.77.00.