Skip to content

Commit

Permalink
Builder setters (#794)
Browse files Browse the repository at this point in the history
- Renamed Keys.forPassword to slightly cleaner/less verbose Keys.password
- Ensured ClaimsMutator extends MapMutator
- Ensured JwtBuilder verifyWith is overloaded and accepts only SecretKey and PublicKey instances
- Ensured JwtBuilder decryptWith is overloaded and accepts only SecretKey and PrivateKey instances
- Renamed JwtParserBuilder#enableUnsecuredJwts() to enableUnsecured() since any JWT or JWS without a header (or with an alg of none) are both considered 'unsecured', so the suffix was removed to avoid confusion.

- Renamed MapMutator `set` methods to `add` methods to avoid Java setter full replacement idiom confusion (as opposed to add/append)

- Removed MapMutator superinterface from ClaimsBuilder.  Generic map mutation methods on the JwtBuilder are a little confusing.
- Added JwtBuilder#claims() method that returns a Claims mutator with an and()  method to get back to the JwtBuilder

- Added a convenience JwtBuilder#claims(Map) method (modern builder-style name)
- Added a new JwtBuilder#encoder to eventually replace the now-deprecated JwtBuilder#base64UrlEncodeWith method
- Added a new JwtBuilder#serializer to eventually replace the now-deprecated JwtBuilder#serializeToJsonWith method

- Renamed JwtParserBuilder#base64UrlDecoder to just JwtParserBuilder#decoder
- Renamed JwtParserBuilder#jsonDeserializer to just JwtParserBuilder#deserializer
- Lots of README.md updates to reflect builder api name changes

- Renamed KeyBuilderSupplier#keyBuilder() to less verbose KeyBuilderSupplier#key()
- Renamed KeyPairBuilderSupplier#keyPairBuilder() to less verbose KeyPairBuilderSupplier#keyPair()

- Renamed ProtoJwkBuilder to DynamicJwkBuilder

- Renamed JwtBuilder.Header to JwtBuilder.BuilderHeader to avoid naming/import conflict with io.jsonwebtoken.Header
- Renamed JwtBuilder.Claims to JwtBuilder.BuilderClaims to avoid naming/import conflict with io.jsonwebtoken.Claims

- removed DynamicJwkBuilder chain methods with array arguments
- added generic DynamicJwkBuilder#keyPair(KeyPair) method
- added generic DynamicJwkBuilder#chain method

- Reintroduced deprecated Header mutation methods for a slightly easier transition to 0.12.0, will remove in next release

- Deprecated public String constants in Header.java and JwsHeader.java

- Documentation, JavaDoc and code example changes/formatting fixes and enhancements
  • Loading branch information
lhazlewood committed Aug 9, 2023
1 parent db94dc7 commit 7ed0b77
Show file tree
Hide file tree
Showing 140 changed files with 2,550 additions and 1,836 deletions.
55 changes: 31 additions & 24 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ available immediately. For example:

```java
AeadAlgorithm enc = Jwts.ENC.A256GCM;
SecretKey key = enc.keyBuilder().build();
SecretKey key = enc.key().build();
String compact = Jwts.builder().setSubject("Joe").encryptWith(key, enc).compact();

Jwe<Claims> jwe = Jwts.parser().decryptWith(key).build().parseClaimsJwe(compact);
Expand All @@ -56,7 +56,7 @@ Private keys - as fully encoded JSON objects according to the JWK specification
supported. The new `Jwks` utility class exists to create JWK builders and parsers as desired. For example:

```java
SecretKey key = Jwts.SIG.HS256.keyBuilder().build();
SecretKey key = Jwts.SIG.HS256.key().build();
SecretJwk jwk = Jwks.builder().forKey(key).build();
assert key.equals(jwk.toKey());

Expand Down Expand Up @@ -92,12 +92,12 @@ interfaces now allow anyone to plug in and support custom algorithms with JJWT a

Because the `io.jsonwebtoken.security.Keys#secretKeyFor` and `io.jsonwebtoken.security.Keys#keyPairFor` methods
accepted the now-deprecated `io.jsonwebtoken.SignatureAlgorithm` enum, they have also been deprecated in favor of
calling new `keyBuilder()` or `keyPairBuilder()` methods on `MacAlgorithm` and `SignatureAlgorithm` instances directly.
calling new `key()` or `keyPair()` builder methods on `MacAlgorithm` and `SignatureAlgorithm` instances directly.
For example:

```java
SecretKey key = Jwts.SIG.HS256.keyBuilder().build();
KeyPair pair = Jwts.SIG.RS256.keyPairBuilder().build();
SecretKey key = Jwts.SIG.HS256.key().build();
KeyPair pair = Jwts.SIG.RS256.keyPair().build();
```

The builders allow for customization of the JCA `Provider` and `SecureRandom` during Key or KeyPair generation if desired, whereas
Expand All @@ -121,15 +121,34 @@ deprecate some concepts, or in some cases, completely break backwards compatibil
support expected congruent behavior with `Jwe` instances (both have digests).


* `io.jsonwebtoken.CompressionCodec` now inherits a new `io.jsonwebtoken.Identifiable` interface and its `getId()`
method is preferred over the now-deprecated `getAlgorithmName()` method. This is to guarantee API congruence with
all other JWT-identifiable algorithm names that can be set as a header value.
* `io.jsonwebtoken.CompressionCodec` is now deprecated in favor of the new `io.jsonwebtoken.io.CompressionAlgorithm`
interface. This is to guarantee API congruence with all other JWT-identifiable algorithm IDs that can be set as a
header value.


* `io.jsonwebtoken.CompressionCodecResolver` has been deprecated in favor of the new
`JwtParserBuilder#addCompressionAlgorithms` method.


#### Breaking Changes

* **`io.jsonwebtoken.Claims` and `io.jsonwebtoken.Header` instances are now immutable** to enhance security and thread
safety. Creation and mutation are supported with newly introduced `ClaimsBuilder` and `HeaderBuilder` concepts.
Even though mutation methods have migrated, there are a couple that have been removed entirely:
* `io.jsonwebtoken.JwsHeader#setAlgorithm` has been removed - the `JwtBuilder` will always set the appropriate
`alg` header automatically based on builder state.
* `io.jsonwebtoken.Header#setCompressionAlgorithm` has been removed - the `JwtBuilder` will always set the appropriate
`zip` header automatically based on builder state.


* `io.jsonwebtoken.Jwts`'s `header(Map)`, `jwsHeader()` and `jwsHeader(Map)` methods have been removed in favor
of the new `header()` builder-based method to support method chaining and dynamic Header type creation.
of the new `header()` method that returns a `HeaderBuilder` to support method chaining and dynamic `Header` type
creation. The `HeaderBuilder` will dynamically create a `Header`, `JwsHeader` or `JweHeader` automatically based on
builder state.


* Similarly, `io.jsonwebtoken.Jwts`'s `claims()` static method has been changed to return a `ClaimsBuilder` instead
of a `Claims` instance.


* **JWTs that do not contain JSON Claims now have a payload type of `byte[]` instead of `String`** (that is,
Expand Down Expand Up @@ -166,19 +185,6 @@ deprecate some concepts, or in some cases, completely break backwards compatibil
`resolveSigningKey(JwsHeader, byte[])`.


* **`io.jsonwebtoken.Claims` and `io.jsonwebtoken.Header` instances are now immutable** to enhance security and thread
safety. Creation and mutation are supported with newly introduced `ClaimsBuilder` and `HeaderBuilder` concepts.


* Consequently, `io.jsonwebtoken.Jwts`'s `claims()` static method has been changed to return a `ClaimsBuilder` instead
of a `Claims` instance.


* Similarly, `io.jsonwebtoken.Jwts`'s `header()` static method has been changed to return a `HeaderBuilder` instead of
a `Header` instance. The `HeaderBuilder` will dynamically create a `Header`, `JwsHeader` or `JweHeader`
automatically based on builder state.


* `io.jsonwebtoken.JwtParser` is now immutable. All mutation/modification methods (setters, etc) deprecated 4 years
ago have been removed. All parser configuration requires using the `JwtParserBuilder` (i.e.
`Jwts.parser()`).
Expand All @@ -191,7 +197,8 @@ deprecate some concepts, or in some cases, completely break backwards compatibil

* `io.jsonwebtoken.CompressionCodec` implementations are no longer discoverable via `java.util.ServiceLoader` due to
runtime performance problems with the JDK's `ServiceLoader` implementation per
https://github.com/jwtk/jjwt/issues/648.
https://github.com/jwtk/jjwt/issues/648. Custom implementations should be made available to the `JwtParser` via
the new `JwtParserBuilder#addCompressionAlgorithms` method.


* Prior to this release, if there was a serialization problem when serializing the JWT Header, an `IllegalStateException`
Expand All @@ -202,7 +209,7 @@ deprecate some concepts, or in some cases, completely break backwards compatibil

* Parsing of unsecured JWTs (`alg` header of `none`) are now disabled by default as mandated by
[RFC 7518, Section 3.6](https://www.rfc-editor.org/rfc/rfc7518.html#section-3.6). If you require parsing of
unsecured JWTs, you must call the `enableUnsecuredJws` method on the `JwtParserBuilder`, but note the security
unsecured JWTs, you must call the `JwtParserBuilder#enableUnsecured()` method, but note the security
implications mentioned in that method's JavaDoc before doing so.


Expand Down
Loading

0 comments on commit 7ed0b77

Please sign in to comment.