mirror of https://github.com/jwtk/jjwt.git
Builder setters (#794)
- 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
This commit is contained in:
parent
db94dc7b79
commit
7ed0b772ae
55
CHANGELOG.md
55
CHANGELOG.md
|
@ -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);
|
||||
|
@ -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());
|
||||
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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()`).
|
||||
|
@ -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`
|
||||
|
@ -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.
|
||||
|
||||
|
||||
|
|
|
@ -33,27 +33,66 @@ public interface ClaimsMutator<T extends ClaimsMutator<T>> {
|
|||
*
|
||||
* @param iss the JWT {@code iss} value or {@code null} to remove the property from the JSON map.
|
||||
* @return the {@code Claims} instance for method chaining.
|
||||
* @deprecated since JJWT_RELEASE_VERSION in favor of the shorter and more modern builder-style named
|
||||
* {@link #issuer(String)}. This method will be removed before the JJWT 1.0 release.
|
||||
*/
|
||||
@Deprecated
|
||||
T setIssuer(String iss);
|
||||
|
||||
/**
|
||||
* Sets the JWT <a href="https://www.rfc-editor.org/rfc/rfc7519.html#section-4.1.1">
|
||||
* <code>iss</code></a> (issuer) value. A {@code null} value will remove the property from the JSON map.
|
||||
*
|
||||
* @param iss the JWT {@code iss} value or {@code null} to remove the property from the JSON map.
|
||||
* @return the {@code Claims} instance for method chaining.
|
||||
* @since JJWT_RELEASE_VERSION
|
||||
*/
|
||||
T issuer(String iss);
|
||||
|
||||
/**
|
||||
* Sets the JWT <a href="https://www.rfc-editor.org/rfc/rfc7519.html#section-4.1.2">
|
||||
* <code>sub</code></a> (subject) value. A {@code null} value will remove the property from the JSON map.
|
||||
*
|
||||
* @param sub the JWT {@code sub} value or {@code null} to remove the property from the JSON map.
|
||||
* @return the {@code Claims} instance for method chaining.
|
||||
* @deprecated since JJWT_RELEASE_VERSION in favor of the shorter and more modern builder-style named
|
||||
* {@link #subject(String)}. This method will be removed before the JJWT 1.0 release.
|
||||
*/
|
||||
@Deprecated
|
||||
T setSubject(String sub);
|
||||
|
||||
/**
|
||||
* Sets the JWT <a href="https://www.rfc-editor.org/rfc/rfc7519.html#section-4.1.2">
|
||||
* <code>sub</code></a> (subject) value. A {@code null} value will remove the property from the JSON map.
|
||||
*
|
||||
* @param sub the JWT {@code sub} value or {@code null} to remove the property from the JSON map.
|
||||
* @return the {@code Claims} instance for method chaining.
|
||||
* @since JJWT_RELEASE_VERSION
|
||||
*/
|
||||
T subject(String sub);
|
||||
|
||||
/**
|
||||
* Sets the JWT <a href="https://www.rfc-editor.org/rfc/rfc7519.html#section-4.1.3">
|
||||
* <code>aud</code></a> (audience) value. A {@code null} value will remove the property from the JSON map.
|
||||
*
|
||||
* @param aud the JWT {@code aud} value or {@code null} to remove the property from the JSON map.
|
||||
* @return the {@code Claims} instance for method chaining.
|
||||
* @deprecated since JJWT_RELEASE_VERSION in favor of the shorter and more modern builder-style named
|
||||
* {@link #audience(String)}. This method will be removed before the JJWT 1.0 release.
|
||||
*/
|
||||
@Deprecated
|
||||
T setAudience(String aud);
|
||||
|
||||
/**
|
||||
* Sets the JWT <a href="https://www.rfc-editor.org/rfc/rfc7519.html#section-4.1.3">
|
||||
* <code>aud</code></a> (audience) value. A {@code null} value will remove the property from the JSON map.
|
||||
*
|
||||
* @param aud the JWT {@code aud} value or {@code null} to remove the property from the JSON map.
|
||||
* @return the {@code Claims} instance for method chaining.
|
||||
* @since JJWT_RELEASE_VERSION
|
||||
*/
|
||||
T audience(String aud);
|
||||
|
||||
/**
|
||||
* Sets the JWT <a href="https://www.rfc-editor.org/rfc/rfc7519.html#section-4.1.4">
|
||||
* <code>exp</code></a> (expiration) timestamp. A {@code null} value will remove the property from the JSON map.
|
||||
|
@ -62,9 +101,24 @@ public interface ClaimsMutator<T extends ClaimsMutator<T>> {
|
|||
*
|
||||
* @param exp the JWT {@code exp} value or {@code null} to remove the property from the JSON map.
|
||||
* @return the {@code Claims} instance for method chaining.
|
||||
* @deprecated since JJWT_RELEASE_VERSION in favor of the shorter and more modern builder-style named
|
||||
* {@link #expiration(Date)}. This method will be removed before the JJWT 1.0 release.
|
||||
*/
|
||||
@Deprecated
|
||||
T setExpiration(Date exp);
|
||||
|
||||
/**
|
||||
* Sets the JWT <a href="https://www.rfc-editor.org/rfc/rfc7519.html#section-4.1.4">
|
||||
* <code>exp</code></a> (expiration) timestamp. A {@code null} value will remove the property from the JSON map.
|
||||
*
|
||||
* <p>A JWT obtained after this timestamp should not be used.</p>
|
||||
*
|
||||
* @param exp the JWT {@code exp} value or {@code null} to remove the property from the JSON map.
|
||||
* @return the {@code Claims} instance for method chaining.
|
||||
* @since JJWT_RELEASE_VERSION
|
||||
*/
|
||||
T expiration(Date exp);
|
||||
|
||||
/**
|
||||
* Sets the JWT <a href="https://www.rfc-editor.org/rfc/rfc7519.html#section-4.1.5">
|
||||
* <code>nbf</code></a> (not before) timestamp. A {@code null} value will remove the property from the JSON map.
|
||||
|
@ -73,9 +127,24 @@ public interface ClaimsMutator<T extends ClaimsMutator<T>> {
|
|||
*
|
||||
* @param nbf the JWT {@code nbf} value or {@code null} to remove the property from the JSON map.
|
||||
* @return the {@code Claims} instance for method chaining.
|
||||
* @deprecated since JJWT_RELEASE_VERSION in favor of the shorter and more modern builder-style named
|
||||
* {@link #notBefore(Date)}. This method will be removed before the JJWT 1.0 release.
|
||||
*/
|
||||
@Deprecated
|
||||
T setNotBefore(Date nbf);
|
||||
|
||||
/**
|
||||
* Sets the JWT <a href="https://www.rfc-editor.org/rfc/rfc7519.html#section-4.1.5">
|
||||
* <code>nbf</code></a> (not before) timestamp. A {@code null} value will remove the property from the JSON map.
|
||||
*
|
||||
* <p>A JWT obtained before this timestamp should not be used.</p>
|
||||
*
|
||||
* @param nbf the JWT {@code nbf} value or {@code null} to remove the property from the JSON map.
|
||||
* @return the {@code Claims} instance for method chaining.
|
||||
* @since JJWT_RELEASE_VERSION
|
||||
*/
|
||||
T notBefore(Date nbf);
|
||||
|
||||
/**
|
||||
* Sets the JWT <a href="https://www.rfc-editor.org/rfc/rfc7519.html#section-4.1.6">
|
||||
* <code>iat</code></a> (issued at) timestamp. A {@code null} value will remove the property from the JSON map.
|
||||
|
@ -84,9 +153,24 @@ public interface ClaimsMutator<T extends ClaimsMutator<T>> {
|
|||
*
|
||||
* @param iat the JWT {@code iat} value or {@code null} to remove the property from the JSON map.
|
||||
* @return the {@code Claims} instance for method chaining.
|
||||
* @deprecated since JJWT_RELEASE_VERSION in favor of the shorter and more modern builder-style named
|
||||
* {@link #issuedAt(Date)}. This method will be removed before the JJWT 1.0 release.
|
||||
*/
|
||||
@Deprecated
|
||||
T setIssuedAt(Date iat);
|
||||
|
||||
/**
|
||||
* Sets the JWT <a href="https://www.rfc-editor.org/rfc/rfc7519.html#section-4.1.6">
|
||||
* <code>iat</code></a> (issued at) timestamp. A {@code null} value will remove the property from the JSON map.
|
||||
*
|
||||
* <p>The value is the timestamp when the JWT was created.</p>
|
||||
*
|
||||
* @param iat the JWT {@code iat} value or {@code null} to remove the property from the JSON map.
|
||||
* @return the {@code Claims} instance for method chaining.
|
||||
* @since JJWT_RELEASE_VERSION
|
||||
*/
|
||||
T issuedAt(Date iat);
|
||||
|
||||
/**
|
||||
* Sets the JWT <a href="https://www.rfc-editor.org/rfc/rfc7519.html#section-4.1.7">
|
||||
* <code>jti</code></a> (JWT ID) value. A {@code null} value will remove the property from the JSON map.
|
||||
|
@ -97,6 +181,23 @@ public interface ClaimsMutator<T extends ClaimsMutator<T>> {
|
|||
*
|
||||
* @param jti the JWT {@code jti} value or {@code null} to remove the property from the JSON map.
|
||||
* @return the {@code Claims} instance for method chaining.
|
||||
* @deprecated since JJWT_RELEASE_VERSION in favor of the shorter and more modern builder-style named
|
||||
* {@link #id(String)}. This method will be removed before the JJWT 1.0 release.
|
||||
*/
|
||||
@Deprecated
|
||||
T setId(String jti);
|
||||
|
||||
/**
|
||||
* Sets the JWT <a href="https://www.rfc-editor.org/rfc/rfc7519.html#section-4.1.7">
|
||||
* <code>jti</code></a> (JWT ID) value. A {@code null} value will remove the property from the JSON map.
|
||||
*
|
||||
* <p>This value is a CaSe-SenSiTiVe unique identifier for the JWT. If specified, this value MUST be assigned in a
|
||||
* manner that ensures that there is a negligible probability that the same value will be accidentally
|
||||
* assigned to a different data object. The ID can be used to prevent the JWT from being replayed.</p>
|
||||
*
|
||||
* @param jti the JWT {@code jti} value or {@code null} to remove the property from the JSON map.
|
||||
* @return the {@code Claims} instance for method chaining.
|
||||
* @since JJWT_RELEASE_VERSION
|
||||
*/
|
||||
T id(String jti);
|
||||
}
|
||||
|
|
|
@ -54,12 +54,16 @@ public interface Header extends Map<String, Object> {
|
|||
|
||||
/**
|
||||
* JWT {@code Type} header parameter name: <code>"typ"</code>
|
||||
* @deprecated since JJWT_RELEASE_VERSION in favor of {@link #getType()}.
|
||||
*/
|
||||
@Deprecated
|
||||
String TYPE = "typ";
|
||||
|
||||
/**
|
||||
* JWT {@code Content Type} header parameter name: <code>"cty"</code>
|
||||
* @deprecated since JJWT_RELEASE_VERSION in favor of {@link #getContentType()}.
|
||||
*/
|
||||
@Deprecated
|
||||
String CONTENT_TYPE = "cty";
|
||||
|
||||
/**
|
||||
|
@ -67,12 +71,16 @@ public interface Header extends Map<String, Object> {
|
|||
*
|
||||
* @see <a href="https://tools.ietf.org/html/rfc7515#section-4.1.1">JWS Algorithm Header</a>
|
||||
* @see <a href="https://tools.ietf.org/html/rfc7516#section-4.1.1">JWE Algorithm Header</a>
|
||||
* @deprecated since JJWT_RELEASE_VERSION in favor of {@link #getAlgorithm()}.
|
||||
*/
|
||||
@Deprecated
|
||||
String ALGORITHM = "alg";
|
||||
|
||||
/**
|
||||
* JWT {@code Compression Algorithm} header parameter name: <code>"zip"</code>
|
||||
* @deprecated since JJWT_RELEASE_VERSION in favor of {@link #getCompressionAlgorithm()}
|
||||
*/
|
||||
@Deprecated
|
||||
String COMPRESSION_ALGORITHM = "zip";
|
||||
|
||||
/**
|
||||
|
|
|
@ -25,14 +25,41 @@ import io.jsonwebtoken.lang.MapMutator;
|
|||
*/
|
||||
public interface HeaderMutator<T extends HeaderMutator<T>> extends MapMutator<String, Object, T> {
|
||||
|
||||
//IMPLEMENTOR NOTE: if this `algorithm` method ever needs to be exposed in the public API, it might be better to
|
||||
// have it in the Jwts.HeaderBuilder interface and NOT this one: in the context of
|
||||
// JwtBuilder.Header, there is never a reason for an application developer to call algorithm(id)
|
||||
// directly because the KeyAlgorithm or SecureDigestAlgorithm instance must always be provided
|
||||
// via the signWith or encryptWith methods. The JwtBuilder will always set the algorithm
|
||||
// header based on these two instances, so there is no need for an app dev to do so.
|
||||
/*
|
||||
* Sets the JWT {@code alg} (Algorithm) header value. A {@code null} value will remove the property
|
||||
* from the JSON map.
|
||||
* <ul>
|
||||
* <li>If the JWT is a Signed JWT (a JWS), the
|
||||
* <a href="https://tools.ietf.org/html/rfc7515#section-4.1.1">{@code alg}</a> (Algorithm) header
|
||||
* parameter identifies the cryptographic algorithm used to secure the JWS.</li>
|
||||
* <li>If the JWT is an Encrypted JWT (a JWE), the
|
||||
* <a href="https://tools.ietf.org/html/rfc7516#section-4.1.1"><code>alg</code></a> (Algorithm) header parameter
|
||||
* identifies the cryptographic key management algorithm used to encrypt or determine the value of the Content
|
||||
* Encryption Key (CEK). The encrypted content is not usable if the <code>alg</code> value does not represent a
|
||||
* supported algorithm, or if the recipient does not have a key that can be used with that algorithm.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param alg the {@code alg} header value
|
||||
* @return this header for method chaining
|
||||
* @since JJWT_RELEASE_VERSION
|
||||
*
|
||||
T algorithm(String alg);
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sets the JWT <a href="https://www.rfc-editor.org/rfc/rfc7519.html#section-5.1">
|
||||
* <code>typ</code> (Type)</a> header value. A {@code null} value will remove the property from the JSON map.
|
||||
*
|
||||
* @param typ the JWT JOSE {@code typ} header value or {@code null} to remove the property from the JSON map.
|
||||
* @return the {@code Header} instance for method chaining.
|
||||
* @return the instance for method chaining.
|
||||
*/
|
||||
T setType(String typ);
|
||||
T type(String typ);
|
||||
|
||||
/**
|
||||
* Sets the JWT <a href="https://www.rfc-editor.org/rfc/rfc7515.html#section-4.1.10">
|
||||
|
@ -57,46 +84,42 @@ public interface HeaderMutator<T extends HeaderMutator<T>> extends MapMutator<St
|
|||
* <b><code>example;part="1/2"</code></b>.</p>
|
||||
*
|
||||
* @param cty the JWT JOSE {@code cty} header value or {@code null} to remove the property from the JSON map.
|
||||
* @return the {@code Header} instance for method chaining.
|
||||
* @return the instance for method chaining.
|
||||
*/
|
||||
T contentType(String cty);
|
||||
|
||||
/**
|
||||
* Deprecated since of JJWT_RELEASE_VERSION, delegates to {@link #type(String)}.
|
||||
*
|
||||
* @param typ the JWT JOSE {@code typ} header value or {@code null} to remove the property from the JSON map.
|
||||
* @return the instance for method chaining.
|
||||
* @see #type(String)
|
||||
* @deprecated since JJWT_RELEASE_VERSION in favor of the more modern builder-style {@link #type(String)} method.
|
||||
* This method will be removed before the 1.0 release.
|
||||
*/
|
||||
@Deprecated
|
||||
T setType(String typ);
|
||||
|
||||
/**
|
||||
* Deprecated as of JJWT_RELEASE_VERSION, delegates to {@link #contentType(String)}.
|
||||
*
|
||||
* @param cty the JWT JOSE {@code cty} header value or {@code null} to remove the property from the JSON map.
|
||||
* @return the instance for method chaining.
|
||||
* @see #contentType(String)
|
||||
* @deprecated since JJWT_RELEASE_VERSION in favor of the more modern builder-style {@link #contentType(String)}.
|
||||
*/
|
||||
@Deprecated
|
||||
T setContentType(String cty);
|
||||
|
||||
/**
|
||||
* Sets the JWT {@code alg} (Algorithm) header value. A {@code null} value will remove the property
|
||||
* from the JSON map.
|
||||
* <ul>
|
||||
* <li>If the JWT is a Signed JWT (a JWS), the
|
||||
* <a href="https://tools.ietf.org/html/rfc7515#section-4.1.1">{@code alg}</a> (Algorithm) header
|
||||
* parameter identifies the cryptographic algorithm used to secure the JWS.</li>
|
||||
* <li>If the JWT is an Encrypted JWT (a JWE), the
|
||||
* <a href="https://tools.ietf.org/html/rfc7516#section-4.1.1"><code>alg</code></a> (Algorithm) header parameter
|
||||
* identifies the cryptographic key management algorithm used to encrypt or determine the value of the Content
|
||||
* Encryption Key (CEK). The encrypted content is not usable if the <code>alg</code> value does not represent a
|
||||
* supported algorithm, or if the recipient does not have a key that can be used with that algorithm.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param alg the {@code alg} header value
|
||||
* @return this header for method chaining
|
||||
* @since JJWT_RELEASE_VERSION
|
||||
*/
|
||||
T setAlgorithm(String alg);
|
||||
|
||||
/**
|
||||
* Sets the JWT <a href="https://tools.ietf.org/html/rfc7516#section-4.1.3"><code>zip</code></a>
|
||||
* (Compression Algorithm) header parameter value. A {@code null} value will remove
|
||||
* the property from the JSON map.
|
||||
*
|
||||
* <p><b>Compatibility Note</b></p>
|
||||
*
|
||||
* <p>While the JWT family of specifications only defines the <code>zip</code> header in the JWE
|
||||
* (JSON Web Encryption) specification, JJWT will also support compression for JWS as well if you choose to use it.
|
||||
* However, be aware that <b>if you use compression when creating a JWS token, other libraries may not be able to
|
||||
* parse the JWS</b>. However, Compression when creating JWE tokens should be universally accepted for any library
|
||||
* that supports JWE.</p>
|
||||
* Deprecated as of JJWT_RELEASE_VERSION, there is no need to set this any longer as the {@code JwtBuilder} will
|
||||
* always set the {@code zip} header as necessary.
|
||||
*
|
||||
* @param zip the JWT compression algorithm {@code zip} value or {@code null} to remove the property from the JSON map.
|
||||
* @return the {@code Header} instance for method chaining.
|
||||
* @return the instance for method chaining.
|
||||
* @since 0.6.0
|
||||
* @deprecated since JJWT_RELEASE_VERSION and will be removed before the 1.0 release.
|
||||
*/
|
||||
@Deprecated
|
||||
T setCompressionAlgorithm(String zip);
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ public interface JweHeaderMutator<T extends JweHeaderMutator<T>> extends Protect
|
|||
* @see Jwts.KEY#ECDH_ES_A192KW
|
||||
* @see Jwts.KEY#ECDH_ES_A256KW
|
||||
*/
|
||||
T setAgreementPartyUInfo(byte[] info);
|
||||
T agreementPartyUInfo(byte[] info);
|
||||
|
||||
/**
|
||||
* Sets any information about the JWE producer for use with key agreement algorithms. A {@code null} value removes
|
||||
|
@ -45,7 +45,7 @@ public interface JweHeaderMutator<T extends JweHeaderMutator<T>> extends Protect
|
|||
*
|
||||
* <p>If not {@code null}, this is a convenience method that calls the equivalent of the following:</p>
|
||||
* <blockquote><pre>
|
||||
* {@link #setAgreementPartyUInfo(byte[]) setAgreementPartyUInfo}(info.getBytes(StandardCharsets.UTF_8))</pre></blockquote>
|
||||
* {@link #agreementPartyUInfo(byte[]) agreementPartyUInfo}(info.getBytes(StandardCharsets.UTF_8))</pre></blockquote>
|
||||
*
|
||||
* @param info information about the JWE producer to use with key agreement algorithms.
|
||||
* @return the header for method chaining.
|
||||
|
@ -55,7 +55,7 @@ public interface JweHeaderMutator<T extends JweHeaderMutator<T>> extends Protect
|
|||
* @see Jwts.KEY#ECDH_ES_A192KW
|
||||
* @see Jwts.KEY#ECDH_ES_A256KW
|
||||
*/
|
||||
T setAgreementPartyUInfo(String info);
|
||||
T agreementPartyUInfo(String info);
|
||||
|
||||
/**
|
||||
* Sets any information about the JWE recipient for use with key agreement algorithms. A {@code null} value removes
|
||||
|
@ -69,7 +69,7 @@ public interface JweHeaderMutator<T extends JweHeaderMutator<T>> extends Protect
|
|||
* @see Jwts.KEY#ECDH_ES_A192KW
|
||||
* @see Jwts.KEY#ECDH_ES_A256KW
|
||||
*/
|
||||
T setAgreementPartyVInfo(byte[] info);
|
||||
T agreementPartyVInfo(byte[] info);
|
||||
|
||||
/**
|
||||
* Sets any information about the JWE recipient for use with key agreement algorithms. A {@code null} value removes
|
||||
|
@ -77,7 +77,7 @@ public interface JweHeaderMutator<T extends JweHeaderMutator<T>> extends Protect
|
|||
*
|
||||
* <p>If not {@code null}, this is a convenience method that calls the equivalent of the following:</p>
|
||||
* <blockquote><pre>
|
||||
* {@link #setAgreementPartyVInfo(byte[]) setAgreementPartVUInfo}(info.getBytes(StandardCharsets.UTF_8))</pre></blockquote>
|
||||
* {@link #agreementPartyVInfo(byte[]) setAgreementPartVUInfo}(info.getBytes(StandardCharsets.UTF_8))</pre></blockquote>
|
||||
*
|
||||
* @param info information about the JWE recipient to use with key agreement algorithms.
|
||||
* @return the header for method chaining.
|
||||
|
@ -87,7 +87,7 @@ public interface JweHeaderMutator<T extends JweHeaderMutator<T>> extends Protect
|
|||
* @see Jwts.KEY#ECDH_ES_A192KW
|
||||
* @see Jwts.KEY#ECDH_ES_A256KW
|
||||
*/
|
||||
T setAgreementPartyVInfo(String info);
|
||||
T agreementPartyVInfo(String info);
|
||||
|
||||
/**
|
||||
* Sets the number of PBKDF2 iterations necessary to derive the key used during JWE encryption. If this value
|
||||
|
@ -112,5 +112,5 @@ public interface JweHeaderMutator<T extends JweHeaderMutator<T>> extends Protect
|
|||
* @see Jwts.KEY#PBES2_HS512_A256KW
|
||||
* @see <a href="https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html#pbkdf2">OWASP PBKDF2 Iteration Recommendations</a>
|
||||
*/
|
||||
T setPbes2Count(int count);
|
||||
T pbes2Count(int count);
|
||||
}
|
||||
|
|
|
@ -24,46 +24,73 @@ public interface JwsHeader extends ProtectedHeader {
|
|||
|
||||
/**
|
||||
* JWS <a href="https://tools.ietf.org/html/rfc7515#section-4.1.1">Algorithm Header</a> name: the string literal <b><code>alg</code></b>
|
||||
*
|
||||
* @deprecated since JJWT_RELEASE_VERSION in favor of {@link #getAlgorithm()}
|
||||
*/
|
||||
@Deprecated
|
||||
String ALGORITHM = "alg";
|
||||
|
||||
/**
|
||||
* JWS <a href="https://tools.ietf.org/html/rfc7515#section-4.1.2">JWK Set URL Header</a> name: the string literal <b><code>jku</code></b>
|
||||
*
|
||||
* @deprecated since JJWT_RELEASE_VERSION in favor of {@link #getJwkSetUrl()}
|
||||
*/
|
||||
@Deprecated
|
||||
String JWK_SET_URL = "jku";
|
||||
|
||||
/**
|
||||
* JWS <a href="https://tools.ietf.org/html/rfc7515#section-4.1.3">JSON Web Key Header</a> name: the string literal <b><code>jwk</code></b>
|
||||
*
|
||||
* @deprecated since JJWT_RELEASE_VERSION in favor of {@link #getJwk()}
|
||||
*/
|
||||
@Deprecated
|
||||
String JSON_WEB_KEY = "jwk";
|
||||
|
||||
/**
|
||||
* JWS <a href="https://tools.ietf.org/html/rfc7516#section-4.1.4">Key ID Header</a> name: the string literal <b><code>kid</code></b>
|
||||
*
|
||||
* @deprecated since JJWT_RELEASE_VERSION in favor of {@link #getKeyId()}
|
||||
*/
|
||||
@Deprecated
|
||||
String KEY_ID = "kid";
|
||||
|
||||
/**
|
||||
* JWS <a href="https://tools.ietf.org/html/rfc7516#section-4.1.5">X.509 URL Header</a> name: the string literal <b><code>x5u</code></b>
|
||||
*
|
||||
* @deprecated since JJWT_RELEASE_VERSION in favor of {@link #getX509Url()}
|
||||
*/
|
||||
@Deprecated
|
||||
String X509_URL = "x5u";
|
||||
|
||||
/**
|
||||
* JWS <a href="https://tools.ietf.org/html/rfc7516#section-4.1.6">X.509 Certificate Chain Header</a> name: the string literal <b><code>x5c</code></b>
|
||||
*
|
||||
* @deprecated since JJWT_RELEASE_VERSION in favor of {@link #getX509CertificateChain()}
|
||||
*/
|
||||
@Deprecated
|
||||
String X509_CERT_CHAIN = "x5c";
|
||||
|
||||
/**
|
||||
* JWS <a href="https://tools.ietf.org/html/rfc7516#section-4.1.7">X.509 Certificate SHA-1 Thumbprint Header</a> name: the string literal <b><code>x5t</code></b>
|
||||
*
|
||||
* @deprecated since JJWT_RELEASE_VERSION in favor of {@link #getX509CertificateSha1Thumbprint()}
|
||||
*/
|
||||
@Deprecated
|
||||
String X509_CERT_SHA1_THUMBPRINT = "x5t";
|
||||
|
||||
/**
|
||||
* JWS <a href="https://tools.ietf.org/html/rfc7516#section-4.1.8">X.509 Certificate SHA-256 Thumbprint Header</a> name: the string literal <b><code>x5t#S256</code></b>
|
||||
*
|
||||
* @deprecated since JJWT_RELEASE_VERSION in favor of {@link #getX509CertificateSha256Thumbprint()}
|
||||
*/
|
||||
@Deprecated
|
||||
String X509_CERT_SHA256_THUMBPRINT = "x5t#S256";
|
||||
|
||||
/**
|
||||
* JWS <a href="https://tools.ietf.org/html/rfc7516#section-4.1.11">Critical Header</a> name: the string literal <b><code>crit</code></b>
|
||||
*
|
||||
* @deprecated since JJWT_RELEASE_VERSION in favor of {@link #getCritical()}
|
||||
*/
|
||||
@Deprecated
|
||||
String CRITICAL = "crit";
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import io.jsonwebtoken.io.Decoder;
|
|||
import io.jsonwebtoken.io.Decoders;
|
||||
import io.jsonwebtoken.io.Encoder;
|
||||
import io.jsonwebtoken.io.Serializer;
|
||||
import io.jsonwebtoken.lang.MapMutator;
|
||||
import io.jsonwebtoken.security.AeadAlgorithm;
|
||||
import io.jsonwebtoken.security.InvalidKeyException;
|
||||
import io.jsonwebtoken.security.KeyAlgorithm;
|
||||
|
@ -55,7 +56,7 @@ public interface JwtBuilder extends ClaimsMutator<JwtBuilder> {
|
|||
* @return the builder for method chaining.
|
||||
* @since JJWT_RELEASE_VERSION
|
||||
*/
|
||||
JwtBuilder setProvider(Provider provider);
|
||||
JwtBuilder provider(Provider provider);
|
||||
|
||||
/**
|
||||
* Sets the {@link SecureRandom} to use during cryptographic signing or encryption operations, or {@code null} if
|
||||
|
@ -66,95 +67,125 @@ public interface JwtBuilder extends ClaimsMutator<JwtBuilder> {
|
|||
* @return the builder for method chaining.
|
||||
* @since JJWT_RELEASE_VERSION
|
||||
*/
|
||||
JwtBuilder setSecureRandom(SecureRandom secureRandom);
|
||||
JwtBuilder random(SecureRandom secureRandom);
|
||||
|
||||
/**
|
||||
* Returns the {@link JwtBuilder.Header} to use to modify the constructed JWT's header name/value pairs as desired.
|
||||
* When finished, callers may return to JWT construction via the {@link JwtBuilder.Header#and() and()} method.
|
||||
* Returns the {@code Header} to use to modify the constructed JWT's header name/value pairs as desired.
|
||||
* When finished, callers may return to JWT construction via the {@link BuilderHeader#and() and()} method.
|
||||
* For example:
|
||||
*
|
||||
* <blockquote><pre>
|
||||
* String jwt = Jwts.builder()
|
||||
*
|
||||
* <b>.header()
|
||||
* .setKeyId("keyId")
|
||||
* .set(myHeaderMap)
|
||||
* // ... other header params ...
|
||||
* .{@link JwtBuilder.Header#and() and()}</b> //return back to the JwtBuilder
|
||||
* .keyId("keyId")
|
||||
* .add("aName", aValue)
|
||||
* .add(myHeaderMap)
|
||||
* // ... etc ...
|
||||
* .{@link BuilderHeader#and() and()}</b> //return back to the JwtBuilder
|
||||
*
|
||||
* .setSubject("Joe") // resume JwtBuilder calls
|
||||
* .subject("Joe") // resume JwtBuilder calls
|
||||
* // ... etc ...
|
||||
* .compact();</pre></blockquote>
|
||||
*
|
||||
* @return the {@link JwtBuilder.Header} to use for header construction.
|
||||
* @return the {@link BuilderHeader} to use for header construction.
|
||||
* @since JJWT_RELEASE_VERSION
|
||||
*/
|
||||
JwtBuilder.Header header();
|
||||
BuilderHeader header();
|
||||
|
||||
/**
|
||||
* Sets (and replaces) any existing header with the specified name/value pairs. If you do not want to replace the
|
||||
* existing header and only want to append to it, call
|
||||
* {@link #header()}{@code .}{@link io.jsonwebtoken.lang.MapMutator#set(Map) set(map)}
|
||||
* instead.
|
||||
* Per standard Java idiom 'setter' conventions, this method sets (and fully replaces) any existing header with the
|
||||
* specified name/value pairs. This is a wrapper method for:
|
||||
*
|
||||
* <blockquote><pre>
|
||||
* {@link #header()}.{@link MapMutator#empty() empty()}.{@link MapMutator#add(Map) add(map)}.{@link BuilderHeader#and() and()}</pre></blockquote>
|
||||
*
|
||||
* <p>If you do not want to replace the existing header and only want to append to it,
|
||||
* call <code>{@link #header()}.{@link io.jsonwebtoken.lang.MapMutator#add(Map) add(map)}.{@link BuilderHeader#and() and()}</code> instead.</p>
|
||||
*
|
||||
* @param map the name/value pairs to set as (and potentially replace) the constructed JWT header.
|
||||
* @return the builder for method chaining.
|
||||
* @deprecated since JJWT_RELEASE_VERSION in favor of
|
||||
* <code>{@link #header()}.{@link MapMutator#empty() empty()}.{@link MapMutator#add(Map) add(map)}.{@link BuilderHeader#and() and()}</code>
|
||||
* (to replace all header parameters) or
|
||||
* <code>{@link #header()}.{@link MapMutator#add(Map) add(map)}.{@link BuilderHeader#and() and()}</code>
|
||||
* to only append the {@code map} entries. This method will be removed before the 1.0 release.
|
||||
*/
|
||||
@SuppressWarnings("DeprecatedIsStillUsed")
|
||||
@Deprecated
|
||||
JwtBuilder setHeader(Map<String, ?> map);
|
||||
|
||||
/**
|
||||
* Applies the specified name/value pairs to the header. If a header does not yet exist at the time this method
|
||||
* is called, one will be created automatically before applying the name/value pairs.
|
||||
* Adds the specified name/value pairs to the header. Any parameter with an empty or null value will remove the
|
||||
* entry from the header. This is a wrapper method for:
|
||||
* <blockquote><pre>
|
||||
* {@link #header()}.{@link MapMutator#add(Map) add(map)}.{@link BuilderHeader#and() and()}</pre></blockquote>
|
||||
*
|
||||
* @param params the header name/value pairs to append to the header.
|
||||
* @return the builder for method chaining.
|
||||
* @deprecated since JJWT_RELEASE_VERSION in favor of
|
||||
* <code>{@link #header()}.{@link MapMutator#add(Map) add(map)}.{@link BuilderHeader#and() and()}</code>.
|
||||
* This method will be removed before the 1.0 release.
|
||||
*/
|
||||
@SuppressWarnings("DeprecatedIsStillUsed")
|
||||
@Deprecated
|
||||
JwtBuilder setHeaderParams(Map<String, ?> params);
|
||||
|
||||
/**
|
||||
* Applies the specified name/value pair to the header. If a header does not yet exist at the time this method
|
||||
* is called, one will be created automatically before applying the name/value pair.
|
||||
* Adds the specified name/value pair to the header. If the value is {@code null} or empty, the parameter will
|
||||
* be removed from the header entirely. This is a wrapper method for:
|
||||
* <blockquote><pre>
|
||||
* {@link #header()}.{@link MapMutator#add(Object, Object) add(name, value)}.{@link BuilderHeader#and() and()}</pre></blockquote>
|
||||
*
|
||||
* @param name the header parameter name
|
||||
* @param value the header parameter value
|
||||
* @return the builder for method chaining.
|
||||
* @deprecated since JJWT_RELEASE_VERSION in favor of <code>
|
||||
* {@link #header()}.{@link MapMutator#add(Object, Object) add(name, value)}.{@link BuilderHeader#and() and()}</code>.
|
||||
* This method will be removed before the 1.0 release.
|
||||
*/
|
||||
@SuppressWarnings("DeprecatedIsStillUsed")
|
||||
@Deprecated
|
||||
JwtBuilder setHeaderParam(String name, Object value);
|
||||
|
||||
/**
|
||||
* Sets the JWT payload to the string's UTF-8-encoded bytes. It is strongly recommended to also set the
|
||||
* {@link Header#setContentType(String) contentType} header value so the JWT recipient may inspect that value to
|
||||
* {@link BuilderHeader#contentType(String) contentType} header value so the JWT recipient may inspect that value to
|
||||
* determine how to convert the byte array to the final data type as desired. In this case, consider using
|
||||
* {@link #setContent(byte[], String)} instead.
|
||||
* {@link #content(byte[], String)} instead.
|
||||
*
|
||||
* <p>This is a convenience method that is effectively the same as:</p>
|
||||
* <p>This is a wrapper method for:</p>
|
||||
* <blockquote><pre>
|
||||
* {@link #setContent(byte[]) setPayload}(payload.getBytes(StandardCharsets.UTF_8));</pre></blockquote>
|
||||
* {@link #content(byte[]) setPayload}(payload.getBytes(StandardCharsets.UTF_8));</pre></blockquote>
|
||||
*
|
||||
* <p>If you want the JWT payload to be JSON, use the
|
||||
* {@link #setClaims(Claims)} or {@link #setClaims(java.util.Map)} methods instead.</p>
|
||||
* <p>If you want the JWT payload to be JSON, use the {@link #claims()} method instead.</p>
|
||||
*
|
||||
* <p>The payload and claims properties are mutually exclusive - only one of the two may be used.</p>
|
||||
* <p>This method is mutually exclusive of the {@link #claims()} and {@link #claim(String, Object)}
|
||||
* methods. Either {@code claims} or {@code content}/{@code payload} method variants may be used, but not both.</p>
|
||||
*
|
||||
* @param payload the string used to set UTF-8-encoded bytes as the JWT payload.
|
||||
* @return the builder for method chaining.
|
||||
* @see #setContent(byte[])
|
||||
* @see #setContent(byte[], String)
|
||||
* @deprecated since JJWT_RELEASE VERSION in favor of {@link #setContent(byte[])} or {@link #setContent(byte[], String)}
|
||||
* @see #content(byte[])
|
||||
* @see #content(byte[], String)
|
||||
* @deprecated since JJWT_RELEASE VERSION in favor of {@link #content(byte[])} or {@link #content(byte[], String)}
|
||||
* because both Claims and Content are technically 'payloads', so this method name is misleading. This method will
|
||||
* be removed before the 1.0 release.
|
||||
*/
|
||||
@SuppressWarnings("DeprecatedIsStillUsed")
|
||||
@Deprecated
|
||||
JwtBuilder setPayload(String payload);
|
||||
|
||||
/**
|
||||
* Sets the JWT payload to be the specified content byte array.
|
||||
*
|
||||
* <p>This method is mutually exclusive of the {@link #claims()} and {@link #claim(String, Object)}
|
||||
* methods. Either {@code claims} or {@code content} method variants may be used, but not both.</p>
|
||||
*
|
||||
* <p><b>Content Type Recommendation</b></p>
|
||||
*
|
||||
* <p>Unless you are confident that the JWT recipient will <em>always</em> know how to use
|
||||
* the given byte array without additional metadata, it is strongly recommended to use the
|
||||
* {@link #setContent(byte[], String)} method instead of this one. That method ensures that a JWT recipient
|
||||
* {@link #content(byte[], String)} method instead of this one. That method ensures that a JWT recipient
|
||||
* can inspect the {@code cty} header to know how to handle the byte array without ambiguity.</p>
|
||||
*
|
||||
* <p>Note that the content and claims properties are mutually exclusive - only one of the two may be used.</p>
|
||||
|
@ -163,14 +194,17 @@ public interface JwtBuilder extends ClaimsMutator<JwtBuilder> {
|
|||
* @return the builder for method chaining.
|
||||
* @since JJWT_RELEASE_VERSION
|
||||
*/
|
||||
JwtBuilder setContent(byte[] content);
|
||||
JwtBuilder content(byte[] content);
|
||||
|
||||
/**
|
||||
* Convenience method that sets the JWT payload to be the specified content byte array and also sets the
|
||||
* {@link Header#setContentType(String) contentType} header value to a compact {@code cty} media type
|
||||
* {@link BuilderHeader#contentType(String) contentType} header value to a compact {@code cty} media type
|
||||
* identifier to indicate the data format of the byte array. The JWT recipient can inspect the
|
||||
* {@code cty} value to determine how to convert the byte array to the final content type as desired.
|
||||
*
|
||||
* <p>This method is mutually exclusive of the {@link #claim(String, Object)} and {@link #claims()}
|
||||
* methods. Either {@code claims} or {@code content} method variants may be used, but not both.</p>
|
||||
*
|
||||
* <p><b>Compact Media Type Identifier</b></p>
|
||||
*
|
||||
* <p>As a convenience, this method will automatically trim any <code><b>application/</b></code> prefix from the
|
||||
|
@ -178,18 +212,18 @@ public interface JwtBuilder extends ClaimsMutator<JwtBuilder> {
|
|||
* <a href="https://www.rfc-editor.org/rfc/rfc7515.html#section-4.1.10">JWT specification recommendations</a>.</p>
|
||||
*
|
||||
* <p>If for some reason you do not wish to adhere to the JWT specification recommendation, do not call this
|
||||
* method - instead call {@link #setContent(byte[])} and set the header's
|
||||
* {@link Header#setContentType(String) contentType} independently. For example:</p>
|
||||
* method - instead call {@link #content(byte[])} and set the header's
|
||||
* {@link BuilderHeader#contentType(String) contentType} independently. For example:</p>
|
||||
*
|
||||
* <blockquote><pre>
|
||||
* Jwts.builder()
|
||||
* .header().setContentType("application/whatever").and()
|
||||
* .setContent(byteArray)
|
||||
* .header().contentType("application/whatever").and()
|
||||
* .content(byteArray)
|
||||
* ...
|
||||
* .build();</pre></blockquote>
|
||||
*
|
||||
* <p>If you want the JWT payload to be JSON claims, use the {@link #setClaims(Claims)} or
|
||||
* {@link #setClaims(java.util.Map)} methods instead.</p>
|
||||
* <p>If you want the JWT payload to be JSON claims, use the {@link #claim(String, Object)} or
|
||||
* {@link #claims()} methods instead.</p>
|
||||
*
|
||||
* <p>Note that the content and claims properties are mutually exclusive - only one of the two may be used.</p>
|
||||
*
|
||||
|
@ -199,258 +233,75 @@ public interface JwtBuilder extends ClaimsMutator<JwtBuilder> {
|
|||
* @throws IllegalArgumentException if either {@code payload} or {@code cty} are null or empty.
|
||||
* @since JJWT_RELEASE_VERSION
|
||||
*/
|
||||
JwtBuilder setContent(byte[] content, String cty) throws IllegalArgumentException;
|
||||
JwtBuilder content(byte[] content, String cty) throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Sets the JWT payload to be a JSON Claims instance. If you do not want the JWT payload to be JSON claims and
|
||||
* instead want it to be a byte array representing any type of content, use the {@link #setContent(byte[])}
|
||||
* method instead.
|
||||
* Returns the JWT {@code Claims} payload to modify as desired. When finished, callers may
|
||||
* return to {@code JwtBuilder} configuration via the {@link BuilderClaims#and() and()} method.
|
||||
* For example:
|
||||
*
|
||||
* <p>The payload and claims properties are mutually exclusive - only one of the two may be used.</p>
|
||||
* <blockquote><pre>
|
||||
* String jwt = Jwts.builder()
|
||||
*
|
||||
* @param claims the JWT claims to be set as the JWT payload.
|
||||
* @return the builder for method chaining.
|
||||
* <b>.claims()
|
||||
* .subject("Joe")
|
||||
* .audience("you")
|
||||
* .issuer("me")
|
||||
* .add("customClaim", customValue)
|
||||
* .add(myClaimsMap)
|
||||
* // ... etc ...
|
||||
* .{@link BuilderClaims#and() and()}</b> //return back to the JwtBuilder
|
||||
*
|
||||
* .signWith(key) // resume JwtBuilder calls
|
||||
* // ... etc ...
|
||||
* .compact();</pre></blockquote>
|
||||
*
|
||||
* @return the {@link BuilderClaims} to use for Claims construction.
|
||||
* @since JJWT_RELEASE_VERSION
|
||||
*/
|
||||
JwtBuilder setClaims(Claims claims);
|
||||
BuilderClaims claims();
|
||||
|
||||
/**
|
||||
* Sets the JWT payload to be a JSON Claims instance populated by the specified name/value pairs. If you do not
|
||||
* want the JWT payload to be JSON claims and instead want it to be a byte array for any content, use the
|
||||
* {@link #setContent(byte[])} or {@link #setContent(byte[], String)} methods instead.
|
||||
* Sets (and replaces) the JWT Claims payload with the specified name/value pairs. If you do not want the JWT
|
||||
* payload to be JSON claims and instead want it to be a byte array for any content, use the
|
||||
* {@link #content(byte[])} or {@link #content(byte[], String)} methods instead.
|
||||
*
|
||||
* <p>The payload and claims properties are mutually exclusive - only one of the two may be used.</p>
|
||||
* <p>The content and claims properties are mutually exclusive - only one of the two may be used.</p>
|
||||
*
|
||||
* @param claims the JWT Claims to be set as the JWT payload.
|
||||
* @return the builder for method chaining.
|
||||
* @deprecated since JJWT_RELEASE_VERSION in favor of the more modern builder-style {@link #claims()} method.
|
||||
*/
|
||||
@SuppressWarnings("DeprecatedIsStillUsed")
|
||||
@Deprecated
|
||||
JwtBuilder setClaims(Map<String, ?> claims);
|
||||
|
||||
/**
|
||||
* Adds all given name/value pairs to the JSON Claims in the payload. If a Claims instance does not yet exist at the
|
||||
* time this method is called, one will be created automatically before applying the name/value pairs.
|
||||
* Adds/appends all given name/value pairs to the JSON Claims in the payload.
|
||||
* <p>
|
||||
* This is a convenience wrapper for:
|
||||
*
|
||||
* <p>The payload and claims properties are mutually exclusive - only one of the two may be used.</p>
|
||||
* <blockquote><pre>
|
||||
* {@link #claims()}.{@link MapMutator#add(Map) add(claims)}.{@link BuilderClaims#and() and()}</pre></blockquote>
|
||||
*
|
||||
* <p>The content and claims properties are mutually exclusive - only one of the two may be used.</p>
|
||||
*
|
||||
* @param claims the JWT Claims to be added to the JWT payload.
|
||||
* @return the builder for method chaining.
|
||||
* @since 0.8
|
||||
* @deprecated since JJWT_RELEASE_VERSION in favor of
|
||||
* <code>{@link #claims()}.{@link BuilderClaims#add(Map) add(Map)}.{@link BuilderClaims#and() and()}</code>.
|
||||
* This method will be removed before the 1.0 release.
|
||||
*/
|
||||
@SuppressWarnings("DeprecatedIsStillUsed")
|
||||
@Deprecated
|
||||
JwtBuilder addClaims(Map<String, ?> claims);
|
||||
|
||||
/**
|
||||
* Sets the JWT Claims <a href="https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-25#section-4.1.1">
|
||||
* <code>iss</code></a> (issuer) value. A {@code null} value will remove the property from the Claims.
|
||||
*
|
||||
* <p>This is a convenience method. It will first ensure a Claims instance exists as the JWT payload and then set
|
||||
* the Claims {@link Claims#getIssuer() issuer} field with the specified value. This allows you to write
|
||||
* code like this:</p>
|
||||
*
|
||||
* <pre>
|
||||
* String jwt = Jwts.builder().setIssuer("Joe").compact();
|
||||
* </pre>
|
||||
*
|
||||
* <p>instead of this:</p>
|
||||
* <pre>
|
||||
* Claims claims = Jwts.claims().setIssuer("Joe").build();
|
||||
* String jwt = Jwts.builder().setClaims(claims).compact();
|
||||
* </pre>
|
||||
* <p>if desired.</p>
|
||||
*
|
||||
* @param iss the JWT {@code iss} value or {@code null} to remove the property from the Claims map.
|
||||
* @return the builder instance for method chaining.
|
||||
* @since 0.2
|
||||
*/
|
||||
@Override
|
||||
//only for better/targeted JavaDoc
|
||||
JwtBuilder setIssuer(String iss);
|
||||
|
||||
/**
|
||||
* Sets the JWT Claims <a href="https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-25#section-4.1.2">
|
||||
* <code>sub</code></a> (subject) value. A {@code null} value will remove the property from the Claims.
|
||||
*
|
||||
* <p>This is a convenience method. It will first ensure a Claims instance exists as the JWT payload and then set
|
||||
* the Claims {@link Claims#getSubject() subject} field with the specified value. This allows you to write
|
||||
* code like this:</p>
|
||||
*
|
||||
* Sets a JWT claim, overwriting any existing claim with the same name. A {@code null} or empty
|
||||
* value will remove the claim entirely. This is a convenience wrapper for:
|
||||
* <blockquote><pre>
|
||||
* String jwt = Jwts.builder().setSubject("Me").compact();</pre></blockquote>
|
||||
*
|
||||
* <p>instead of this:</p>
|
||||
* <blockquote><pre>
|
||||
* Claims claims = Jwts.claims().setSubject("Me").build();
|
||||
* String jwt = Jwts.builder().setClaims(claims).compact();</pre></blockquote>
|
||||
* <p>if desired.</p>
|
||||
*
|
||||
* @param sub the JWT {@code sub} value or {@code null} to remove the property from the Claims map.
|
||||
* @return the builder instance for method chaining.
|
||||
* @since 0.2
|
||||
*/
|
||||
@Override
|
||||
//only for better/targeted JavaDoc
|
||||
JwtBuilder setSubject(String sub);
|
||||
|
||||
/**
|
||||
* Sets the JWT Claims <a href="https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-25#section-4.1.3">
|
||||
* <code>aud</code></a> (audience) value. A {@code null} value will remove the property from the Claims.
|
||||
*
|
||||
* <p>This is a convenience method. It will first ensure a Claims instance exists as the JWT payload and then set
|
||||
* the Claims {@link Claims#getAudience() audience} field with the specified value. This allows you to write
|
||||
* code like this:</p>
|
||||
*
|
||||
* <pre>
|
||||
* String jwt = Jwts.builder().setAudience("You").compact();
|
||||
* </pre>
|
||||
*
|
||||
* <p>instead of this:</p>
|
||||
* <pre>
|
||||
* Claims claims = Jwts.claims().setAudience("You");
|
||||
* String jwt = Jwts.builder().setClaims(claims).compact();
|
||||
* </pre>
|
||||
* <p>if desired.</p>
|
||||
*
|
||||
* @param aud the JWT {@code aud} value or {@code null} to remove the property from the Claims map.
|
||||
* @return the builder instance for method chaining.
|
||||
* @since 0.2
|
||||
*/
|
||||
@Override
|
||||
//only for better/targeted JavaDoc
|
||||
JwtBuilder setAudience(String aud);
|
||||
|
||||
/**
|
||||
* Sets the JWT Claims <a href="https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-25#section-4.1.4">
|
||||
* <code>exp</code></a> (expiration) value. A {@code null} value will remove the property from the Claims.
|
||||
*
|
||||
* <p>A JWT obtained after this timestamp should not be used.</p>
|
||||
*
|
||||
* <p>This is a convenience method. It will first ensure a Claims instance exists as the JWT payload and then set
|
||||
* the Claims {@link Claims#getExpiration() expiration} field with the specified value. This allows
|
||||
* you to write code like this:</p>
|
||||
*
|
||||
* <pre>
|
||||
* String jwt = Jwts.builder().setExpiration(new Date(System.currentTimeMillis() + 3600000)).compact();
|
||||
* </pre>
|
||||
*
|
||||
* <p>instead of this:</p>
|
||||
* <pre>
|
||||
* Claims claims = Jwts.claims().setExpiration(new Date(System.currentTimeMillis() + 3600000));
|
||||
* String jwt = Jwts.builder().setClaims(claims).compact();
|
||||
* </pre>
|
||||
* <p>if desired.</p>
|
||||
*
|
||||
* @param exp the JWT {@code exp} value or {@code null} to remove the property from the Claims map.
|
||||
* @return the builder instance for method chaining.
|
||||
* @since 0.2
|
||||
*/
|
||||
@Override
|
||||
//only for better/targeted JavaDoc
|
||||
JwtBuilder setExpiration(Date exp);
|
||||
|
||||
/**
|
||||
* Sets the JWT Claims <a href="https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-25#section-4.1.5">
|
||||
* <code>nbf</code></a> (not before) value. A {@code null} value will remove the property from the Claims.
|
||||
*
|
||||
* <p>A JWT obtained before this timestamp should not be used.</p>
|
||||
*
|
||||
* <p>This is a convenience method. It will first ensure a Claims instance exists as the JWT payload and then set
|
||||
* the Claims {@link Claims#getNotBefore() notBefore} field with the specified value. This allows
|
||||
* you to write code like this:</p>
|
||||
*
|
||||
* <pre>
|
||||
* String jwt = Jwts.builder().setNotBefore(new Date()).compact();
|
||||
* </pre>
|
||||
*
|
||||
* <p>instead of this:</p>
|
||||
* <pre>
|
||||
* Claims claims = Jwts.claims().setNotBefore(new Date());
|
||||
* String jwt = Jwts.builder().setClaims(claims).compact();
|
||||
* </pre>
|
||||
* <p>if desired.</p>
|
||||
*
|
||||
* @param nbf the JWT {@code nbf} value or {@code null} to remove the property from the Claims map.
|
||||
* @return the builder instance for method chaining.
|
||||
* @since 0.2
|
||||
*/
|
||||
@Override
|
||||
//only for better/targeted JavaDoc
|
||||
JwtBuilder setNotBefore(Date nbf);
|
||||
|
||||
/**
|
||||
* Sets the JWT Claims <a href="https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-25#section-4.1.6">
|
||||
* <code>iat</code></a> (issued at) value. A {@code null} value will remove the property from the Claims.
|
||||
*
|
||||
* <p>The value is the timestamp when the JWT was created.</p>
|
||||
*
|
||||
* <p>This is a convenience method. It will first ensure a Claims instance exists as the JWT payload and then set
|
||||
* the Claims {@link Claims#getIssuedAt() issuedAt} field with the specified value. This allows
|
||||
* you to write code like this:</p>
|
||||
*
|
||||
* <pre>
|
||||
* String jwt = Jwts.builder().setIssuedAt(new Date()).compact();
|
||||
* </pre>
|
||||
*
|
||||
* <p>instead of this:</p>
|
||||
* <pre>
|
||||
* Claims claims = Jwts.claims().setIssuedAt(new Date());
|
||||
* String jwt = Jwts.builder().setClaims(claims).compact();
|
||||
* </pre>
|
||||
* <p>if desired.</p>
|
||||
*
|
||||
* @param iat the JWT {@code iat} value or {@code null} to remove the property from the Claims map.
|
||||
* @return the builder instance for method chaining.
|
||||
* @since 0.2
|
||||
*/
|
||||
@Override
|
||||
//only for better/targeted JavaDoc
|
||||
JwtBuilder setIssuedAt(Date iat);
|
||||
|
||||
/**
|
||||
* Sets the JWT Claims <a href="https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-25#section-4.1.7">
|
||||
* <code>jti</code></a> (JWT ID) value. A {@code null} value will remove the property from the Claims.
|
||||
*
|
||||
* <p>The value is a CaSe-SenSiTiVe unique identifier for the JWT. If specified, this value MUST be assigned in a
|
||||
* manner that ensures that there is a negligible probability that the same value will be accidentally
|
||||
* assigned to a different data object. The ID can be used to prevent the JWT from being replayed.</p>
|
||||
*
|
||||
* <p>This is a convenience method. It will first ensure a Claims instance exists as the JWT payload and then set
|
||||
* the Claims {@link Claims#getId() id} field with the specified value. This allows
|
||||
* you to write code like this:</p>
|
||||
*
|
||||
* <pre>
|
||||
* String jwt = Jwts.builder().setId(UUID.randomUUID().toString()).compact();
|
||||
* </pre>
|
||||
*
|
||||
* <p>instead of this:</p>
|
||||
* <pre>
|
||||
* Claims claims = Jwts.claims().setId(UUID.randomUUID().toString());
|
||||
* String jwt = Jwts.builder().setClaims(claims).compact();
|
||||
* </pre>
|
||||
* <p>if desired.</p>
|
||||
*
|
||||
* @param jti the JWT {@code jti} (id) value or {@code null} to remove the property from the Claims map.
|
||||
* @return the builder instance for method chaining.
|
||||
* @since 0.2
|
||||
*/
|
||||
@Override
|
||||
//only for better/targeted JavaDoc
|
||||
JwtBuilder setId(String jti);
|
||||
|
||||
/**
|
||||
* Sets a custom JWT Claims parameter value. A {@code null} value will remove the property from the Claims.
|
||||
*
|
||||
* <p>This is a convenience method. It will first ensure a Claims instance exists as the JWT payload and then set the
|
||||
* named property on the Claims instance using the Claims {@link Claims#put(Object, Object) put} method. This allows
|
||||
* you to write code like this:</p>
|
||||
*
|
||||
* <pre>
|
||||
* String jwt = Jwts.builder().claim("aName", "aValue").compact();
|
||||
* </pre>
|
||||
*
|
||||
* <p>instead of this:</p>
|
||||
* <pre>
|
||||
* Claims claims = Jwts.claims().put("aName", "aValue");
|
||||
* String jwt = Jwts.builder().setClaims(claims).compact();
|
||||
* </pre>
|
||||
* <p>if desired.</p>
|
||||
* {@link #claims()}.{@link MapMutator#add(Object, Object) add(name, value)}.{@link BuilderClaims#and() and()}</pre></blockquote>
|
||||
*
|
||||
* @param name the JWT Claims property name
|
||||
* @param value the value to set for the specified Claims property name
|
||||
|
@ -459,6 +310,133 @@ public interface JwtBuilder extends ClaimsMutator<JwtBuilder> {
|
|||
*/
|
||||
JwtBuilder claim(String name, Object value);
|
||||
|
||||
/**
|
||||
* Adds all given name/value pairs to the JSON Claims in the payload, overwriting any existing claims
|
||||
* with the same names. If any name has a {@code null} or empty value, that claim will be removed from the
|
||||
* Claims. This is a convenience wrapper for:
|
||||
* <blockquote><pre>
|
||||
* {@link #claims()}.{@link MapMutator#add(Map) add(claims)}.{@link BuilderClaims#and() and()}</pre></blockquote>
|
||||
*
|
||||
* <p>The content and claims properties are mutually exclusive - only one of the two may be used.</p>
|
||||
*
|
||||
* @param claims the JWT Claims to be added to the JWT payload.
|
||||
* @return the builder instance for method chaining
|
||||
* @since JJWT_RELEASE_VERSION
|
||||
*/
|
||||
JwtBuilder claims(Map<String, ?> claims);
|
||||
|
||||
/**
|
||||
* Sets the JWT Claims <a href="https://www.rfc-editor.org/rfc/rfc7519.html#section-4.1.1">
|
||||
* <code>iss</code></a> (issuer) value. A {@code null} value will remove the property from the Claims.
|
||||
* This is a convenience wrapper for:
|
||||
* <blockquote><pre>
|
||||
* {@link #claims()}.{@link ClaimsMutator#issuer(String) issuer(iss)}.{@link BuilderClaims#and() and()}</pre></blockquote>
|
||||
*
|
||||
* @param iss the JWT {@code iss} value or {@code null} to remove the property from the Claims map.
|
||||
* @return the builder instance for method chaining.
|
||||
*/
|
||||
@Override
|
||||
// for better/targeted JavaDoc
|
||||
JwtBuilder issuer(String iss);
|
||||
|
||||
/**
|
||||
* Sets the JWT Claims <a href="https://www.rfc-editor.org/rfc/rfc7519.html#section-4.1.2">
|
||||
* <code>sub</code></a> (subject) value. A {@code null} value will remove the property from the Claims.
|
||||
* This is a convenience wrapper for:
|
||||
* <blockquote><pre>
|
||||
* {@link #claims()}.{@link ClaimsMutator#subject(String) subject(sub)}.{@link BuilderClaims#and() and()}</pre></blockquote>
|
||||
*
|
||||
* @param sub the JWT {@code sub} value or {@code null} to remove the property from the Claims map.
|
||||
* @return the builder instance for method chaining.
|
||||
*/
|
||||
@Override
|
||||
// for better/targeted JavaDoc
|
||||
JwtBuilder subject(String sub);
|
||||
|
||||
/**
|
||||
* Sets the JWT Claims <a href="https://www.rfc-editor.org/rfc/rfc7519.html#section-4.1.3">
|
||||
* <code>aud</code></a> (audience) value. A {@code null} value will remove the property from the Claims.
|
||||
* This is a convenience wrapper for:
|
||||
* <blockquote><pre>
|
||||
* {@link #claims()}.{@link ClaimsMutator#audience(String) audience(aud)}.{@link BuilderClaims#and() and()}</pre></blockquote>
|
||||
*
|
||||
* @param aud the JWT {@code aud} value or {@code null} to remove the property from the Claims map.
|
||||
* @return the builder instance for method chaining.
|
||||
*/
|
||||
@Override
|
||||
// for better/targeted JavaDoc
|
||||
JwtBuilder audience(String aud);
|
||||
|
||||
/**
|
||||
* Sets the JWT Claims <a href="https://www.rfc-editor.org/rfc/rfc7519.html#section-4.1.4">
|
||||
* <code>exp</code></a> (expiration) value. A {@code null} value will remove the property from the Claims.
|
||||
*
|
||||
* <p>A JWT obtained after this timestamp should not be used.</p>
|
||||
*
|
||||
* <p>This is a convenience wrapper for:</p>
|
||||
* <blockquote><pre>
|
||||
* {@link #claims()}.{@link ClaimsMutator#expiration(Date) expiration(exp)}.{@link BuilderClaims#and() and()}</pre></blockquote>
|
||||
*
|
||||
* @param exp the JWT {@code exp} value or {@code null} to remove the property from the Claims map.
|
||||
* @return the builder instance for method chaining.
|
||||
*/
|
||||
@Override
|
||||
// for better/targeted JavaDoc
|
||||
JwtBuilder expiration(Date exp);
|
||||
|
||||
/**
|
||||
* Sets the JWT Claims <a href="https://www.rfc-editor.org/rfc/rfc7519.html#section-4.1.5">
|
||||
* <code>nbf</code></a> (not before) value. A {@code null} value will remove the property from the Claims.
|
||||
*
|
||||
* <p>A JWT obtained before this timestamp should not be used.</p>
|
||||
*
|
||||
* <p>This is a convenience wrapper for:</p>
|
||||
* <blockquote><pre>
|
||||
* {@link #claims()}.{@link ClaimsMutator#notBefore(Date) notBefore(nbf)}.{@link BuilderClaims#and() and()}</pre></blockquote>
|
||||
*
|
||||
* @param nbf the JWT {@code nbf} value or {@code null} to remove the property from the Claims map.
|
||||
* @return the builder instance for method chaining.
|
||||
*/
|
||||
@Override
|
||||
// for better/targeted JavaDoc
|
||||
JwtBuilder setNotBefore(Date nbf);
|
||||
|
||||
/**
|
||||
* Sets the JWT Claims <a href="https://www.rfc-editor.org/rfc/rfc7519.html#section-4.1.6">
|
||||
* <code>iat</code></a> (issued at) value. A {@code null} value will remove the property from the Claims.
|
||||
*
|
||||
* <p>The value is the timestamp when the JWT was created.</p>
|
||||
*
|
||||
* <p>This is a convenience wrapper for:</p>
|
||||
* <blockquote><pre>
|
||||
* {@link #claims()}.{@link ClaimsMutator#issuedAt(Date) issuedAt(iat)}.{@link BuilderClaims#and() and()}</pre></blockquote>
|
||||
*
|
||||
* @param iat the JWT {@code iat} value or {@code null} to remove the property from the Claims map.
|
||||
* @return the builder instance for method chaining.
|
||||
*/
|
||||
@Override
|
||||
// for better/targeted JavaDoc
|
||||
JwtBuilder issuedAt(Date iat);
|
||||
|
||||
/**
|
||||
* Sets the JWT Claims <a href="https://www.rfc-editor.org/rfc/rfc7519.html#section-4.1.7">
|
||||
* <code>jti</code></a> (JWT ID) value. A {@code null} value will remove the property from the Claims.
|
||||
*
|
||||
* <p>The value is a CaSe-SenSiTiVe unique identifier for the JWT. If specified, this value MUST be assigned in a
|
||||
* manner that ensures that there is a negligible probability that the same value will be accidentally
|
||||
* assigned to a different data object. The ID can be used to prevent the JWT from being replayed.</p>
|
||||
*
|
||||
* <p>This is a convenience wrapper for:</p>
|
||||
* <blockquote><pre>
|
||||
* {@link #claims()}.{@link ClaimsMutator#id(String) id(jti)}.{@link BuilderClaims#and() and()}</pre></blockquote>
|
||||
*
|
||||
* @param jti the JWT {@code jti} (id) value or {@code null} to remove the property from the Claims map.
|
||||
* @return the builder instance for method chaining.
|
||||
*/
|
||||
@Override
|
||||
// for better/targeted JavaDoc
|
||||
JwtBuilder id(String jti);
|
||||
|
||||
/**
|
||||
* Signs the constructed JWT with the specified key using the key's <em>recommended signature algorithm</em>
|
||||
* as defined below, producing a JWS. If the recommended signature algorithm isn't sufficient for your needs,
|
||||
|
@ -760,7 +738,7 @@ public interface JwtBuilder extends ClaimsMutator<JwtBuilder> {
|
|||
* {@code enc} algorithm. In this case, the {@code key} argument <em>MUST</em> be of sufficient strength to
|
||||
* use with the specified {@code enc} algorithm, otherwise an exception will be thrown during encryption. If
|
||||
* desired, secure-random keys suitable for an {@link AeadAlgorithm} may be generated using the algorithm's
|
||||
* {@link AeadAlgorithm#keyBuilder() keyBuilder}.</li>
|
||||
* {@link AeadAlgorithm#key() key()} builder.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param key the symmetric encryption key to use with the {@code enc} algorithm.
|
||||
|
@ -828,19 +806,35 @@ public interface JwtBuilder extends ClaimsMutator<JwtBuilder> {
|
|||
JwtBuilder compressWith(CompressionAlgorithm alg);
|
||||
|
||||
/**
|
||||
* Perform Base64Url encoding with the specified Encoder.
|
||||
* Perform Base64Url encoding during {@link #compact() compaction} with the specified Encoder.
|
||||
*
|
||||
* <p>JJWT uses a spec-compliant encoder that works on all supported JDK versions, but you may call this method
|
||||
* to specify a different encoder if you desire.</p>
|
||||
*
|
||||
* @param base64UrlEncoder the encoder to use when Base64Url-encoding
|
||||
* @return the builder for method chaining.
|
||||
* @see #encoder(Encoder)
|
||||
* @since 0.10.0
|
||||
* @deprecated since JJWT_RELEASE_VERSION in favor of the more modern builder-style
|
||||
* {@link #encoder(Encoder)} method.
|
||||
*/
|
||||
@Deprecated
|
||||
JwtBuilder base64UrlEncodeWith(Encoder<byte[], String> base64UrlEncoder);
|
||||
|
||||
/**
|
||||
* Performs object-to-JSON serialization with the specified Serializer. This is used by the builder to convert
|
||||
* Perform Base64Url encoding during {@link #compact() compaction} with the specified Encoder.
|
||||
*
|
||||
* <p>JJWT uses a spec-compliant encoder that works on all supported JDK versions, but you may call this method
|
||||
* to specify a different encoder if necessar.</p>
|
||||
*
|
||||
* @param encoder the encoder to use when Base64Url-encoding
|
||||
* @return the builder for method chaining.
|
||||
* @since JJWT_RELEASE_VERSION
|
||||
*/
|
||||
JwtBuilder encoder(Encoder<byte[], String> encoder);
|
||||
|
||||
/**
|
||||
* Performs Map-to-JSON serialization with the specified Serializer. This is used by the builder to convert
|
||||
* JWT/JWS/JWE headers and claims Maps to JSON strings as required by the JWT specification.
|
||||
*
|
||||
* <p>If this method is not called, JJWT will use whatever serializer it can find at runtime, checking for the
|
||||
|
@ -850,12 +844,29 @@ public interface JwtBuilder extends ClaimsMutator<JwtBuilder> {
|
|||
* @param serializer the serializer to use when converting Map objects to JSON strings.
|
||||
* @return the builder for method chaining.
|
||||
* @since 0.10.0
|
||||
* @deprecated since JJWT_RELEASE_VERSION in favor of the more modern builder-style
|
||||
* {@link #serializer(Serializer)} method.
|
||||
*/
|
||||
@Deprecated
|
||||
JwtBuilder serializeToJsonWith(Serializer<Map<String, ?>> serializer);
|
||||
|
||||
/**
|
||||
* Perform Map-to-JSON serialization with the specified Serializer. This is used by the builder to convert
|
||||
* JWT/JWS/JWE headers and Claims Maps to JSON strings as required by the JWT specification.
|
||||
*
|
||||
* <p>If this method is not called, JJWT will use whatever serializer it can find at runtime, checking for the
|
||||
* presence of well-known implementations such Jackson, Gson, and org.json. If one of these is not found
|
||||
* in the runtime classpath, an exception will be thrown when the {@link #compact()} method is invoked.</p>
|
||||
*
|
||||
* @param serializer the serializer to use when converting Map objects to JSON strings.
|
||||
* @return the builder for method chaining.
|
||||
* @since JJWT_RELEASE_VERSION
|
||||
*/
|
||||
JwtBuilder serializer(Serializer<Map<String, ?>> serializer);
|
||||
|
||||
/**
|
||||
* Actually builds the JWT and serializes it to a compact, URL-safe string according to the
|
||||
* <a href="https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-25#section-7">JWT Compact Serialization</a>
|
||||
* <a href="https://www.rfc-editor.org/rfc/rfc7519.html#section-7.1">JWT Compact Serialization</a>
|
||||
* rules.
|
||||
*
|
||||
* @return A compact URL-safe JWT string.
|
||||
|
@ -863,13 +874,30 @@ public interface JwtBuilder extends ClaimsMutator<JwtBuilder> {
|
|||
String compact();
|
||||
|
||||
/**
|
||||
* Editable header for use with a {@link JwtBuilder} that supports method chaining for any/all
|
||||
* Claims for use with a {@link JwtBuilder} that supports method chaining for standard JWT Claims parameters.
|
||||
* Once claims are configured, the associated {@link JwtBuilder} may be obtained with the {@link #and() and()}
|
||||
* method for continued configuration.
|
||||
*
|
||||
* @since JJWT_RELEASE_VERSION
|
||||
*/
|
||||
interface BuilderClaims extends MapMutator<String, Object, BuilderClaims>, ClaimsMutator<BuilderClaims> {
|
||||
|
||||
/**
|
||||
* Returns the associated JwtBuilder for continued configuration.
|
||||
*
|
||||
* @return the associated JwtBuilder for continued configuration.
|
||||
*/
|
||||
JwtBuilder and();
|
||||
}
|
||||
|
||||
/**
|
||||
* Header for use with a {@link JwtBuilder} that supports method chaining for
|
||||
* standard JWT, JWS and JWE header parameters. Once header parameters are configured, the associated
|
||||
* {@link JwtBuilder} may be obtained with the {@link #and() and()} method for continued configuration.
|
||||
*
|
||||
* @since JJWT_RELEASE_VERSION
|
||||
*/
|
||||
interface Header extends JweHeaderMutator<Header>, X509Builder<Header> {
|
||||
interface BuilderHeader extends JweHeaderMutator<BuilderHeader>, X509Builder<BuilderHeader> {
|
||||
|
||||
/**
|
||||
* Returns the associated JwtBuilder for continued configuration.
|
||||
|
|
|
@ -23,8 +23,11 @@ import io.jsonwebtoken.security.AeadAlgorithm;
|
|||
import io.jsonwebtoken.security.KeyAlgorithm;
|
||||
import io.jsonwebtoken.security.SecureDigestAlgorithm;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
import java.security.Key;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.Provider;
|
||||
import java.security.PublicKey;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
@ -45,11 +48,11 @@ import java.util.Map;
|
|||
public interface JwtParserBuilder extends Builder<JwtParser> {
|
||||
|
||||
/**
|
||||
* Enables parsing of Unsecured JWSs (JWTs with an 'alg' (Algorithm) header value of
|
||||
* 'none'). <b>Be careful when calling this method - one should fully understand
|
||||
* Enables parsing of Unsecured JWTs (JWTs with an 'alg' (Algorithm) header value of
|
||||
* 'none' or missing the 'alg' header entirely). <b>Be careful when calling this method - one should fully understand
|
||||
* <a href="https://www.rfc-editor.org/rfc/rfc7518.html#section-8.5">Unsecured JWS Security Considerations</a>
|
||||
* before enabling this feature.</b>
|
||||
* <p>If this method is not called, Unsecured JWSs are disabled by default as mandated by
|
||||
* <p>If this method is not called, Unsecured JWTs are disabled by default as mandated by
|
||||
* <a href="https://www.rfc-editor.org/rfc/rfc7518.html#section-3.6">RFC 7518, Section
|
||||
* 3.6</a>.</p>
|
||||
*
|
||||
|
@ -60,23 +63,23 @@ public interface JwtParserBuilder extends Builder<JwtParser> {
|
|||
* @see #enableUnsecuredDecompression()
|
||||
* @since JJWT_RELEASE_VERSION
|
||||
*/
|
||||
JwtParserBuilder enableUnsecuredJws();
|
||||
JwtParserBuilder enableUnsecured();
|
||||
|
||||
/**
|
||||
* If {@link #enableUnsecuredJws() enabledUnsecuredJws} is enabled, calling this method additionally enables
|
||||
* payload decompression of Unsecured JWSs (JWTs with an 'alg' (Algorithm) header value of 'none') that also have
|
||||
* If {@link #enableUnsecured() enabledUnsecuredJws} is enabled, calling this method additionally enables
|
||||
* payload decompression of Unsecured JWTs (JWTs with an 'alg' (Algorithm) header value of 'none') that also have
|
||||
* a 'zip' (Compression) header. This behavior is disabled by default because using compression
|
||||
* algorithms with data from unverified (unauthenticated) parties can be susceptible to Denial of Service attacks
|
||||
* and other data integrity problems as described in
|
||||
* <a href="https://www.usenix.org/system/files/conference/usenixsecurity15/sec15-paper-pellegrino.pdf">In the
|
||||
* Compression Hornet’s Nest: A Security Study of Data Compression in Network Services</a>.
|
||||
*
|
||||
* <p>Because this behavior is only relevant if {@link #enableUnsecuredJws() enabledUnsecuredJws} is specified,
|
||||
* calling this method without also calling {@code enableUnsecuredJws()} will result in a build exception, as the
|
||||
* <p>Because this behavior is only relevant if {@link #enableUnsecured() enabledUnsecured} is specified,
|
||||
* calling this method without also calling {@code enableUnsecured()} will result in a build exception, as the
|
||||
* incongruent state could reflect a misunderstanding of both behaviors which should be remedied by the
|
||||
* application developer.</p>
|
||||
*
|
||||
* <b>As is the case for {@link #enableUnsecuredJws()}, be careful when calling this method - one should fully
|
||||
* <b>As is the case for {@link #enableUnsecured()}, be careful when calling this method - one should fully
|
||||
* understand
|
||||
* <a href="https://www.rfc-editor.org/rfc/rfc7518.html#section-8.5">Unsecured JWS Security Considerations</a>
|
||||
* before enabling this feature.</b>
|
||||
|
@ -86,7 +89,7 @@ public interface JwtParserBuilder extends Builder<JwtParser> {
|
|||
* @see <a href="https://www.usenix.org/system/files/conference/usenixsecurity15/sec15-paper-pellegrino.pdf">In the
|
||||
* Compression Hornet’s Nest: A Security Study of Data Compression in Network Services</a>
|
||||
* @see Jwts.SIG#NONE
|
||||
* @see #enableUnsecuredJws()
|
||||
* @see #enableUnsecured()
|
||||
* @since JJWT_RELEASE_VERSION
|
||||
*/
|
||||
JwtParserBuilder enableUnsecuredDecompression();
|
||||
|
@ -100,7 +103,7 @@ public interface JwtParserBuilder extends Builder<JwtParser> {
|
|||
* @return the builder for method chaining.
|
||||
* @since JJWT_RELEASE_VERSION
|
||||
*/
|
||||
JwtParserBuilder setProvider(Provider provider);
|
||||
JwtParserBuilder provider(Provider provider);
|
||||
|
||||
/**
|
||||
* Ensures that the specified {@code jti} exists in the parsed JWT. If missing or if the parsed
|
||||
|
@ -205,9 +208,36 @@ public interface JwtParserBuilder extends Builder<JwtParser> {
|
|||
*
|
||||
* @param clock a {@code Clock} object to return the timestamp to use when validating the parsed JWT.
|
||||
* @return the parser builder for method chaining.
|
||||
* @deprecated since JJWT_RELEASE_VERSION for the more modern builder-style named {@link #clock(Clock)} method.
|
||||
* This method will be removed before the JJWT 1.0 release.
|
||||
*/
|
||||
@Deprecated
|
||||
JwtParserBuilder setClock(Clock clock);
|
||||
|
||||
/**
|
||||
* Sets the {@link Clock} that determines the timestamp to use when validating the parsed JWT.
|
||||
* The parser uses a default Clock implementation that simply returns {@code new Date()} when called.
|
||||
*
|
||||
* @param clock a {@code Clock} object to return the timestamp to use when validating the parsed JWT.
|
||||
* @return the parser builder for method chaining.
|
||||
*/
|
||||
JwtParserBuilder clock(Clock clock);
|
||||
|
||||
/**
|
||||
* Sets the amount of clock skew in seconds to tolerate when verifying the local time against the {@code exp}
|
||||
* and {@code nbf} claims.
|
||||
*
|
||||
* @param seconds the number of seconds to tolerate for clock skew when verifying {@code exp} or {@code nbf} claims.
|
||||
* @return the parser builder for method chaining.
|
||||
* @throws IllegalArgumentException if {@code seconds} is a value greater than {@code Long.MAX_VALUE / 1000} as
|
||||
* any such value would cause numeric overflow when multiplying by 1000 to obtain
|
||||
* a millisecond value.
|
||||
* @deprecated since JJWT_RELEASE_VERSION in favor of the shorter and more modern builder-style named
|
||||
* {@link #clockSkewSeconds(long)}. This method will be removed before the JJWT 1.0 release.
|
||||
*/
|
||||
@Deprecated
|
||||
JwtParserBuilder setAllowedClockSkewSeconds(long seconds) throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Sets the amount of clock skew in seconds to tolerate when verifying the local time against the {@code exp}
|
||||
* and {@code nbf} claims.
|
||||
|
@ -218,7 +248,7 @@ public interface JwtParserBuilder extends Builder<JwtParser> {
|
|||
* any such value would cause numeric overflow when multiplying by 1000 to obtain
|
||||
* a millisecond value.
|
||||
*/
|
||||
JwtParserBuilder setAllowedClockSkewSeconds(long seconds) throws IllegalArgumentException;
|
||||
JwtParserBuilder clockSkewSeconds(long seconds) throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* <p><b>Deprecation Notice</b></p>
|
||||
|
@ -226,7 +256,7 @@ public interface JwtParserBuilder extends Builder<JwtParser> {
|
|||
* <p>This method has been deprecated since JJWT_RELEASE_VERSION and will be removed before 1.0. It was not
|
||||
* readily obvious to many JJWT users that this method was for bytes that pertained <em>only</em> to HMAC
|
||||
* {@code SecretKey}s, and could be confused with keys of other types. It is better to obtain a type-safe
|
||||
* {@link Key} instance and call the {@link #verifyWith(Key)} instead.</p>
|
||||
* {@link SecretKey} instance and call {@link #verifyWith(SecretKey)} instead.</p>
|
||||
*
|
||||
* <p>Previous Documentation</p>
|
||||
*
|
||||
|
@ -241,8 +271,8 @@ public interface JwtParserBuilder extends Builder<JwtParser> {
|
|||
* @param key the algorithm-specific signature verification key used to validate any discovered JWS digital
|
||||
* signature.
|
||||
* @return the parser builder for method chaining.
|
||||
* @deprecated since JJWT_RELEASE_VERSION in favor of {@link #verifyWith(Key)} for type safety and name congruence
|
||||
* with the {@link #decryptWith(Key)} method.
|
||||
* @deprecated since JJWT_RELEASE_VERSION in favor of {@link #verifyWith(SecretKey)} for type safety and name
|
||||
* congruence with the {@link #decryptWith(SecretKey)} method.
|
||||
*/
|
||||
@Deprecated
|
||||
JwtParserBuilder setSigningKey(byte[] key);
|
||||
|
@ -268,7 +298,7 @@ public interface JwtParserBuilder extends Builder<JwtParser> {
|
|||
* StackOverflow answer</a> explaining why raw (non-base64-encoded) strings are almost always incorrect for
|
||||
* signature operations.</p>
|
||||
*
|
||||
* <p>Finally, please use the {@link #verifyWith(Key)} method instead, as this method (and likely
|
||||
* <p>Finally, please use the {@link #verifyWith(SecretKey)} method instead, as this method (and likely
|
||||
* {@link #setSigningKey(byte[])}) will be removed before the 1.0.0 release.</p>
|
||||
*
|
||||
* <p><b>Previous JavaDoc</b></p>
|
||||
|
@ -278,12 +308,12 @@ public interface JwtParserBuilder extends Builder<JwtParser> {
|
|||
* <blockquote><pre>
|
||||
* byte[] bytes = Decoders.{@link io.jsonwebtoken.io.Decoders#BASE64 BASE64}.decode(base64EncodedSecretKey);
|
||||
* Key key = Keys.{@link io.jsonwebtoken.security.Keys#hmacShaKeyFor(byte[]) hmacShaKeyFor}(bytes);
|
||||
* return {@link #verifyWith(Key) verifyWith}(key);</pre></blockquote>
|
||||
* return {@link #verifyWith(SecretKey) verifyWith}(key);</pre></blockquote>
|
||||
*
|
||||
* @param base64EncodedSecretKey BASE64-encoded HMAC-SHA key bytes used to create a Key which will be used to
|
||||
* verify all encountered JWS digital signatures.
|
||||
* @return the parser builder for method chaining.
|
||||
* @deprecated in favor of {@link #verifyWith(Key)} as explained in the above <b>Deprecation Notice</b>,
|
||||
* @deprecated in favor of {@link #verifyWith(SecretKey)} as explained in the above <b>Deprecation Notice</b>,
|
||||
* and will be removed in 1.0.0.
|
||||
*/
|
||||
@Deprecated
|
||||
|
@ -295,63 +325,104 @@ public interface JwtParserBuilder extends Builder<JwtParser> {
|
|||
* <p>This method is being renamed to accurately reflect its purpose - the key is not technically a signing key,
|
||||
* it is a signature verification key, and the two concepts can be different, especially with asymmetric key
|
||||
* cryptography. The method has been deprecated since JJWT_RELEASE_VERSION in favor of
|
||||
* {@link #verifyWith(Key)} for type safety, to reflect accurate naming of the concept, and for name congruence
|
||||
* with the {@link #decryptWith(Key)} method.</p>
|
||||
* {@link #verifyWith(SecretKey)} for type safety, to reflect accurate naming of the concept, and for name
|
||||
* congruence with the {@link #decryptWith(SecretKey)} method.</p>
|
||||
*
|
||||
* <p>This method merely delegates directly to {@link #verifyWith(Key)}.</p>
|
||||
* <p>This method merely delegates directly to {@link #verifyWith(SecretKey)}.</p>
|
||||
*
|
||||
* @param key the algorithm-specific signature verification key to use to verify all encountered JWS digital
|
||||
* signatures.
|
||||
* @return the parser builder for method chaining.
|
||||
* @deprecated since JJWT_RELEASE_VERSION in favor of {@link #verifyWith(Key)} for naming congruence with the
|
||||
* {@link #decryptWith(Key)} method.
|
||||
* @deprecated since JJWT_RELEASE_VERSION in favor of {@link #verifyWith(SecretKey)} for naming congruence with the
|
||||
* {@link #decryptWith(SecretKey)} method.
|
||||
*/
|
||||
@Deprecated
|
||||
JwtParserBuilder setSigningKey(Key key);
|
||||
|
||||
/**
|
||||
* Sets the signature verification key used to verify all encountered JWS signatures. If the encountered JWT
|
||||
* Sets the signature verification SecretKey used to verify all encountered JWS signatures. If the encountered JWT
|
||||
* string is not a JWS (e.g. unsigned or a JWE), this key is not used.
|
||||
*
|
||||
* <p>This is a convenience method to use in a specific scenario: when the parser will only ever encounter
|
||||
* JWSs with signatures that can always be verified by a single key. This also implies that this key
|
||||
* JWSs with signatures that can always be verified by a single SecretKey. This also implies that this key
|
||||
* <em>MUST</em> be a valid key for the signature algorithm ({@code alg} header) used for the JWS.</p>
|
||||
*
|
||||
* <p>If there is any chance that the parser will encounter JWSs
|
||||
* that need different signature verification keys based on the JWS being parsed, or JWEs, it is strongly
|
||||
* recommended to configure your own {@link Locator} via the
|
||||
* {@link #setKeyLocator(Locator) setKeyLocator} method instead of using this one.</p>
|
||||
* <p>If there is any chance that the parser will also encounter JWEs, or JWSs that need different signature
|
||||
* verification keys based on the JWS being parsed, it is strongly recommended to configure your own
|
||||
* {@link #keyLocator(Locator) keyLocator} instead of calling this method.</p>
|
||||
*
|
||||
* <p>Calling this method overrides any previously set signature verification key.</p>
|
||||
*
|
||||
* @param key the signature verification key to use to verify all encountered JWS digital signatures.
|
||||
* @return the parser builder for method chaining.
|
||||
* @see #verifyWith(PublicKey)
|
||||
* @since JJWT_RELEASE_VERSION
|
||||
*/
|
||||
JwtParserBuilder verifyWith(Key key);
|
||||
JwtParserBuilder verifyWith(SecretKey key);
|
||||
|
||||
/**
|
||||
* Sets the decryption key used to decrypt all encountered JWEs, <b>overwriting any previously configured
|
||||
* {@link #setKeyLocator(Locator) keyLocator}</b>. If the encountered JWT string is not a JWE (e.g. a JWS),
|
||||
* this key is not used.
|
||||
* Sets the signature verification PublicKey used to verify all encountered JWS signatures. If the encountered JWT
|
||||
* string is not a JWS (e.g. unsigned or a JWE), this key is not used.
|
||||
*
|
||||
* <p>This is a convenience method to use in a specific scenario: when the parser will only ever encounter
|
||||
* JWSs with signatures that can always be verified by a single PublicKey. This also implies that this key
|
||||
* <em>MUST</em> be a valid key for the signature algorithm ({@code alg} header) used for the JWS.</p>
|
||||
*
|
||||
* <p>If there is any chance that the parser will also encounter JWEs, or JWSs that need different signature
|
||||
* verification keys based on the JWS being parsed, it is strongly recommended to configure your own
|
||||
* {@link #keyLocator(Locator) keyLocator} instead of calling this method.</p>
|
||||
*
|
||||
* <p>Calling this method overrides any previously set signature verification key.</p>
|
||||
*
|
||||
* @param key the signature verification key to use to verify all encountered JWS digital signatures.
|
||||
* @return the parser builder for method chaining.
|
||||
* @see #verifyWith(SecretKey)
|
||||
* @since JJWT_RELEASE_VERSION
|
||||
*/
|
||||
JwtParserBuilder verifyWith(PublicKey key);
|
||||
|
||||
/**
|
||||
* Sets the decryption SecretKey used to decrypt all encountered JWEs. If the encountered JWT string is not a
|
||||
* JWE (e.g. a JWS), this key is not used.
|
||||
*
|
||||
* <p>This is a convenience method to use in specific circumstances: when the parser will only ever encounter
|
||||
* JWEs that can always be decrypted by a single key. This also implies that this key <em>MUST</em> be a valid
|
||||
* JWEs that can always be decrypted by a single SecretKey. This also implies that this key <em>MUST</em> be a valid
|
||||
* key for both the key management algorithm ({@code alg} header) and the content encryption algorithm
|
||||
* ({@code enc} header) used for the JWE.</p>
|
||||
*
|
||||
* <p>If there is any chance that the parser will encounter JWEs that need different decryption keys based on the
|
||||
* JWE being parsed, or JWSs, it is strongly recommended to configure
|
||||
* your own {@link Locator Locator} via the {@link #setKeyLocator(Locator) setKeyLocator} method instead of
|
||||
* using {@code decryptWith}.</p>
|
||||
* <p>If there is any chance that the parser will also encounter JWSs, or JWEs that need different decryption
|
||||
* keys based on the JWE being parsed, it is strongly recommended to configure your own
|
||||
* {@link #keyLocator(Locator) keyLocator} instead of calling this method.</p>
|
||||
*
|
||||
* <p>Calling this method overrides any previously set decryption key.</p>
|
||||
*
|
||||
* @param key the algorithm-specific decryption key to use to decrypt all encountered JWEs.
|
||||
* @return the parser builder for method chaining.
|
||||
* @see #decryptWith(PrivateKey)
|
||||
* @since JJWT_RELEASE_VERSION
|
||||
*/
|
||||
JwtParserBuilder decryptWith(Key key);
|
||||
JwtParserBuilder decryptWith(SecretKey key);
|
||||
|
||||
/**
|
||||
* Sets the decryption PrivateKey used to decrypt all encountered JWEs. If the encountered JWT string is not a
|
||||
* JWE (e.g. a JWS), this key is not used.
|
||||
*
|
||||
* <p>This is a convenience method to use in specific circumstances: when the parser will only ever encounter JWEs
|
||||
* that can always be decrypted by a single PrivateKey. This also implies that this key <em>MUST</em> be a valid
|
||||
* key for the JWE's key management algorithm ({@code alg} header).</p>
|
||||
*
|
||||
* <p>If there is any chance that the parser will also encounter JWSs, or JWEs that need different decryption
|
||||
* keys based on the JWE being parsed, it is strongly recommended to configure your own
|
||||
* {@link #keyLocator(Locator) keyLocator} instead of calling this method.</p>
|
||||
*
|
||||
* <p>Calling this method overrides any previously set decryption key.</p>
|
||||
*
|
||||
* @param key the algorithm-specific decryption key to use to decrypt all encountered JWEs.
|
||||
* @return the parser builder for method chaining.
|
||||
* @see #decryptWith(SecretKey)
|
||||
* @since JJWT_RELEASE_VERSION
|
||||
*/
|
||||
JwtParserBuilder decryptWith(PrivateKey key);
|
||||
|
||||
/**
|
||||
* Sets the {@link Locator} used to acquire any signature verification or decryption key needed during parsing.
|
||||
|
@ -361,13 +432,13 @@ public interface JwtParserBuilder extends Builder<JwtParser> {
|
|||
* <li>If the parsed String is a JWE, it will be called to find the appropriate decryption key.</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>Specifying a key {@code Locator} is necessary when the signing or decryption key is not already known before
|
||||
* parsing the JWT and the JWT header must be inspected first to determine how to
|
||||
* <p>Specifying a key {@code Locator} is necessary when the signature verification or decryption key is not
|
||||
* already known before parsing the JWT and the JWT header must be inspected first to determine how to
|
||||
* look up the verification or decryption key. Once returned by the locator, the JwtParser will then either
|
||||
* verify the JWS signature or decrypt the JWE payload with the returned key. For example:</p>
|
||||
*
|
||||
* <pre>
|
||||
* Jws<Claims> jws = Jwts.parser().setKeyLocator(new Locator<Key>() {
|
||||
* Jws<Claims> jws = Jwts.parser().keyLocator(new Locator<Key>() {
|
||||
* @Override
|
||||
* public Key locate(Header<?> header) {
|
||||
* if (header instanceof JwsHeader) {
|
||||
|
@ -386,14 +457,14 @@ public interface JwtParserBuilder extends Builder<JwtParser> {
|
|||
* @return the parser builder for method chaining.
|
||||
* @since JJWT_RELEASE_VERSION
|
||||
*/
|
||||
JwtParserBuilder setKeyLocator(Locator<Key> keyLocator);
|
||||
JwtParserBuilder keyLocator(Locator<Key> keyLocator);
|
||||
|
||||
/**
|
||||
* <p><b>Deprecation Notice</b></p>
|
||||
*
|
||||
* <p>This method has been deprecated as of JJWT version JJWT_RELEASE_VERSION because it only supports key location
|
||||
* for JWSs (signed JWTs) instead of both signed (JWS) and encrypted (JWE) scenarios. Use the
|
||||
* {@link #setKeyLocator(Locator) setKeyLocator} method instead to ensure a locator that can work for both JWS and
|
||||
* {@link #keyLocator(Locator) keyLocator} method instead to ensure a locator that can work for both JWS and
|
||||
* JWE inputs. This method will be removed for the 1.0 release.</p>
|
||||
*
|
||||
* <p><b>Previous Documentation</b></p>
|
||||
|
@ -420,7 +491,7 @@ public interface JwtParserBuilder extends Builder<JwtParser> {
|
|||
*
|
||||
* @param signingKeyResolver the signing key resolver used to retrieve the signing key.
|
||||
* @return the parser builder for method chaining.
|
||||
* @deprecated since JJWT_RELEASE_VERSION in favor of {@link #setKeyLocator(Locator)}
|
||||
* @deprecated since JJWT_RELEASE_VERSION in favor of {@link #keyLocator(Locator)}
|
||||
*/
|
||||
@SuppressWarnings("DeprecatedIsStillUsed")
|
||||
@Deprecated
|
||||
|
@ -428,82 +499,109 @@ public interface JwtParserBuilder extends Builder<JwtParser> {
|
|||
|
||||
/**
|
||||
* Adds the specified compression algorithms to the parser's total set of supported compression algorithms,
|
||||
* overwriting any previously-added compression algorithms with the same {@link CompressionAlgorithm#getId() id}s.
|
||||
* If the parser encounters a JWT {@code zip} header value that matches a compression algorithm's
|
||||
* {@link CompressionAlgorithm#getId() id}, that algorithm will be used for decompression.
|
||||
* replacing any existing ones with identical {@link Identifiable#getId() id}s.
|
||||
* If the parser encounters a JWT {@code zip} header value that equals a compression algorithm's
|
||||
* {@link Identifiable#getId() id}, that algorithm will be used for decompression.
|
||||
*
|
||||
* <p>There may be only one registered {@code CompressionAlgorithm} per {@code id}, and the {@code algs}
|
||||
* collection is added in iteration order; if a duplicate id is found when iterating the {@code algs}
|
||||
* collection, the later element will evict any previously-added algorithm with the same {@code id}.</p>
|
||||
* <p>There may be only one registered {@code CompressionAlgorithm} per CaSe-SeNsItIvE {@code id}, and the
|
||||
* {@code algs} collection is added in iteration order; if a duplicate id is found when iterating the {@code algs}
|
||||
* collection, the later algorithm will evict any existing algorithm with the same {@code id}.</p>
|
||||
*
|
||||
* <p>Finally, {@link Jwts.ZIP#DEF} and {@link Jwts.ZIP#GZIP} algorithms are added last,
|
||||
* <em>after</em> those in the {@code algs} collection, to ensure that JWA standard algorithms cannot be
|
||||
* accidentally replaced.</p>
|
||||
* <p><b>Standard Algorithms and Overrides</b></p>
|
||||
*
|
||||
* @param algs collection of compression algorithms to add to the parser's total set of supported compression algorithms.
|
||||
* <p>The {@link Jwts.ZIP} compression algorithms are supported by default and do not need
|
||||
* to be added via this method, but beware: <b>any algorithm in the {@code algs} collection with a
|
||||
* JWA standard {@link Identifiable#getId() id} will replace the JJWT standard algorithm implementation</b>.
|
||||
* This is to allow application developers to favor their own implementations over JJWT's default implementations
|
||||
* if necessary (for example, to support legacy or custom behavior).
|
||||
*
|
||||
* @param algs collection of compression algorithms to add to the parser's total set of supported compression
|
||||
* algorithms, replacing any existing ones with the same exact (CaSe-SeNsItIvE)
|
||||
* {@link CompressionAlgorithm#getId() id}s.
|
||||
* @return the builder for method chaining.
|
||||
* @see Jwts.ZIP
|
||||
* @since JJWT_RELEASE_VERSION
|
||||
*/
|
||||
JwtParserBuilder addCompressionAlgorithms(Collection<? extends CompressionAlgorithm> algs);
|
||||
|
||||
/**
|
||||
* Adds the specified AEAD encryption algorithms to the parser's total set of supported encryption algorithms,
|
||||
* overwriting any previously-added algorithms with the same {@link AeadAlgorithm#getId() id}s.
|
||||
* replacing any existing algorithms with the same exact (CaSe-SeNsItIvE) {@link AeadAlgorithm#getId() id}s.
|
||||
* If the parser encounters a JWT {@code enc} header value that equals an encryption algorithm's
|
||||
* {@link Identifiable#getId() id}, that algorithm will be used for decryption.
|
||||
*
|
||||
* <p>There may be only one registered {@code AeadAlgorithm} per algorithm {@code id}, and the {@code encAlgs}
|
||||
* collection is added in iteration order; if a duplicate id is found when iterating the {@code encAlgs}
|
||||
* collection, the later element will evict any previously-added algorithm with the same {@code id}.</p>
|
||||
* <p>There may be only one registered {@code AeadAlgorithm} per algorithm {@code id}, and the {@code algs}
|
||||
* collection is added in iteration order; if a duplicate id is found when iterating the {@code algs}
|
||||
* collection, the later algorithm will evict any existing algorithm with the same {@code id}.</p>
|
||||
*
|
||||
* <p>Finally, the {@link Jwts.ENC JWA standard encryption algorithms} are added last,
|
||||
* <em>after</em> those in the {@code encAlgs} collection, to ensure that JWA standard algorithms cannot be
|
||||
* accidentally replaced.</p>
|
||||
* <p><b>Standard Algorithms and Overrides</b></p>
|
||||
*
|
||||
* @param encAlgs collection of AEAD encryption algorithms to add to the parser's total set of supported
|
||||
* encryption algorithms.
|
||||
* <p>All JWA standard encryption algorithms in {@link Jwts.ENC} are supported by default and do not need
|
||||
* to be added via this method, but beware: <b>any algorithm in the {@code algs} collection with a
|
||||
* JWA standard {@link Identifiable#getId() id} will replace the JJWT standard algorithm implementation</b>.
|
||||
* This is to allow application developers to favor their own implementations over JJWT's default implementations
|
||||
* if necessary (for example, to support legacy or custom behavior).
|
||||
*
|
||||
* @param algs collection of AEAD encryption algorithms to add to the parser's total set of supported
|
||||
* encryption algorithms, replacing any existing algorithms with the same
|
||||
* {@link AeadAlgorithm#getId() id}s.
|
||||
* @return the builder for method chaining.
|
||||
* @since JJWT_RELEASE_VERSION
|
||||
*/
|
||||
JwtParserBuilder addEncryptionAlgorithms(Collection<? extends AeadAlgorithm> encAlgs);
|
||||
JwtParserBuilder addEncryptionAlgorithms(Collection<? extends AeadAlgorithm> algs);
|
||||
|
||||
/**
|
||||
* Adds the specified signature algorithms to the parser's total set of supported signature algorithms,
|
||||
* overwriting any previously-added algorithms with the same
|
||||
* {@link Identifiable#getId() id}s.
|
||||
* replacing any existing algorithms with the same exact (CaSe-SeNsItIvE) {@link Identifiable#getId() id}s.
|
||||
* If the parser encounters a JWS {@code alg} header value that equals a signature algorithm's
|
||||
* {@link Identifiable#getId() id}, that algorithm will be used for signature verification.
|
||||
*
|
||||
* <p>There may be only one registered {@code SecureDigestAlgorithm} per algorithm {@code id}, and the
|
||||
* {@code sigAlgs} collection is added in iteration order; if a duplicate id is found when iterating the
|
||||
* {@code sigAlgs} collection, the later element will evict any previously-added algorithm with the same
|
||||
* {@code id}.</p>
|
||||
* {@code algs} collection is added in iteration order; if a duplicate id is found when iterating the
|
||||
* {@code algs} argument, the later algorithm will evict any existing algorithm with the same {@code id}.</p>
|
||||
*
|
||||
* <p>Finally, the {@link Jwts.SIG JWA standard signature and MAC algorithms} are
|
||||
* added last, <em>after</em> those in the {@code sigAlgs} collection, to ensure that JWA standard algorithms
|
||||
* cannot be accidentally replaced.</p>
|
||||
* <p><b>Standard Algorithms and Overrides</b></p>
|
||||
*
|
||||
* @param sigAlgs collection of signing algorithms to add to the parser's total set of supported signature
|
||||
* algorithms.
|
||||
* <p>All JWA standard signature and MAC algorithms in {@link Jwts.SIG} are supported by default and do not need
|
||||
* to be added via this method, but beware: <b>any algorithm in the {@code algs} collection with a
|
||||
* JWA standard {@link Identifiable#getId() id} will replace the JJWT standard
|
||||
* algorithm implementation</b>. This is to allow application developers to favor their own implementations over
|
||||
* JJWT's default implementations if necessary (for example, to support legacy or custom behavior).
|
||||
*
|
||||
* @param algs collection of signature algorithms to add to the parser's total set of supported signature
|
||||
* algorithms, replacing any existing algorithms with the same exact (CaSe-SeNsItIvE)
|
||||
* {@link Identifiable#getId() id}s.
|
||||
* @return the builder for method chaining.
|
||||
* @see <a href="https://www.rfc-editor.org/rfc/rfc7518.html#section-7.1.1">Algorithm Name (id) requirements</a>
|
||||
* @since JJWT_RELEASE_VERSION
|
||||
*/
|
||||
JwtParserBuilder addSignatureAlgorithms(Collection<? extends SecureDigestAlgorithm<?, ?>> sigAlgs);
|
||||
JwtParserBuilder addSignatureAlgorithms(Collection<? extends SecureDigestAlgorithm<?, ?>> algs);
|
||||
|
||||
/**
|
||||
* Adds the specified key management algorithms to the parser's total set of supported key algorithms,
|
||||
* overwriting any previously-added algorithms with the same {@link KeyAlgorithm#getId() id}s.
|
||||
* replacing any existing algorithms with the same exact (CaSe-SeNsItIvE) {@link KeyAlgorithm#getId() id}s.
|
||||
* If the parser encounters a JWE {@code alg} header value that equals a key management algorithm's
|
||||
* {@link Identifiable#getId() id}, that algorithm will be used to obtain the content decryption key.
|
||||
*
|
||||
* <p>There may be only one registered {@code KeyAlgorithm} per algorithm {@code id}, and the {@code keyAlgs}
|
||||
* collection is added in iteration order; if a duplicate id is found when iterating the {@code keyAlgs}
|
||||
* collection, the later element will evict any previously-added algorithm with the same {@code id}.</p>
|
||||
* <p>There may be only one registered {@code KeyAlgorithm} per algorithm {@code id}, and the {@code algs}
|
||||
* collection is added in iteration order; if a duplicate id is found when iterating the {@code algs}
|
||||
* argument, the later algorithm will evict any existing algorithm with the same {@code id}.</p>
|
||||
*
|
||||
* <p>Finally, the {@link Jwts.KEY#get() JWA standard key management algorithms}
|
||||
* are added last, <em>after</em> those in the {@code keyAlgs} collection, to ensure that JWA standard algorithms
|
||||
* cannot be accidentally replaced.</p>
|
||||
* <p><b>Standard Algorithms and Overrides</b></p>
|
||||
*
|
||||
* @param keyAlgs collection of key management algorithms to add to the parser's total set of supported key
|
||||
* management algorithms.
|
||||
* <p>All JWA standard key management algorithms in {@link Jwts.KEY} are supported by default and do not need
|
||||
* to be added via this method, but beware: <b>any algorithm in the {@code algs} collection with a
|
||||
* JWA standard {@link Identifiable#getId() id} will replace the JJWT standard algorithm implementation</b>.
|
||||
* This is to allow application developers to favor their own implementations over JJWT's default implementations
|
||||
* if necessary (for example, to support legacy or custom behavior).
|
||||
*
|
||||
* @param algs collection of key management algorithms to add to the parser's total set of supported key
|
||||
* management algorithms, replacing any existing algorithms with the same exact (CaSe-SeNsItIvE)
|
||||
* {@link KeyAlgorithm#getId() id}s.
|
||||
* @return the builder for method chaining.
|
||||
* @since JJWT_RELEASE_VERSION
|
||||
*/
|
||||
JwtParserBuilder addKeyAlgorithms(Collection<? extends KeyAlgorithm<?, ?>> keyAlgs);
|
||||
JwtParserBuilder addKeyAlgorithms(Collection<? extends KeyAlgorithm<?, ?>> algs);
|
||||
|
||||
/**
|
||||
* <p><b>Deprecated as of JJWT JJWT_RELEASE_VERSION. This method will be removed before the 1.0 release.</b></p>
|
||||
|
@ -531,6 +629,7 @@ public interface JwtParserBuilder extends Builder<JwtParser> {
|
|||
* @param compressionCodecResolver the compression codec resolver used to decompress the JWT body.
|
||||
* @return the parser builder for method chaining.
|
||||
* @deprecated since JJWT_RELEASE_VERSION in favor of {@link #addCompressionAlgorithms(Collection)}.
|
||||
* This method will be removed before the 1.0 release.
|
||||
*/
|
||||
@Deprecated
|
||||
JwtParserBuilder setCompressionCodecResolver(CompressionCodecResolver compressionCodecResolver);
|
||||
|
@ -543,9 +642,41 @@ public interface JwtParserBuilder extends Builder<JwtParser> {
|
|||
*
|
||||
* @param base64UrlDecoder the decoder to use when Base64Url-decoding
|
||||
* @return the parser builder for method chaining.
|
||||
* @deprecated since JJWT_RELEASE_VERSION in favor of the shorter and more modern builder-style named
|
||||
* {@link #decoder(Decoder)}. This method will be removed before the JJWT 1.0 release.
|
||||
*/
|
||||
@Deprecated
|
||||
JwtParserBuilder base64UrlDecodeWith(Decoder<String, byte[]> base64UrlDecoder);
|
||||
|
||||
/**
|
||||
* Perform Base64Url decoding with the specified Decoder
|
||||
*
|
||||
* <p>JJWT uses a spec-compliant decoder that works on all supported JDK versions, but you may call this method
|
||||
* to specify a different decoder if you desire.</p>
|
||||
*
|
||||
* @param base64UrlDecoder the decoder to use when Base64Url-decoding
|
||||
* @return the parser builder for method chaining.
|
||||
*/
|
||||
JwtParserBuilder decoder(Decoder<String, byte[]> base64UrlDecoder);
|
||||
|
||||
/**
|
||||
* Uses the specified deserializer to convert JSON Strings (UTF-8 byte arrays) into Java Map objects. This is
|
||||
* used by the parser after Base64Url-decoding to convert JWT/JWS/JWT JSON headers and claims into Java Map
|
||||
* objects.
|
||||
*
|
||||
* <p>If this method is not called, JJWT will use whatever deserializer it can find at runtime, checking for the
|
||||
* presence of well-known implementations such Jackson, Gson, and org.json. If one of these is not found
|
||||
* in the runtime classpath, an exception will be thrown when one of the various {@code parse}* methods is
|
||||
* invoked.</p>
|
||||
*
|
||||
* @param deserializer the deserializer to use when converting JSON Strings (UTF-8 byte arrays) into Map objects.
|
||||
* @return the builder for method chaining.
|
||||
* @deprecated since JJWT_RELEASE_VERSION in favor of the shorter and more modern builder-style named
|
||||
* {@link #deserializer(Deserializer)}. This method will be removed before the JJWT 1.0 release.
|
||||
*/
|
||||
@Deprecated
|
||||
JwtParserBuilder deserializeJsonWith(Deserializer<Map<String, ?>> deserializer);
|
||||
|
||||
/**
|
||||
* Uses the specified deserializer to convert JSON Strings (UTF-8 byte arrays) into Java Map objects. This is
|
||||
* used by the parser after Base64Url-decoding to convert JWT/JWS/JWT JSON headers and claims into Java Map
|
||||
|
@ -559,7 +690,7 @@ public interface JwtParserBuilder extends Builder<JwtParser> {
|
|||
* @param deserializer the deserializer to use when converting JSON Strings (UTF-8 byte arrays) into Map objects.
|
||||
* @return the builder for method chaining.
|
||||
*/
|
||||
JwtParserBuilder deserializeJsonWith(Deserializer<Map<String, ?>> deserializer);
|
||||
JwtParserBuilder deserializer(Deserializer<Map<String, ?>> deserializer);
|
||||
|
||||
/**
|
||||
* Returns an immutable/thread-safe {@link JwtParser} created from the configuration from this JwtParserBuilder.
|
||||
|
|
|
@ -365,7 +365,7 @@ public final class Jwts {
|
|||
* <p>During JWE creation, this algorithm:</p>
|
||||
* <ol>
|
||||
* <li>Generates a new secure-random content encryption {@link SecretKey} suitable for use with a
|
||||
* specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#keyBuilder()}).</li>
|
||||
* specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#key()}).</li>
|
||||
* <li>Encrypts this newly-generated {@code SecretKey} with a 128-bit shared symmetric key using the
|
||||
* AES Key Wrap algorithm, producing encrypted key ciphertext.</li>
|
||||
* <li>Returns the encrypted key ciphertext for inclusion in the final JWE as well as the newly-generated
|
||||
|
@ -389,7 +389,7 @@ public final class Jwts {
|
|||
* <p>During JWE creation, this algorithm:</p>
|
||||
* <ol>
|
||||
* <li>Generates a new secure-random content encryption {@link SecretKey} suitable for use with a
|
||||
* specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#keyBuilder()}).</li>
|
||||
* specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#key()}).</li>
|
||||
* <li>Encrypts this newly-generated {@code SecretKey} with a 192-bit shared symmetric key using the
|
||||
* AES Key Wrap algorithm, producing encrypted key ciphertext.</li>
|
||||
* <li>Returns the encrypted key ciphertext for inclusion in the final JWE as well as the newly-generated
|
||||
|
@ -413,7 +413,7 @@ public final class Jwts {
|
|||
* <p>During JWE creation, this algorithm:</p>
|
||||
* <ol>
|
||||
* <li>Generates a new secure-random content encryption {@link SecretKey} suitable for use with a
|
||||
* specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#keyBuilder()}).</li>
|
||||
* specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#key()}).</li>
|
||||
* <li>Encrypts this newly-generated {@code SecretKey} with a 256-bit shared symmetric key using the
|
||||
* AES Key Wrap algorithm, producing encrypted key ciphertext.</li>
|
||||
* <li>Returns the encrypted key ciphertext for inclusion in the final JWE as well as the newly-generated
|
||||
|
@ -437,7 +437,7 @@ public final class Jwts {
|
|||
* <p>During JWE creation, this algorithm:</p>
|
||||
* <ol>
|
||||
* <li>Generates a new secure-random content encryption {@link SecretKey} suitable for use with a
|
||||
* specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#keyBuilder()}).</li>
|
||||
* specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#key()}).</li>
|
||||
* <li>Generates a new secure-random 96-bit Initialization Vector to use during key wrap/encryption.</li>
|
||||
* <li>Encrypts this newly-generated {@code SecretKey} with a 128-bit shared symmetric key using the
|
||||
* AES GCM Key Wrap algorithm with the generated Initialization Vector, producing encrypted key ciphertext
|
||||
|
@ -476,7 +476,7 @@ public final class Jwts {
|
|||
* <p>During JWE creation, this algorithm:</p>
|
||||
* <ol>
|
||||
* <li>Generates a new secure-random content encryption {@link SecretKey} suitable for use with a
|
||||
* specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#keyBuilder()}).</li>
|
||||
* specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#key()}).</li>
|
||||
* <li>Generates a new secure-random 96-bit Initialization Vector to use during key wrap/encryption.</li>
|
||||
* <li>Encrypts this newly-generated {@code SecretKey} with a 192-bit shared symmetric key using the
|
||||
* AES GCM Key Wrap algorithm with the generated Initialization Vector, producing encrypted key ciphertext
|
||||
|
@ -515,7 +515,7 @@ public final class Jwts {
|
|||
* <p>During JWE creation, this algorithm:</p>
|
||||
* <ol>
|
||||
* <li>Generates a new secure-random content encryption {@link SecretKey} suitable for use with a
|
||||
* specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#keyBuilder()}).</li>
|
||||
* specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#key()}).</li>
|
||||
* <li>Generates a new secure-random 96-bit Initialization Vector to use during key wrap/encryption.</li>
|
||||
* <li>Encrypts this newly-generated {@code SecretKey} with a 256-bit shared symmetric key using the
|
||||
* AES GCM Key Wrap algorithm with the generated Initialization Vector, producing encrypted key ciphertext
|
||||
|
@ -564,7 +564,7 @@ public final class Jwts {
|
|||
* <li>Derives a 128-bit Key Encryption Key with the PBES2-HS256 password-based key derivation algorithm,
|
||||
* using the provided password, iteration count, and input salt as arguments.</li>
|
||||
* <li>Generates a new secure-random Content Encryption {@link SecretKey} suitable for use with a
|
||||
* specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#keyBuilder()}).</li>
|
||||
* specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#key()}).</li>
|
||||
* <li>Encrypts this newly-generated Content Encryption {@code SecretKey} with the {@code A128KW} key wrap
|
||||
* algorithm using the 128-bit derived password-based Key Encryption Key from step {@code #3},
|
||||
* producing encrypted key ciphertext.</li>
|
||||
|
@ -609,7 +609,7 @@ public final class Jwts {
|
|||
* <li>Derives a 192-bit Key Encryption Key with the PBES2-HS384 password-based key derivation algorithm,
|
||||
* using the provided password, iteration count, and input salt as arguments.</li>
|
||||
* <li>Generates a new secure-random Content Encryption {@link SecretKey} suitable for use with a
|
||||
* specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#keyBuilder()}).</li>
|
||||
* specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#key()}).</li>
|
||||
* <li>Encrypts this newly-generated Content Encryption {@code SecretKey} with the {@code A192KW} key wrap
|
||||
* algorithm using the 192-bit derived password-based Key Encryption Key from step {@code #3},
|
||||
* producing encrypted key ciphertext.</li>
|
||||
|
@ -654,7 +654,7 @@ public final class Jwts {
|
|||
* <li>Derives a 256-bit Key Encryption Key with the PBES2-HS512 password-based key derivation algorithm,
|
||||
* using the provided password, iteration count, and input salt as arguments.</li>
|
||||
* <li>Generates a new secure-random Content Encryption {@link SecretKey} suitable for use with a
|
||||
* specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#keyBuilder()}).</li>
|
||||
* specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#key()}).</li>
|
||||
* <li>Encrypts this newly-generated Content Encryption {@code SecretKey} with the {@code A256KW} key wrap
|
||||
* algorithm using the 256-bit derived password-based Key Encryption Key from step {@code #3},
|
||||
* producing encrypted key ciphertext.</li>
|
||||
|
@ -690,7 +690,7 @@ public final class Jwts {
|
|||
* <p>During JWE creation, this algorithm:</p>
|
||||
* <ol>
|
||||
* <li>Generates a new secure-random content encryption {@link SecretKey} suitable for use with a
|
||||
* specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#keyBuilder()}).</li>
|
||||
* specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#key()}).</li>
|
||||
* <li>Encrypts this newly-generated {@code SecretKey} with the RSA key wrap algorithm, using the JWE
|
||||
* recipient's RSA Public Key, producing encrypted key ciphertext.</li>
|
||||
* <li>Returns the encrypted key ciphertext for inclusion in the final JWE as well as the newly-generated
|
||||
|
@ -715,7 +715,7 @@ public final class Jwts {
|
|||
* <p>During JWE creation, this algorithm:</p>
|
||||
* <ol>
|
||||
* <li>Generates a new secure-random content encryption {@link SecretKey} suitable for use with a
|
||||
* specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#keyBuilder()}).</li>
|
||||
* specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#key()}).</li>
|
||||
* <li>Encrypts this newly-generated {@code SecretKey} with the RSA OAEP with SHA-1 and MGF1 key wrap algorithm,
|
||||
* using the JWE recipient's RSA Public Key, producing encrypted key ciphertext.</li>
|
||||
* <li>Returns the encrypted key ciphertext for inclusion in the final JWE as well as the newly-generated
|
||||
|
@ -740,7 +740,7 @@ public final class Jwts {
|
|||
* <p>During JWE creation, this algorithm:</p>
|
||||
* <ol>
|
||||
* <li>Generates a new secure-random content encryption {@link SecretKey} suitable for use with a
|
||||
* specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#keyBuilder()}).</li>
|
||||
* specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#key()}).</li>
|
||||
* <li>Encrypts this newly-generated {@code SecretKey} with the RSA OAEP with SHA-256 and MGF1 key wrap
|
||||
* algorithm, using the JWE recipient's RSA Public Key, producing encrypted key ciphertext.</li>
|
||||
* <li>Returns the encrypted key ciphertext for inclusion in the final JWE as well as the newly-generated
|
||||
|
@ -818,7 +818,7 @@ public final class Jwts {
|
|||
* <a href="https://www.rfc-editor.org/rfc/rfc7518.html#section-4.6.1.1">"epk"
|
||||
* (Ephemeral Public Key) Header Parameter</a> to be transmitted in the JWE.</li>
|
||||
* <li>Generates a new secure-random content encryption {@link SecretKey} suitable for use with a
|
||||
* specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#keyBuilder()}).</li>
|
||||
* specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#key()}).</li>
|
||||
* <li>Encrypts this newly-generated {@code SecretKey} with the {@code A128KW} key wrap
|
||||
* algorithm using the derived symmetric Key Encryption Key from step {@code #3}, producing encrypted key ciphertext.</li>
|
||||
* <li>Returns the encrypted key ciphertext for inclusion in the final JWE as well as the newly-generated
|
||||
|
@ -866,7 +866,7 @@ public final class Jwts {
|
|||
* <a href="https://www.rfc-editor.org/rfc/rfc7518.html#section-4.6.1.1">"epk"
|
||||
* (Ephemeral Public Key) Header Parameter</a> to be transmitted in the JWE.</li>
|
||||
* <li>Generates a new secure-random content encryption {@link SecretKey} suitable for use with a
|
||||
* specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#keyBuilder()}).</li>
|
||||
* specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#key()}).</li>
|
||||
* <li>Encrypts this newly-generated {@code SecretKey} with the {@code A192KW} key wrap
|
||||
* algorithm using the derived symmetric Key Encryption Key from step {@code #3}, producing encrypted key
|
||||
* ciphertext.</li>
|
||||
|
@ -915,7 +915,7 @@ public final class Jwts {
|
|||
* <a href="https://www.rfc-editor.org/rfc/rfc7518.html#section-4.6.1.1">"epk"
|
||||
* (Ephemeral Public Key) Header Parameter</a> to be transmitted in the JWE.</li>
|
||||
* <li>Generates a new secure-random content encryption {@link SecretKey} suitable for use with a
|
||||
* specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#keyBuilder()}).</li>
|
||||
* specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#key()}).</li>
|
||||
* <li>Encrypts this newly-generated {@code SecretKey} with the {@code A256KW} key wrap
|
||||
* algorithm using the derived symmetric Key Encryption Key from step {@code #3}, producing encrypted key
|
||||
* ciphertext.</li>
|
||||
|
@ -1041,7 +1041,7 @@ public final class Jwts {
|
|||
|
||||
/**
|
||||
* <p><b>Deprecated since JJWT_RELEASE_VERSION in favor of
|
||||
* {@code Jwts.}{@link #claims()}{@code .set(map).build()}</b>.
|
||||
* {@code Jwts.}{@link #claims()}{@code .add(map).build()}</b>.
|
||||
* This method will be removed before 1.0.</p>
|
||||
*
|
||||
* <p>Returns a new {@link Claims} instance populated with the specified name/value pairs.</p>
|
||||
|
@ -1053,16 +1053,7 @@ public final class Jwts {
|
|||
*/
|
||||
@Deprecated
|
||||
public static Claims claims(Map<String, Object> claims) {
|
||||
return claims().set(claims).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new {@link JwtParserBuilder} instance that can be configured to create an immutable/thread-safe {@link JwtParser}.
|
||||
*
|
||||
* @return a new {@link JwtParser} instance that can be configured create an immutable/thread-safe {@link JwtParser}.
|
||||
*/
|
||||
public static JwtParserBuilder parser() {
|
||||
return Classes.newInstance("io.jsonwebtoken.impl.DefaultJwtParserBuilder");
|
||||
return claims().add(claims).build();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1076,6 +1067,15 @@ public final class Jwts {
|
|||
return Classes.newInstance("io.jsonwebtoken.impl.DefaultJwtBuilder");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new {@link JwtParserBuilder} instance that can be configured to create an immutable/thread-safe {@link JwtParser}.
|
||||
*
|
||||
* @return a new {@link JwtParser} instance that can be configured create an immutable/thread-safe {@link JwtParser}.
|
||||
*/
|
||||
public static JwtParserBuilder parser() {
|
||||
return Classes.newInstance("io.jsonwebtoken.impl.DefaultJwtParserBuilder");
|
||||
}
|
||||
|
||||
/**
|
||||
* Private constructor, prevent instantiation.
|
||||
*/
|
||||
|
|
|
@ -29,6 +29,32 @@ import java.util.Set;
|
|||
*/
|
||||
public interface ProtectedHeaderMutator<T extends ProtectedHeaderMutator<T>> extends HeaderMutator<T>, X509Mutator<T> {
|
||||
|
||||
/**
|
||||
* Sets the header parameter names that use extensions to the JWT or JWA specification that <em>MUST</em>
|
||||
* be understood and supported by the JWT recipient. A {@code null} value will remove the
|
||||
* property from the JSON map.
|
||||
*
|
||||
* @param crit the header parameter names that use extensions to the JWT or JWA specification that <em>MUST</em>
|
||||
* be understood and supported by the JWT recipient.
|
||||
* @return the header for method chaining.
|
||||
* @see <a href="https://www.rfc-editor.org/rfc/rfc7515.html#section-4.1.11">JWS <code>crit</code> (Critical) Header Parameter</a>
|
||||
* @see <a href="https://www.rfc-editor.org/rfc/rfc7516.html#section-4.1.13">JWS <code>crit</code> (Critical) Header Parameter</a>
|
||||
*/
|
||||
T critical(Set<String> crit);
|
||||
|
||||
/**
|
||||
* Sets the {@code jwk} (JSON Web Key) associated with the JWT. When set for a {@link JwsHeader}, the
|
||||
* {@code jwk} is the public key complement of the private key used to digitally sign the JWS. When set for a
|
||||
* {@link JweHeader}, the {@code jwk} is the public key to which the JWE was encrypted, and may be used to
|
||||
* determine the private key needed to decrypt the JWE.
|
||||
*
|
||||
* @param jwk the {@code jwk} (JSON Web Key) associated with the header.
|
||||
* @return the header for method chaining
|
||||
* @see <a href="https://www.rfc-editor.org/rfc/rfc7515.html#section-4.1.3">JWS <code>jwk</code> (JSON Web Key) Header Parameter</a>
|
||||
* @see <a href="https://www.rfc-editor.org/rfc/rfc7516.html#section-4.1.5">JWE <code>jwk</code> (JSON Web Key) Header Parameter</a>
|
||||
*/
|
||||
T jwk(PublicJwk<?> jwk);
|
||||
|
||||
/**
|
||||
* Sets the {@code jku} (JWK Set URL) value that refers to a
|
||||
* <a href="https://www.rfc-editor.org/rfc/rfc7517.html#section-5">JWK Set</a>
|
||||
|
@ -43,20 +69,7 @@ public interface ProtectedHeaderMutator<T extends ProtectedHeaderMutator<T>> ext
|
|||
* @see <a href="https://www.rfc-editor.org/rfc/rfc7515.html#section-4.1.2">JWS JWK Set URL</a>
|
||||
* @see <a href="https://www.rfc-editor.org/rfc/rfc7516.html#section-4.1.4">JWE JWK Set URL</a>
|
||||
*/
|
||||
T setJwkSetUrl(URI uri);
|
||||
|
||||
/**
|
||||
* Sets the {@code jwk} (JSON Web Key) associated with the JWT. When set for a {@link JwsHeader}, the
|
||||
* {@code jwk} is the public key complement of the private key used to digitally sign the JWS. When set for a
|
||||
* {@link JweHeader}, the {@code jwk} is the public key to which the JWE was encrypted, and may be used to
|
||||
* determine the private key needed to decrypt the JWE.
|
||||
*
|
||||
* @param jwk the {@code jwk} (JSON Web Key) associated with the header.
|
||||
* @return the header for method chaining
|
||||
* @see <a href="https://www.rfc-editor.org/rfc/rfc7515.html#section-4.1.3">JWS <code>jwk</code> (JSON Web Key) Header Parameter</a>
|
||||
* @see <a href="https://www.rfc-editor.org/rfc/rfc7516.html#section-4.1.5">JWE <code>jwk</code> (JSON Web Key) Header Parameter</a>
|
||||
*/
|
||||
T setJwk(PublicJwk<?> jwk);
|
||||
T jwkSetUrl(URI uri);
|
||||
|
||||
/**
|
||||
* Sets the JWT case-sensitive {@code kid} (Key ID) header value. A {@code null} value will remove the property
|
||||
|
@ -73,18 +86,29 @@ public interface ProtectedHeaderMutator<T extends ProtectedHeaderMutator<T>> ext
|
|||
* @see <a href="https://www.rfc-editor.org/rfc/rfc7515.html#section-4.1.4">JWS Key ID</a>
|
||||
* @see <a href="https://www.rfc-editor.org/rfc/rfc7516.html#section-4.1.6">JWE Key ID</a>
|
||||
*/
|
||||
T keyId(String kid);
|
||||
|
||||
/**
|
||||
* Deprecated since JJWT_RELEASE_VERSION, delegates to {@link #keyId(String)}.
|
||||
*
|
||||
* @param kid the case-sensitive JWS {@code kid} header value or {@code null} to remove the property from the JSON map.
|
||||
* @return the instance for method chaining.
|
||||
* @see <a href="https://www.rfc-editor.org/rfc/rfc7515.html#section-4.1.4">JWS Key ID</a>
|
||||
* @see <a href="https://www.rfc-editor.org/rfc/rfc7516.html#section-4.1.6">JWE Key ID</a>
|
||||
* @deprecated since JJWT_RELEASE_VERSION in favor of the more modern builder-style {@link #keyId(String)} method.
|
||||
*/
|
||||
@Deprecated
|
||||
T setKeyId(String kid);
|
||||
|
||||
/**
|
||||
* Sets the header parameter names that use extensions to the JWT or JWA specification that <em>MUST</em>
|
||||
* be understood and supported by the JWT recipient. A {@code null} value will remove the
|
||||
* property from the JSON map.
|
||||
* Deprecated as of JJWT_RELEASE_VERSION, there is no need to set this any longer as the {@code JwtBuilder} will
|
||||
* always set the {@code alg} header as necessary.
|
||||
*
|
||||
* @param crit the header parameter names that use extensions to the JWT or JWA specification that <em>MUST</em>
|
||||
* be understood and supported by the JWT recipient.
|
||||
* @return the header for method chaining.
|
||||
* @see <a href="https://www.rfc-editor.org/rfc/rfc7515.html#section-4.1.11">JWS <code>crit</code> (Critical) Header Parameter</a>
|
||||
* @see <a href="https://www.rfc-editor.org/rfc/rfc7516.html#section-4.1.13">JWS <code>crit</code> (Critical) Header Parameter</a>
|
||||
* @param alg the JWS or JWE algorithm {@code alg} value or {@code null} to remove the property from the JSON map.
|
||||
* @return the instance for method chaining.
|
||||
* @since 0.1
|
||||
* @deprecated since JJWT_RELEASE_VERSION and will be removed before the 1.0 release.
|
||||
*/
|
||||
T setCritical(Set<String> crit);
|
||||
@Deprecated
|
||||
T setAlgorithm(String alg);
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ import java.security.Key;
|
|||
* the {@link io.jsonwebtoken.SigningKeyResolverAdapter} and overriding only the method you need to support instead of
|
||||
* implementing this interface directly.</p>
|
||||
*
|
||||
* @see io.jsonwebtoken.JwtParserBuilder#setKeyLocator(Locator)
|
||||
* @see io.jsonwebtoken.JwtParserBuilder#keyLocator(Locator)
|
||||
* @since 0.4
|
||||
* @deprecated since JJWT_RELEASE_VERSION. Implement {@link Locator} instead.
|
||||
*/
|
||||
|
|
|
@ -25,7 +25,7 @@ import java.security.Key;
|
|||
*
|
||||
* <p>As of JJWT JJWT_RELEASE_VERSION, various Resolver concepts (including the {@code SigningKeyResolver}) have been
|
||||
* unified into a single {@link Locator} interface. For key location, (for both signing and encryption keys),
|
||||
* use the {@link JwtParserBuilder#setKeyLocator(Locator)} to configure a parser with your desired Key locator instead
|
||||
* use the {@link JwtParserBuilder#keyLocator(Locator)} to configure a parser with your desired Key locator instead
|
||||
* of using a {@code SigningKeyResolver}. Also see {@link LocatorAdapter} for the Adapter pattern parallel of this
|
||||
* class. <b>This {@code SigningKeyResolverAdapter} class will be removed before the 1.0 release.</b></p>
|
||||
*
|
||||
|
@ -46,11 +46,11 @@ import java.security.Key;
|
|||
* are not overridden, one (or both) of the *KeyBytes variants must be overridden depending on your expected
|
||||
* use case. You do not have to override any method that does not represent an expected condition.</p>
|
||||
*
|
||||
* @see io.jsonwebtoken.JwtParserBuilder#setKeyLocator(Locator)
|
||||
* @see io.jsonwebtoken.JwtParserBuilder#keyLocator(Locator)
|
||||
* @see LocatorAdapter
|
||||
* @since 0.4
|
||||
* @deprecated since JJWT_RELEASE_VERSION. Use {@link LocatorAdapter LocatorAdapter} with
|
||||
* {@link JwtParserBuilder#setKeyLocator(Locator)}
|
||||
* {@link JwtParserBuilder#keyLocator(Locator)}
|
||||
*/
|
||||
@SuppressWarnings("DeprecatedIsStillUsed")
|
||||
@Deprecated
|
||||
|
|
|
@ -29,6 +29,16 @@ import java.util.Map;
|
|||
*/
|
||||
public interface MapMutator<K, V, T extends MapMutator<K, V, T>> {
|
||||
|
||||
/**
|
||||
* Removes the map entry with the specified key.
|
||||
* <p>This method is the same as {@link Map#remove Map.remove}, but instead returns the mutator instance for
|
||||
* method chaining.</p>
|
||||
*
|
||||
* @param key the key for the map entry to remove.
|
||||
* @return the mutator/builder for method chaining.
|
||||
*/
|
||||
T delete(K key);
|
||||
|
||||
/**
|
||||
* Removes all entries from the map. The map will be empty after this call returns.
|
||||
* <p>This method is the same as {@link Map#clear Map.clear}, but instead returns the mutator instance for
|
||||
|
@ -39,8 +49,9 @@ public interface MapMutator<K, V, T extends MapMutator<K, V, T>> {
|
|||
T empty();
|
||||
|
||||
/**
|
||||
* Sets the specified name/value pair in the map. A {@code null} or empty value will remove the property
|
||||
* from the map entirely.
|
||||
* Sets the specified key/value pair in the map, overwriting any existing entry with the same key.
|
||||
* A {@code null} or empty value will remove the entry from the map entirely.
|
||||
*
|
||||
* <p>This method is the same as {@link Map#put Map.put}, but instead returns the mutator instance for
|
||||
* method chaining.</p>
|
||||
*
|
||||
|
@ -48,26 +59,17 @@ public interface MapMutator<K, V, T extends MapMutator<K, V, T>> {
|
|||
* @param value the value to set for the specified header parameter name
|
||||
* @return the mutator/builder for method chaining.
|
||||
*/
|
||||
T set(K key, V value);
|
||||
T add(K key, V value);
|
||||
|
||||
/**
|
||||
* Sets the specified name/value pairs in the map. If any name has a {@code null} or empty value, that
|
||||
* map entry will be removed from the map entirely.
|
||||
* Sets the specified key/value pairs in the map, overwriting any existing entries with the same keys.
|
||||
* If any pair has a {@code null} or empty value, that pair will be removed from the map entirely.
|
||||
*
|
||||
* <p>This method is the same as {@link Map#putAll Map.putAll}, but instead returns the mutator instance for
|
||||
* method chaining.</p>
|
||||
*
|
||||
* @param m the map to add
|
||||
* @return the mutator/builder for method chaining.
|
||||
*/
|
||||
T set(Map<? extends K, ? extends V> m);
|
||||
|
||||
/**
|
||||
* Removes the map entry with the specified key.
|
||||
* <p>This method is the same as {@link Map#remove Map.remove}, but instead returns the mutator instance for
|
||||
* method chaining.</p>
|
||||
*
|
||||
* @param key the key for the map entry to remove.
|
||||
* @return the mutator/builder for method chaining.
|
||||
*/
|
||||
T delete(K key);
|
||||
T add(Map<? extends K, ? extends V> m);
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ import javax.crypto.SecretKey;
|
|||
* and algorithm parameters required by that algorithm. For example:</p>
|
||||
*
|
||||
* <pre><code>
|
||||
* SecretKey key = aeadAlgorithm.keyBuilder().build();
|
||||
* SecretKey key = aeadAlgorithm.key().build();
|
||||
* </code></pre>
|
||||
*
|
||||
* <p>The resulting {@code key} is guaranteed to have the correct algorithm parameters and strength/length necessary for
|
||||
|
|
|
@ -69,7 +69,7 @@ public interface AsymmetricJwkBuilder<K extends Key, J extends AsymmetricJwk<K>,
|
|||
*
|
||||
* <p>Per
|
||||
* <a href="https://www.rfc-editor.org/rfc/rfc7517.html#section-4.3">JWK RFC 7517, Section 4.3, last paragraph</a>,
|
||||
* the {@code use} (Public Key Use) and {@link #setOperations(Set) key_ops (Key Operations)} members
|
||||
* the {@code use} (Public Key Use) and {@link #operations(Set) key_ops (Key Operations)} members
|
||||
* <em>SHOULD NOT</em> be used together; however, if both are used, the information they convey <em>MUST</em> be
|
||||
* consistent. Applications should specify which of these members they use, if either is to be used by the
|
||||
* application.</p>
|
||||
|
@ -78,5 +78,5 @@ public interface AsymmetricJwkBuilder<K extends Key, J extends AsymmetricJwk<K>,
|
|||
* @return the builder for method chaining.
|
||||
* @throws IllegalArgumentException if the {@code use} value is {@code null} or empty.
|
||||
*/
|
||||
T setPublicKeyUse(String use) throws IllegalArgumentException;
|
||||
T publicKeyUse(String use) throws IllegalArgumentException;
|
||||
}
|
||||
|
|
|
@ -28,14 +28,56 @@ import java.security.interfaces.RSAPublicKey;
|
|||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A prototypical {@link JwkBuilder} that coerces to a more type-specific builder based on the {@link Key} that will
|
||||
* be represented as a JWK.
|
||||
* A {@link JwkBuilder} that coerces to a more type-specific builder based on the {@link Key} that will be
|
||||
* represented as a JWK.
|
||||
*
|
||||
* @param <K> the type of Java {@link Key} represented by the created {@link Jwk}.
|
||||
* @param <J> the type of {@link Jwk} created by the builder
|
||||
* @since JJWT_RELEASE_VERSION
|
||||
*/
|
||||
public interface ProtoJwkBuilder<K extends Key, J extends Jwk<K>> extends JwkBuilder<K, J, ProtoJwkBuilder<K, J>> {
|
||||
public interface DynamicJwkBuilder<K extends Key, J extends Jwk<K>> extends JwkBuilder<K, J, DynamicJwkBuilder<K, J>> {
|
||||
|
||||
/**
|
||||
* Ensures the builder will create a {@link PublicJwk} for the specified Java {@link X509Certificate} chain.
|
||||
* The first {@code X509Certificate} in the chain (at array index 0) <em>MUST</em> contain a {@link PublicKey}
|
||||
* instance when calling the certificate's {@link X509Certificate#getPublicKey() getPublicKey()} method.
|
||||
*
|
||||
* <p>This method is provided for congruence with the other {@code chain} methods and is expected to be used when
|
||||
* the calling code has a variable {@code PublicKey} reference. Based on the argument type, it will
|
||||
* delegate to one of the following methods if possible:
|
||||
* <ul>
|
||||
* <li>{@link #rsaChain(List)}</li>
|
||||
* <li>{@link #ecChain(List)}</li>
|
||||
* <li>{@link #octetChain(List)}</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>If the specified {@code chain} argument is not capable of being supported by one of those methods, an
|
||||
* {@link UnsupportedKeyException} will be thrown.</p>
|
||||
*
|
||||
* <p><b>Type Parameters</b></p>
|
||||
*
|
||||
* <p>In addition to the public key type <code>A</code>, the public key's associated private key type
|
||||
* <code>B</code> is parameterized as well. This ensures that any subsequent call to the builder's
|
||||
* {@link PublicJwkBuilder#privateKey(PrivateKey) privateKey} method will be type-safe. For example:</p>
|
||||
*
|
||||
* <blockquote><pre>Jwks.builder().<EdECPublicKey, <b>EdECPrivateKey</b>>chain(edECPublicKeyX509CertificateChain)
|
||||
* .privateKey(<b>aPrivateKey</b>) // <-- must be an EdECPrivateKey instance
|
||||
* ... etc ...
|
||||
* .build();</pre></blockquote>
|
||||
*
|
||||
* @param <A> the type of {@link PublicKey} provided by the created public JWK.
|
||||
* @param <B> the type of {@link PrivateKey} that may be paired with the {@link PublicKey} to produce a
|
||||
* {@link PrivateJwk} if desired.
|
||||
* @param chain the {@link X509Certificate} chain to inspect to find the {@link PublicKey} to represent as a
|
||||
* {@link PublicJwk}.
|
||||
* @return the builder coerced as a {@link PublicJwkBuilder} for continued method chaining.
|
||||
* @throws UnsupportedKeyException if the specified key is not a supported type and cannot be used to delegate to
|
||||
* other {@code key} methods.
|
||||
* @see PublicJwk
|
||||
* @see PrivateJwk
|
||||
*/
|
||||
<A extends PublicKey, B extends PrivateKey> PublicJwkBuilder<A, B, ?, ?, ?, ?> chain(List<X509Certificate> chain)
|
||||
throws UnsupportedKeyException;
|
||||
|
||||
/**
|
||||
* Ensures the builder will create a {@link SecretJwk} for the specified Java {@link SecretKey}.
|
||||
|
@ -43,7 +85,7 @@ public interface ProtoJwkBuilder<K extends Key, J extends Jwk<K>> extends JwkBui
|
|||
* @param key the {@link SecretKey} to represent as a {@link SecretJwk}.
|
||||
* @return the builder coerced as a {@link SecretJwkBuilder}.
|
||||
*/
|
||||
SecretJwkBuilder forKey(SecretKey key);
|
||||
SecretJwkBuilder key(SecretKey key);
|
||||
|
||||
/**
|
||||
* Ensures the builder will create an {@link RsaPublicJwk} for the specified Java {@link RSAPublicKey}.
|
||||
|
@ -51,20 +93,20 @@ public interface ProtoJwkBuilder<K extends Key, J extends Jwk<K>> extends JwkBui
|
|||
* @param key the {@link RSAPublicKey} to represent as a {@link RsaPublicJwk}.
|
||||
* @return the builder coerced as an {@link RsaPublicJwkBuilder}.
|
||||
*/
|
||||
RsaPublicJwkBuilder forKey(RSAPublicKey key);
|
||||
RsaPublicJwkBuilder key(RSAPublicKey key);
|
||||
|
||||
/**
|
||||
* Ensures the builder will create an {@link RsaPrivateJwk} for the specified Java {@link RSAPrivateKey}. If
|
||||
* possible, it is recommended to also call the resulting builder's
|
||||
* {@link RsaPrivateJwkBuilder#setPublicKey(PublicKey) setPublicKey} method with the private key's matching
|
||||
* {@link RsaPrivateJwkBuilder#publicKey(PublicKey) publicKey} method with the private key's matching
|
||||
* {@link PublicKey} for better performance. See the
|
||||
* {@link RsaPrivateJwkBuilder#setPublicKey(PublicKey) setPublicKey} and {@link PrivateJwk} JavaDoc for more
|
||||
* {@link RsaPrivateJwkBuilder#publicKey(PublicKey) publicKey} and {@link PrivateJwk} JavaDoc for more
|
||||
* information.
|
||||
*
|
||||
* @param key the {@link RSAPublicKey} to represent as a {@link RsaPublicJwk}.
|
||||
* @return the builder coerced as an {@link RsaPrivateJwkBuilder}.
|
||||
*/
|
||||
RsaPrivateJwkBuilder forKey(RSAPrivateKey key);
|
||||
RsaPrivateJwkBuilder key(RSAPrivateKey key);
|
||||
|
||||
/**
|
||||
* Ensures the builder will create an {@link EcPublicJwk} for the specified Java {@link ECPublicKey}.
|
||||
|
@ -72,31 +114,30 @@ public interface ProtoJwkBuilder<K extends Key, J extends Jwk<K>> extends JwkBui
|
|||
* @param key the {@link ECPublicKey} to represent as a {@link EcPublicJwk}.
|
||||
* @return the builder coerced as an {@link EcPublicJwkBuilder}.
|
||||
*/
|
||||
EcPublicJwkBuilder forKey(ECPublicKey key);
|
||||
EcPublicJwkBuilder key(ECPublicKey key);
|
||||
|
||||
/**
|
||||
* Ensures the builder will create an {@link EcPrivateJwk} for the specified Java {@link ECPrivateKey}. If
|
||||
* possible, it is recommended to also call the resulting builder's
|
||||
* {@link EcPrivateJwkBuilder#setPublicKey(PublicKey) setPublicKey} method with the private key's matching
|
||||
* {@link EcPrivateJwkBuilder#publicKey(PublicKey) publicKey} method with the private key's matching
|
||||
* {@link PublicKey} for better performance. See the
|
||||
* {@link EcPrivateJwkBuilder#setPublicKey(PublicKey) setPublicKey} and {@link PrivateJwk} JavaDoc for more
|
||||
* {@link EcPrivateJwkBuilder#publicKey(PublicKey) publicKey} and {@link PrivateJwk} JavaDoc for more
|
||||
* information.
|
||||
*
|
||||
* @param key the {@link ECPublicKey} to represent as an {@link EcPublicJwk}.
|
||||
* @return the builder coerced as a {@link EcPrivateJwkBuilder}.
|
||||
*/
|
||||
EcPrivateJwkBuilder forKey(ECPrivateKey key);
|
||||
|
||||
EcPrivateJwkBuilder key(ECPrivateKey key);
|
||||
|
||||
/**
|
||||
* Ensures the builder will create a {@link PublicJwk} for the specified Java {@link PublicKey} argument. This
|
||||
* method is provided for congruence with the other {@code forKey} methods and is expected to be used when
|
||||
* method is provided for congruence with the other {@code key} methods and is expected to be used when
|
||||
* the calling code has an untyped {@code PublicKey} reference. Based on the argument type, it will delegate to one
|
||||
* of the following methods if possible:
|
||||
* <ul>
|
||||
* <li>{@link #forKey(RSAPublicKey)}</li>
|
||||
* <li>{@link #forKey(ECPublicKey)}</li>
|
||||
* <li>{@link #forOctetKey(PublicKey)}</li>
|
||||
* <li>{@link #key(RSAPublicKey)}</li>
|
||||
* <li>{@link #key(ECPublicKey)}</li>
|
||||
* <li>{@link #octetKey(PublicKey)}</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>If the specified {@code key} argument is not capable of being supported by one of those methods, an
|
||||
|
@ -106,10 +147,10 @@ public interface ProtoJwkBuilder<K extends Key, J extends Jwk<K>> extends JwkBui
|
|||
*
|
||||
* <p>In addition to the public key type <code>A</code>, the public key's associated private key type
|
||||
* <code>B</code> is parameterized as well. This ensures that any subsequent call to the builder's
|
||||
* {@link PublicJwkBuilder#setPrivateKey(PrivateKey) setPrivateKey} method will be type-safe. For example:</p>
|
||||
* {@link PublicJwkBuilder#privateKey(PrivateKey) privateKey} method will be type-safe. For example:</p>
|
||||
*
|
||||
* <blockquote><pre>Jwks.builder().<EdECPublicKey, <b>EdECPrivateKey</b>>forKey(anEdECPublicKey)
|
||||
* .setPrivateKey(<b>aPrivateKey</b>) // <-- must be an EdECPrivateKey instance
|
||||
* <blockquote><pre>Jwks.builder().<EdECPublicKey, <b>EdECPrivateKey</b>>key(anEdECPublicKey)
|
||||
* .privateKey(<b>aPrivateKey</b>) // <-- must be an EdECPrivateKey instance
|
||||
* ... etc ...
|
||||
* .build();</pre></blockquote>
|
||||
*
|
||||
|
@ -119,21 +160,21 @@ public interface ProtoJwkBuilder<K extends Key, J extends Jwk<K>> extends JwkBui
|
|||
* @param key the {@link PublicKey} to represent as a {@link PublicJwk}.
|
||||
* @return the builder coerced as a {@link PublicJwkBuilder} for continued method chaining.
|
||||
* @throws UnsupportedKeyException if the specified key is not a supported type and cannot be used to delegate to
|
||||
* other {@code forKey} methods.
|
||||
* other {@code key} methods.
|
||||
* @see PublicJwk
|
||||
* @see PrivateJwk
|
||||
*/
|
||||
<A extends PublicKey, B extends PrivateKey> PublicJwkBuilder<A, B, ?, ?, ?, ?> forKey(A key) throws UnsupportedKeyException;
|
||||
<A extends PublicKey, B extends PrivateKey> PublicJwkBuilder<A, B, ?, ?, ?, ?> key(A key) throws UnsupportedKeyException;
|
||||
|
||||
/**
|
||||
* Ensures the builder will create a {@link PrivateJwk} for the specified Java {@link PrivateKey} argument. This
|
||||
* method is provided for congruence with the other {@code forKey} methods and is expected to be used when
|
||||
* method is provided for congruence with the other {@code key} methods and is expected to be used when
|
||||
* the calling code has an untyped {@code PrivateKey} reference. Based on the argument type, it will delegate to one
|
||||
* of the following methods if possible:
|
||||
* <ul>
|
||||
* <li>{@link #forKey(RSAPrivateKey)}</li>
|
||||
* <li>{@link #forKey(ECPrivateKey)}</li>
|
||||
* <li>{@link #forOctetKey(PrivateKey)}</li>
|
||||
* <li>{@link #key(RSAPrivateKey)}</li>
|
||||
* <li>{@link #key(ECPrivateKey)}</li>
|
||||
* <li>{@link #octetKey(PrivateKey)}</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>If the specified {@code key} argument is not capable of being supported by one of those methods, an
|
||||
|
@ -143,10 +184,10 @@ public interface ProtoJwkBuilder<K extends Key, J extends Jwk<K>> extends JwkBui
|
|||
*
|
||||
* <p>In addition to the private key type <code>B</code>, the private key's associated public key type
|
||||
* <code>A</code> is parameterized as well. This ensures that any subsequent call to the builder's
|
||||
* {@link PrivateJwkBuilder#setPublicKey(PublicKey) setPublicKey} method will be type-safe. For example:</p>
|
||||
* {@link PrivateJwkBuilder#publicKey(PublicKey) publicKey} method will be type-safe. For example:</p>
|
||||
*
|
||||
* <blockquote><pre>Jwks.builder().<<b>EdECPublicKey</b>, EdECPrivateKey>forKey(anEdECPrivateKey)
|
||||
* .setPublicKey(<b>aPublicKey</b>) // <-- must be an EdECPublicKey instance
|
||||
* <blockquote><pre>Jwks.builder().<<b>EdECPublicKey</b>, EdECPrivateKey>key(anEdECPrivateKey)
|
||||
* .publicKey(<b>aPublicKey</b>) // <-- must be an EdECPublicKey instance
|
||||
* ... etc ...
|
||||
* .build();</pre></blockquote>
|
||||
*
|
||||
|
@ -155,11 +196,50 @@ public interface ProtoJwkBuilder<K extends Key, J extends Jwk<K>> extends JwkBui
|
|||
* @param key the {@link PrivateKey} to represent as a {@link PrivateJwk}.
|
||||
* @return the builder coerced as a {@link PrivateJwkBuilder} for continued method chaining.
|
||||
* @throws UnsupportedKeyException if the specified key is not a supported type and cannot be used to delegate to
|
||||
* other {@code forKey} methods.
|
||||
* other {@code key} methods.
|
||||
* @see PublicJwk
|
||||
* @see PrivateJwk
|
||||
*/
|
||||
<A extends PublicKey, B extends PrivateKey> PrivateJwkBuilder<B, A, ?, ?, ?> forKey(B key) throws UnsupportedKeyException;
|
||||
<A extends PublicKey, B extends PrivateKey> PrivateJwkBuilder<B, A, ?, ?, ?> key(B key) throws UnsupportedKeyException;
|
||||
|
||||
/**
|
||||
* Ensures the builder will create a {@link PrivateJwk} for the specified Java {@link KeyPair} argument. This
|
||||
* method is provided for congruence with the other {@code keyPair} methods and is expected to be used when
|
||||
* the calling code has a variable {@code PrivateKey} reference. Based on the argument's {@code PrivateKey} type,
|
||||
* it will delegate to one of the following methods if possible:
|
||||
* <ul>
|
||||
* <li>{@link #key(RSAPrivateKey)}</li>
|
||||
* <li>{@link #key(ECPrivateKey)}</li>
|
||||
* <li>{@link #octetKey(PrivateKey)}</li>
|
||||
* </ul>
|
||||
* <p>and automatically set the resulting builder's {@link PrivateJwkBuilder#publicKey(PublicKey) publicKey} with
|
||||
* the pair's {@code PublicKey}.</p>
|
||||
*
|
||||
* <p>If the specified {@code key} argument is not capable of being supported by one of those methods, an
|
||||
* {@link UnsupportedKeyException} will be thrown.</p>
|
||||
*
|
||||
* <p><b>Type Parameters</b></p>
|
||||
*
|
||||
* <p>In addition to the private key type <code>B</code>, the private key's associated public key type
|
||||
* <code>A</code> is parameterized as well. This ensures that any subsequent call to the builder's
|
||||
* {@link PrivateJwkBuilder#publicKey(PublicKey) publicKey} method will be type-safe. For example:</p>
|
||||
*
|
||||
* <blockquote><pre>Jwks.builder().<<b>EdECPublicKey</b>, EdECPrivateKey>keyPair(anEdECKeyPair)
|
||||
* .publicKey(<b>aPublicKey</b>) // <-- must be an EdECPublicKey instance
|
||||
* ... etc ...
|
||||
* .build();</pre></blockquote>
|
||||
*
|
||||
* @param <A> the {@code keyPair} argument's {@link PublicKey} type
|
||||
* @param <B> the {@code keyPair} argument's {@link PrivateKey} type
|
||||
* @param keyPair the {@code KeyPair} containing the public and private key
|
||||
* @return the builder coerced as a {@link PrivateJwkBuilder} for continued method chaining.
|
||||
* @throws UnsupportedKeyException if the specified {@code KeyPair}'s keys are not supported and cannot be used to
|
||||
* delegate to other {@code key} methods.
|
||||
* @see PublicJwk
|
||||
* @see PrivateJwk
|
||||
*/
|
||||
<A extends PublicKey, B extends PrivateKey> PrivateJwkBuilder<B, A, ?, ?, ?> keyPair(KeyPair keyPair)
|
||||
throws UnsupportedKeyException;
|
||||
|
||||
/**
|
||||
* Ensures the builder will create an {@link OctetPublicJwk} for the specified Edwards-curve {@code PublicKey}
|
||||
|
@ -175,10 +255,10 @@ public interface ProtoJwkBuilder<K extends Key, J extends Jwk<K>> extends JwkBui
|
|||
*
|
||||
* <p>In addition to the public key type <code>A</code>, the public key's associated private key type
|
||||
* <code>B</code> is parameterized as well. This ensures that any subsequent call to the builder's
|
||||
* {@link PublicJwkBuilder#setPrivateKey(PrivateKey) setPrivateKey} method will be type-safe. For example:</p>
|
||||
* {@link PublicJwkBuilder#privateKey(PrivateKey) privateKey} method will be type-safe. For example:</p>
|
||||
*
|
||||
* <blockquote><pre>Jwks.builder().<EdECPublicKey, <b>EdECPrivateKey</b>>forKey(anEdECPublicKey)
|
||||
* .setPrivateKey(<b>aPrivateKey</b>) // <-- must be an EdECPrivateKey instance
|
||||
* <blockquote><pre>Jwks.builder().<EdECPublicKey, <b>EdECPrivateKey</b>>key(anEdECPublicKey)
|
||||
* .privateKey(<b>aPrivateKey</b>) // <-- must be an EdECPrivateKey instance
|
||||
* ... etc ...
|
||||
* .build();</pre></blockquote>
|
||||
*
|
||||
|
@ -191,7 +271,7 @@ public interface ProtoJwkBuilder<K extends Key, J extends Jwk<K>> extends JwkBui
|
|||
* @see <a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/security/interfaces/XECPublicKey.html">java.security.interfaces.XECPublicKey</a>
|
||||
* @see <a href="https://docs.oracle.com/en/java/javase/15/docs/api/java.base/java/security/interfaces/EdECPublicKey.html">java.security.interfaces.EdECPublicKey</a>
|
||||
*/
|
||||
<A extends PublicKey, B extends PrivateKey> OctetPublicJwkBuilder<A, B> forOctetKey(A key);
|
||||
<A extends PublicKey, B extends PrivateKey> OctetPublicJwkBuilder<A, B> octetKey(A key);
|
||||
|
||||
/**
|
||||
* Ensures the builder will create an {@link OctetPrivateJwk} for the specified Edwards-curve {@code PrivateKey}
|
||||
|
@ -209,10 +289,10 @@ public interface ProtoJwkBuilder<K extends Key, J extends Jwk<K>> extends JwkBui
|
|||
*
|
||||
* <p>In addition to the private key type <code>B</code>, the private key's associated public key type
|
||||
* <code>A</code> is parameterized as well. This ensures that any subsequent call to the builder's
|
||||
* {@link PrivateJwkBuilder#setPublicKey(PublicKey) setPublicKey} method will be type-safe. For example:</p>
|
||||
* {@link PrivateJwkBuilder#publicKey(PublicKey) publicKey} method will be type-safe. For example:</p>
|
||||
*
|
||||
* <blockquote><pre>Jwks.builder().<<b>EdECPublicKey</b>, EdECPrivateKey>forKey(anEdECPrivateKey)
|
||||
* .setPublicKey(<b>aPublicKey</b>) // <-- must be an EdECPublicKey instance
|
||||
* <blockquote><pre>Jwks.builder().<<b>EdECPublicKey</b>, EdECPrivateKey>key(anEdECPrivateKey)
|
||||
* .publicKey(<b>aPublicKey</b>) // <-- must be an EdECPublicKey instance
|
||||
* ... etc ...
|
||||
* .build();</pre></blockquote>
|
||||
*
|
||||
|
@ -225,64 +305,38 @@ public interface ProtoJwkBuilder<K extends Key, J extends Jwk<K>> extends JwkBui
|
|||
* @see <a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/security/interfaces/XECPrivateKey.html">java.security.interfaces.XECPrivateKey</a>
|
||||
* @see <a href="https://docs.oracle.com/en/java/javase/15/docs/api/java.base/java/security/interfaces/EdECPrivateKey.html">java.security.interfaces.EdECPrivateKey</a>
|
||||
*/
|
||||
<A extends PrivateKey, B extends PublicKey> OctetPrivateJwkBuilder<A, B> forOctetKey(A key);
|
||||
|
||||
/**
|
||||
* Ensures the builder will create an {@link OctetPrivateJwk} for the specified Java Edwards-curve
|
||||
* {@link KeyPair}. The pair's {@link KeyPair#getPublic() public key} <em>MUST</em> be an
|
||||
* Edwards-curve public key as defined by {@link #forOctetKey(PublicKey)}. The pair's
|
||||
* {@link KeyPair#getPrivate() private key} <em>MUST</em> be an Edwards-curve private key as defined by
|
||||
* {@link #forOctetKey(PrivateKey)}.
|
||||
*
|
||||
* @param <A> the type of Edwards-curve {@link PublicKey} contained in the key pair.
|
||||
* @param <B> the type of the Edwards-curve {@link PrivateKey} contained in the key pair.
|
||||
* @param keyPair the Edwards-curve {@link KeyPair} to represent as an {@link OctetPrivateJwk}.
|
||||
* @return the builder coerced as an {@link OctetPrivateJwkBuilder} for continued method chaining.
|
||||
* @throws IllegalArgumentException if the {@code keyPair} does not contain Edwards-curve public and private key
|
||||
* instances.
|
||||
*/
|
||||
<A extends PrivateKey, B extends PublicKey> OctetPrivateJwkBuilder<A, B> forOctetKeyPair(KeyPair keyPair);
|
||||
<A extends PrivateKey, B extends PublicKey> OctetPrivateJwkBuilder<A, B> octetKey(A key);
|
||||
|
||||
/**
|
||||
* Ensures the builder will create an {@link OctetPublicJwk} for the specified Java {@link X509Certificate} chain.
|
||||
* The first {@code X509Certificate} in the chain (at list index 0) <em>MUST</em>
|
||||
* {@link X509Certificate#getPublicKey() contain} an Edwards-curve public key as defined by
|
||||
* {@link #forOctetKey(PublicKey)}.
|
||||
* {@link #octetKey(PublicKey)}.
|
||||
*
|
||||
* @param <A> the type of Edwards-curve {@link PublicKey} contained in the first {@code X509Certificate}.
|
||||
* @param <B> the type of Edwards-curve {@link PrivateKey} that may be paired with the {@link PublicKey} to produce
|
||||
* an {@link OctetPrivateJwk} if desired.
|
||||
* @param <A> the type of Edwards-curve {@link PublicKey} contained in the first {@code X509Certificate}.
|
||||
* @param <B> the type of Edwards-curve {@link PrivateKey} that may be paired with the {@link PublicKey} to produce
|
||||
* an {@link OctetPrivateJwk} if desired.
|
||||
* @param chain the {@link X509Certificate} chain to inspect to find the Edwards-curve {@code PublicKey} to
|
||||
* represent as an {@link OctetPublicJwk}.
|
||||
* @return the builder coerced as an {@link OctetPublicJwkBuilder} for continued method chaining.
|
||||
*/
|
||||
<A extends PublicKey, B extends PrivateKey> OctetPublicJwkBuilder<A, B> forOctetChain(List<X509Certificate> chain);
|
||||
<A extends PublicKey, B extends PrivateKey> OctetPublicJwkBuilder<A, B> octetChain(List<X509Certificate> chain);
|
||||
|
||||
/**
|
||||
* Ensures the builder will create an {@link OctetPublicJwk} for the specified Java {@link X509Certificate} chain.
|
||||
* The first {@code X509Certificate} in the chain (at array index 0) <em>MUST</em>
|
||||
* {@link X509Certificate#getPublicKey() contain} an Edwards-curve public key as defined by
|
||||
* {@link #forOctetKey(PublicKey)}.
|
||||
* Ensures the builder will create an {@link OctetPrivateJwk} for the specified Java Edwards-curve
|
||||
* {@link KeyPair}. The pair's {@link KeyPair#getPublic() public key} <em>MUST</em> be an
|
||||
* Edwards-curve public key as defined by {@link #octetKey(PublicKey)}. The pair's
|
||||
* {@link KeyPair#getPrivate() private key} <em>MUST</em> be an Edwards-curve private key as defined by
|
||||
* {@link #octetKey(PrivateKey)}.
|
||||
*
|
||||
* @param <A> the type of Edwards-curve {@link PublicKey} contained in the first {@code X509Certificate}.
|
||||
* @param <B> the type of Edwards-curve {@link PrivateKey} that may be paired with the {@link PublicKey} to produce
|
||||
* an {@link OctetPrivateJwk} if desired.
|
||||
* @param chain the {@link X509Certificate} chain to inspect to find the Edwards-curve {@code PublicKey} to
|
||||
* represent as an {@link OctetPublicJwk}.
|
||||
* @return the builder coerced as an {@link OctetPublicJwkBuilder} for continued method chaining.
|
||||
* @param <A> the type of Edwards-curve {@link PublicKey} contained in the key pair.
|
||||
* @param <B> the type of the Edwards-curve {@link PrivateKey} contained in the key pair.
|
||||
* @param keyPair the Edwards-curve {@link KeyPair} to represent as an {@link OctetPrivateJwk}.
|
||||
* @return the builder coerced as an {@link OctetPrivateJwkBuilder} for continued method chaining.
|
||||
* @throws IllegalArgumentException if the {@code keyPair} does not contain Edwards-curve public and private key
|
||||
* instances.
|
||||
*/
|
||||
<A extends PublicKey, B extends PrivateKey> OctetPublicJwkBuilder<A, B> forOctetChain(X509Certificate... chain);
|
||||
|
||||
/**
|
||||
* Ensures the builder will create an {@link EcPublicJwk} for the specified Java {@link X509Certificate} chain.
|
||||
* The first {@code X509Certificate} in the chain (at array index 0) <em>MUST</em> contain an {@link ECPublicKey}
|
||||
* instance when calling the certificate's {@link X509Certificate#getPublicKey() getPublicKey()} method.
|
||||
*
|
||||
* @param chain the {@link X509Certificate} chain to inspect to find the {@link ECPublicKey} to represent as a
|
||||
* {@link EcPublicJwk}.
|
||||
* @return the builder coerced as an {@link EcPublicJwkBuilder}.
|
||||
*/
|
||||
EcPublicJwkBuilder forEcChain(X509Certificate... chain);
|
||||
<A extends PrivateKey, B extends PublicKey> OctetPrivateJwkBuilder<A, B> octetKeyPair(KeyPair keyPair);
|
||||
|
||||
/**
|
||||
* Ensures the builder will create an {@link EcPublicJwk} for the specified Java {@link X509Certificate} chain.
|
||||
|
@ -293,7 +347,7 @@ public interface ProtoJwkBuilder<K extends Key, J extends Jwk<K>> extends JwkBui
|
|||
* {@link EcPublicJwk}.
|
||||
* @return the builder coerced as an {@link EcPublicJwkBuilder}.
|
||||
*/
|
||||
EcPublicJwkBuilder forEcChain(List<X509Certificate> chain);
|
||||
EcPublicJwkBuilder ecChain(List<X509Certificate> chain);
|
||||
|
||||
/**
|
||||
* Ensures the builder will create an {@link EcPrivateJwk} for the specified Java Elliptic Curve
|
||||
|
@ -306,18 +360,7 @@ public interface ProtoJwkBuilder<K extends Key, J extends Jwk<K>> extends JwkBui
|
|||
* @throws IllegalArgumentException if the {@code keyPair} does not contain {@link ECPublicKey} and
|
||||
* {@link ECPrivateKey} instances.
|
||||
*/
|
||||
EcPrivateJwkBuilder forEcKeyPair(KeyPair keyPair) throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Ensures the builder will create an {@link RsaPublicJwk} for the specified Java {@link X509Certificate} chain.
|
||||
* The first {@code X509Certificate} in the chain (at array index 0) <em>MUST</em> contain an {@link RSAPublicKey}
|
||||
* instance when calling the certificate's {@link X509Certificate#getPublicKey() getPublicKey()} method.
|
||||
*
|
||||
* @param chain the {@link X509Certificate} chain to inspect to find the {@link RSAPublicKey} to represent as a
|
||||
* {@link RsaPublicJwk}.
|
||||
* @return the builder coerced as an {@link RsaPublicJwkBuilder}.
|
||||
*/
|
||||
RsaPublicJwkBuilder forRsaChain(X509Certificate... chain);
|
||||
EcPrivateJwkBuilder ecKeyPair(KeyPair keyPair) throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Ensures the builder will create an {@link RsaPublicJwk} for the specified Java {@link X509Certificate} chain.
|
||||
|
@ -328,7 +371,7 @@ public interface ProtoJwkBuilder<K extends Key, J extends Jwk<K>> extends JwkBui
|
|||
* {@link RsaPublicJwk}.
|
||||
* @return the builder coerced as an {@link RsaPublicJwkBuilder}.
|
||||
*/
|
||||
RsaPublicJwkBuilder forRsaChain(List<X509Certificate> chain);
|
||||
RsaPublicJwkBuilder rsaChain(List<X509Certificate> chain);
|
||||
|
||||
/**
|
||||
* Ensures the builder will create an {@link RsaPrivateJwk} for the specified Java RSA
|
||||
|
@ -341,5 +384,5 @@ public interface ProtoJwkBuilder<K extends Key, J extends Jwk<K>> extends JwkBui
|
|||
* @throws IllegalArgumentException if the {@code keyPair} does not contain {@link RSAPublicKey} and
|
||||
* {@link RSAPrivateKey} instances.
|
||||
*/
|
||||
RsaPrivateJwkBuilder forRsaKeyPair(KeyPair keyPair) throws IllegalArgumentException;
|
||||
RsaPrivateJwkBuilder rsaKeyPair(KeyPair keyPair) throws IllegalArgumentException;
|
||||
}
|
|
@ -57,7 +57,7 @@ public interface JwkBuilder<K extends Key, J extends Jwk<K>, T extends JwkBuilde
|
|||
* @return the builder for method chaining.
|
||||
* @throws IllegalArgumentException if {@code alg} is {@code null} or empty.
|
||||
*/
|
||||
T setAlgorithm(String alg) throws IllegalArgumentException;
|
||||
T algorithm(String alg) throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Sets the JWK <a href="https://www.rfc-editor.org/rfc/rfc7517.html#section-4.5">{@code kid} (Key ID)
|
||||
|
@ -77,22 +77,22 @@ public interface JwkBuilder<K extends Key, J extends Jwk<K>, T extends JwkBuilde
|
|||
* @return the builder for method chaining.
|
||||
* @throws IllegalArgumentException if the argument is {@code null} or empty.
|
||||
*/
|
||||
T setId(String kid) throws IllegalArgumentException;
|
||||
T id(String kid) throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Sets the JWK's {@link #setId(String) kid} value to be the Base64URL-encoding of its {@code SHA-256}
|
||||
* Sets the JWK's {@link #id(String) kid} value to be the Base64URL-encoding of its {@code SHA-256}
|
||||
* {@link Jwk#thumbprint(HashAlgorithm) thumbprint}. That is, the constructed JWK's {@code kid} value will equal
|
||||
* <code>jwk.{@link Jwk#thumbprint(HashAlgorithm) thumbprint}({@link Jwks.HASH}.{@link Jwks.HASH#SHA256 SHA256}).{@link JwkThumbprint#toString() toString()}</code>.
|
||||
*
|
||||
* <p>This is a convenience method that delegates to {@link #setIdFromThumbprint(HashAlgorithm)} using
|
||||
* <p>This is a convenience method that delegates to {@link #idFromThumbprint(HashAlgorithm)} using
|
||||
* {@link Jwks.HASH}{@code .}{@link Jwks.HASH#SHA256 SHA256}.</p>
|
||||
*
|
||||
* @return the builder for method chaining.
|
||||
*/
|
||||
T setIdFromThumbprint();
|
||||
T idFromThumbprint();
|
||||
|
||||
/**
|
||||
* Sets the JWK's {@link #setId(String) kid} value to be the Base64URL-encoding of its
|
||||
* Sets the JWK's {@link #id(String) kid} value to be the Base64URL-encoding of its
|
||||
* {@link Jwk#thumbprint(HashAlgorithm) thumbprint} using the specified {@link HashAlgorithm}. That is, the
|
||||
* constructed JWK's {@code kid} value will equal
|
||||
* <code>{@link Jwk#thumbprint(HashAlgorithm) thumbprint}(alg).{@link JwkThumbprint#toString() toString()}.</code>
|
||||
|
@ -101,7 +101,7 @@ public interface JwkBuilder<K extends Key, J extends Jwk<K>, T extends JwkBuilde
|
|||
* @return the builder for method chaining.
|
||||
* @see Jwks.HASH
|
||||
*/
|
||||
T setIdFromThumbprint(HashAlgorithm alg);
|
||||
T idFromThumbprint(HashAlgorithm alg);
|
||||
|
||||
/**
|
||||
* Sets the JWK <a href="https://www.rfc-editor.org/rfc/rfc7517.html#section-4.3">{@code key_ops}
|
||||
|
@ -174,5 +174,5 @@ public interface JwkBuilder<K extends Key, J extends Jwk<K>, T extends JwkBuilde
|
|||
* @return the builder for method chaining.
|
||||
* @throws IllegalArgumentException if {@code ops} is {@code null} or empty.
|
||||
*/
|
||||
T setOperations(Set<String> ops) throws IllegalArgumentException;
|
||||
T operations(Set<String> ops) throws IllegalArgumentException;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ import java.util.Map;
|
|||
* A builder to construct a {@link JwkParser}. Example usage:
|
||||
* <blockquote><pre>
|
||||
* Jwk<?> jwk = Jwks.parser()
|
||||
* .setProvider(aJcaProvider) // optional
|
||||
* .provider(aJcaProvider) // optional
|
||||
* .deserializeJsonWith(deserializer) // optional
|
||||
* .build()
|
||||
* .parse(jwkString);</pre></blockquote>
|
||||
|
@ -42,7 +42,7 @@ public interface JwkParserBuilder extends Builder<JwkParser> {
|
|||
* if the JCA subsystem preferred provider should be used.
|
||||
* @return the builder for method chaining.
|
||||
*/
|
||||
JwkParserBuilder setProvider(Provider provider);
|
||||
JwkParserBuilder provider(Provider provider);
|
||||
|
||||
/**
|
||||
* Uses the specified deserializer to convert JSON Strings (UTF-8 byte arrays) into Java Map objects. The
|
||||
|
|
|
@ -40,7 +40,7 @@ public final class Jwks {
|
|||
private Jwks() {
|
||||
} //prevent instantiation
|
||||
|
||||
private static final String BUILDER_CLASSNAME = "io.jsonwebtoken.impl.security.DefaultProtoJwkBuilder";
|
||||
private static final String BUILDER_CLASSNAME = "io.jsonwebtoken.impl.security.DefaultDynamicJwkBuilder";
|
||||
|
||||
private static final String PARSERBUILDER_CLASSNAME = "io.jsonwebtoken.impl.security.DefaultJwkParserBuilder";
|
||||
|
||||
|
@ -54,7 +54,7 @@ public final class Jwks {
|
|||
* <blockquote><pre>
|
||||
* Jwks.{@link Jwks#builder}()
|
||||
* // ... etc ...
|
||||
* .{@link JwkBuilder#setIdFromThumbprint(HashAlgorithm) setIdFromThumbprint}(Jwts.HASH.{@link Jwks.HASH#SHA256 SHA256}) // <---
|
||||
* .{@link JwkBuilder#idFromThumbprint(HashAlgorithm) idFromThumbprint}(Jwts.HASH.{@link Jwks.HASH#SHA256 SHA256}) // <---
|
||||
* .build()</pre></blockquote>
|
||||
* <p>or</p>
|
||||
* <blockquote><pre>
|
||||
|
@ -152,7 +152,7 @@ public final class Jwks {
|
|||
*
|
||||
* @return a new JWK builder instance, allowing for type-safe JWK builder coercion based on a provided key or key pair.
|
||||
*/
|
||||
public static ProtoJwkBuilder<?, ?> builder() {
|
||||
public static DynamicJwkBuilder<?, ?> builder() {
|
||||
return Classes.newInstance(BUILDER_CLASSNAME);
|
||||
}
|
||||
|
||||
|
|
|
@ -22,8 +22,8 @@ import java.security.Key;
|
|||
* their associated cryptographic algorithm implementation.
|
||||
*
|
||||
* @param <K> type of {@link Key} created by the builder
|
||||
* @param <B> type of builder to create each time {@link #keyBuilder()} is called.
|
||||
* @see #keyBuilder()
|
||||
* @param <B> type of builder to create each time {@link #key()} is called.
|
||||
* @see #key()
|
||||
* @see KeyBuilder
|
||||
* @since JJWT_RELEASE_VERSION
|
||||
*/
|
||||
|
@ -36,5 +36,5 @@ public interface KeyBuilderSupplier<K extends Key, B extends KeyBuilder<K, B>> {
|
|||
* @return a new {@link KeyBuilder} instance that will produce new secure-random keys with a length sufficient
|
||||
* to be used by the component's associated cryptographic algorithm.
|
||||
*/
|
||||
B keyBuilder();
|
||||
B key();
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ import java.security.KeyPair;
|
|||
* Interface implemented by components that support building/creating new {@link KeyPair}s suitable for use with their
|
||||
* associated cryptographic algorithm implementation.
|
||||
*
|
||||
* @see #keyPairBuilder()
|
||||
* @see #keyPair()
|
||||
* @see KeyPairBuilder
|
||||
* @since JJWT_RELEASE_VERSION
|
||||
*/
|
||||
|
@ -34,5 +34,5 @@ public interface KeyPairBuilderSupplier {
|
|||
* @return a new {@link KeyPairBuilder} that will create new secure-random {@link KeyPair}s with a length and
|
||||
* parameters sufficient for use with the component's associated cryptographic algorithm.
|
||||
*/
|
||||
KeyPairBuilder keyPairBuilder();
|
||||
KeyPairBuilder keyPair();
|
||||
}
|
||||
|
|
|
@ -49,8 +49,7 @@ public interface KeyRequest<T> extends Request<T> {
|
|||
* {@code KeyRequest}. {@link KeyAlgorithm} implementations that generate an ephemeral {@code SecretKey} to use
|
||||
* as what the <a href="https://www.rfc-editor.org/rfc/rfc7516.html#section-2">JWE specification calls</a> a
|
||||
* "Content Encryption Key (CEK)" should call the {@code AeadAlgorithm}'s
|
||||
* {@link AeadAlgorithm#keyBuilder() keyBuilder()} to obtain a builder that will create a key suitable for that
|
||||
* exact {@code AeadAlgorithm}.
|
||||
* {@link AeadAlgorithm#key() key()} builder to create a key suitable for that exact {@code AeadAlgorithm}.
|
||||
*
|
||||
* @return the {@link AeadAlgorithm} that will be called for encryption or decryption after processing the
|
||||
* {@code KeyRequest}.
|
||||
|
|
|
@ -68,8 +68,8 @@ public final class Keys {
|
|||
"is not secure enough for any JWT HMAC-SHA algorithm. The JWT " +
|
||||
"JWA Specification (RFC 7518, Section 3.2) states that keys used with HMAC-SHA algorithms MUST have a " +
|
||||
"size >= 256 bits (the key size must be greater than or equal to the hash " +
|
||||
"output size). Consider using the Jwts.SIG.HS256.keyBuilder() method (or HS384.keyBuilder() " +
|
||||
"or HS512.keyBuilder()) to create a key guaranteed to be secure enough for your preferred HMAC-SHA " +
|
||||
"output size). Consider using the Jwts.SIG.HS256.key() builder (or HS384.key() " +
|
||||
"or HS512.key()) to create a key guaranteed to be secure enough for your preferred HMAC-SHA " +
|
||||
"algorithm. See https://tools.ietf.org/html/rfc7518#section-3.2 for more information.";
|
||||
throw new WeakKeyException(msg);
|
||||
}
|
||||
|
@ -78,12 +78,12 @@ public final class Keys {
|
|||
* <p><b>Deprecation Notice</b></p>
|
||||
*
|
||||
* <p>As of JJWT JJWT_RELEASE_VERSION, symmetric (secret) key algorithm instances can generate a key of suitable
|
||||
* length for that specific algorithm by calling their {@code keyBuilder()} method directly. For example:</p>
|
||||
* length for that specific algorithm by calling their {@code key()} builder method directly. For example:</p>
|
||||
*
|
||||
* <pre><code>
|
||||
* {@link Jwts.SIG#HS256}.keyBuilder().build();
|
||||
* {@link Jwts.SIG#HS384}.keyBuilder().build();
|
||||
* {@link Jwts.SIG#HS512}.keyBuilder().build();
|
||||
* {@link Jwts.SIG#HS256}.key().build();
|
||||
* {@link Jwts.SIG#HS384}.key().build();
|
||||
* {@link Jwts.SIG#HS512}.key().build();
|
||||
* </code></pre>
|
||||
*
|
||||
* <p>Call those methods as needed instead of this static {@code secretKeyFor} helper method - the returned
|
||||
|
@ -124,7 +124,7 @@ public final class Keys {
|
|||
* @throws IllegalArgumentException for any input value other than {@link io.jsonwebtoken.SignatureAlgorithm#HS256},
|
||||
* {@link io.jsonwebtoken.SignatureAlgorithm#HS384}, or {@link io.jsonwebtoken.SignatureAlgorithm#HS512}
|
||||
* @deprecated since JJWT_RELEASE_VERSION. Use your preferred {@link MacAlgorithm} instance's
|
||||
* {@link MacAlgorithm#keyBuilder() keyBuilder()} method directly.
|
||||
* {@link MacAlgorithm#key() key()} builder method directly.
|
||||
*/
|
||||
@SuppressWarnings("DeprecatedIsStillUsed")
|
||||
@Deprecated
|
||||
|
@ -135,21 +135,21 @@ public final class Keys {
|
|||
String msg = "The " + alg.name() + " algorithm does not support shared secret keys.";
|
||||
throw new IllegalArgumentException(msg);
|
||||
}
|
||||
return ((MacAlgorithm) salg).keyBuilder().build();
|
||||
return ((MacAlgorithm) salg).key().build();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p><b>Deprecation Notice</b></p>
|
||||
*
|
||||
* <p>As of JJWT JJWT_RELEASE_VERSION, asymmetric key algorithm instances can generate KeyPairs of suitable strength
|
||||
* for that specific algorithm by calling their {@code keyPairBuilder()} method directly. For example:</p>
|
||||
* for that specific algorithm by calling their {@code keyPair()} builder method directly. For example:</p>
|
||||
*
|
||||
* <blockquote><pre>
|
||||
* Jwts.SIG.{@link Jwts.SIG#RS256 RS256}.keyPairBuilder().build();
|
||||
* Jwts.SIG.{@link Jwts.SIG#RS384 RS384}.keyPairBuilder().build();
|
||||
* Jwts.SIG.{@link Jwts.SIG#RS512 RS512}.keyPairBuilder().build();
|
||||
* Jwts.SIG.{@link Jwts.SIG#RS256 RS256}.keyPair().build();
|
||||
* Jwts.SIG.{@link Jwts.SIG#RS384 RS384}.keyPair().build();
|
||||
* Jwts.SIG.{@link Jwts.SIG#RS512 RS512}.keyPair().build();
|
||||
* ... etc ...
|
||||
* Jwts.SIG.{@link Jwts.SIG#ES512 ES512}.keyPairBuilder().build();</pre></blockquote>
|
||||
* Jwts.SIG.{@link Jwts.SIG#ES512 ES512}.keyPair().build();</pre></blockquote>
|
||||
*
|
||||
* <p>Call those methods as needed instead of this static {@code keyPairFor} helper method - the returned
|
||||
* {@link KeyPairBuilder} allows callers to specify a preferred Provider or SecureRandom on the builder if
|
||||
|
@ -229,7 +229,7 @@ public final class Keys {
|
|||
* @throws IllegalArgumentException if {@code alg} is not an asymmetric algorithm
|
||||
* @deprecated since JJWT_RELEASE_VERSION in favor of your preferred
|
||||
* {@link io.jsonwebtoken.security.SignatureAlgorithm} instance's
|
||||
* {@link SignatureAlgorithm#keyPairBuilder() keyPairBuilder()} method directly.
|
||||
* {@link SignatureAlgorithm#keyPair() keyPair()} builder method directly.
|
||||
*/
|
||||
@SuppressWarnings("DeprecatedIsStillUsed")
|
||||
@Deprecated
|
||||
|
@ -241,7 +241,7 @@ public final class Keys {
|
|||
throw new IllegalArgumentException(msg);
|
||||
}
|
||||
SignatureAlgorithm asalg = ((SignatureAlgorithm) salg);
|
||||
return asalg.keyPairBuilder().build();
|
||||
return asalg.keyPair().build();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -264,7 +264,7 @@ public final class Keys {
|
|||
* @see Password#toCharArray()
|
||||
* @since JJWT_RELEASE_VERSION
|
||||
*/
|
||||
public static Password forPassword(char[] password) {
|
||||
return Classes.invokeStatic(BRIDGE_CLASS, "forPassword", FOR_PASSWORD_ARG_TYPES, new Object[]{password});
|
||||
public static Password password(char[] password) {
|
||||
return Classes.invokeStatic(BRIDGE_CLASS, "password", FOR_PASSWORD_ARG_TYPES, new Object[]{password});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ import javax.crypto.SecretKey;
|
|||
* have a sufficient length and any algorithm parameters required by that algorithm. For example:</p>
|
||||
*
|
||||
* <blockquote><pre>
|
||||
* SecretKey key = macAlgorithm.keyBuilder().build();</pre></blockquote>
|
||||
* SecretKey key = macAlgorithm.key().build();</pre></blockquote>
|
||||
*
|
||||
* <p>The resulting {@code key} is guaranteed to have the correct algorithm parameters and strength/length necessary for
|
||||
* that exact {@code MacAlgorithm} instance.</p>
|
||||
|
|
|
@ -26,7 +26,7 @@ import java.security.PublicKey;
|
|||
* @param <M> the type of {@link PrivateJwk} created
|
||||
* @param <J> the type of {@link PublicJwk} paired with the created private JWK.
|
||||
* @param <T> the type of the builder, for subtype method chaining
|
||||
* @see #setPublicKey(PublicKey)
|
||||
* @see #publicKey(PublicKey)
|
||||
* @since JJWT_RELEASE_VERSION
|
||||
*/
|
||||
public interface PrivateJwkBuilder<K extends PrivateKey, L extends PublicKey,
|
||||
|
@ -40,7 +40,7 @@ public interface PrivateJwkBuilder<K extends PrivateKey, L extends PublicKey,
|
|||
*
|
||||
* <p>As discussed in the {@link PrivateJwk} documentation, the JWK and JWA specifications require private JWKs to
|
||||
* contain <em>both</em> private key <em>and</em> public key data. If a public key is not provided via this
|
||||
* {@code setPublicKey} method, the builder implementation must go through the work to derive the
|
||||
* {@code publicKey} method, the builder implementation must go through the work to derive the
|
||||
* {@code PublicKey} instance based on the {@code PrivateKey} to obtain the necessary public key information.</p>
|
||||
*
|
||||
* <p>Calling this method with the {@code PrivateKey}'s matching {@code PublicKey} instance eliminates the need
|
||||
|
@ -49,5 +49,5 @@ public interface PrivateJwkBuilder<K extends PrivateKey, L extends PublicKey,
|
|||
* @param publicKey the {@link PublicKey} that matches the builder's existing {@link PrivateKey}.
|
||||
* @return the builder for method chaining.
|
||||
*/
|
||||
T setPublicKey(L publicKey);
|
||||
T publicKey(L publicKey);
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ import java.security.PublicKey;
|
|||
* @param <M> the type of {@link PrivateJwk} that matches the created {@link PublicJwk}
|
||||
* @param <P> the type of {@link PrivateJwkBuilder} that matches this builder if a {@link PrivateJwk} is desired.
|
||||
* @param <T> the type of the builder, for subtype method chaining
|
||||
* @see #setPrivateKey(PrivateKey)
|
||||
* @see #privateKey(PrivateKey)
|
||||
* @since JJWT_RELEASE_VERSION
|
||||
*/
|
||||
public interface PublicJwkBuilder<K extends PublicKey, L extends PrivateKey,
|
||||
|
@ -43,5 +43,5 @@ public interface PublicJwkBuilder<K extends PublicKey, L extends PrivateKey,
|
|||
* @param privateKey the {@link PrivateKey} that pairs with the builder's existing {@link PublicKey}
|
||||
* @return the builder coerced as a {@link PrivateJwkBuilder} which will produce a corresponding {@link PrivateJwk}.
|
||||
*/
|
||||
P setPrivateKey(L privateKey);
|
||||
P privateKey(L privateKey);
|
||||
}
|
||||
|
|
|
@ -25,8 +25,8 @@ import java.security.SecureRandom;
|
|||
* during instance creation, such as a {@link java.security.Provider} or {@link java.security.SecureRandom}.
|
||||
*
|
||||
* @param <T> The type of object that will be created each time {@link #build()} is invoked.
|
||||
* @see #setProvider(Provider)
|
||||
* @see #setRandom(SecureRandom)
|
||||
* @see #provider(Provider)
|
||||
* @see #random(SecureRandom)
|
||||
* @since JJWT_RELEASE_VERSION
|
||||
*/
|
||||
public interface SecurityBuilder<T, B extends SecurityBuilder<T, B>> extends Builder<T> {
|
||||
|
@ -38,7 +38,7 @@ public interface SecurityBuilder<T, B extends SecurityBuilder<T, B>> extends Bui
|
|||
* @param provider the JCA Security Provider instance to use if necessary when building the new instance.
|
||||
* @return the builder for method chaining.
|
||||
*/
|
||||
B setProvider(Provider provider);
|
||||
B provider(Provider provider);
|
||||
|
||||
/**
|
||||
* Sets the {@link SecureRandom} to use if necessary when calling {@link #build()}. This is an optional property
|
||||
|
@ -47,5 +47,5 @@ public interface SecurityBuilder<T, B extends SecurityBuilder<T, B>> extends Bui
|
|||
* @param random the {@link SecureRandom} instance to use if necessary when building the new instance.
|
||||
* @return the builder for method chaining.
|
||||
*/
|
||||
B setRandom(SecureRandom random);
|
||||
B random(SecureRandom random);
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ import java.security.PublicKey;
|
|||
* required by that algorithm. For example:</p>
|
||||
*
|
||||
* <blockquote><pre>
|
||||
* KeyPair pair = signatureAlgorithm.keyPairBuilder().build();</pre></blockquote>
|
||||
* KeyPair pair = signatureAlgorithm.keyPair().build();</pre></blockquote>
|
||||
*
|
||||
* <p>The resulting {@code pair} is guaranteed to have the correct algorithm parameters and length/strength necessary
|
||||
* for that exact {@code signatureAlgorithm} instance.</p>
|
||||
|
|
|
@ -28,8 +28,8 @@ public interface X509Builder<T extends X509Builder<T>> extends X509Mutator<T> {
|
|||
|
||||
/**
|
||||
* If the {@code enable} argument is {@code true}, compute the SHA-1 thumbprint of the first
|
||||
* {@link X509Certificate} in the configured {@link #setX509CertificateChain(List) x509CertificateChain}, and set
|
||||
* the resulting value as the {@link #setX509CertificateSha1Thumbprint(byte[])} parameter.
|
||||
* {@link X509Certificate} in the configured {@link #x509CertificateChain(List) x509CertificateChain}, and set
|
||||
* the resulting value as the {@link #x509CertificateSha1Thumbprint(byte[])} parameter.
|
||||
*
|
||||
* <p>If no chain has been configured, or {@code enable} is {@code false}, the builder will not compute nor add a
|
||||
* {@code x5t} value.</p>
|
||||
|
@ -42,8 +42,8 @@ public interface X509Builder<T extends X509Builder<T>> extends X509Mutator<T> {
|
|||
|
||||
/**
|
||||
* If the {@code enable} argument is {@code true}, compute the SHA-256 thumbprint of the first
|
||||
* {@link X509Certificate} in the configured {@link #setX509CertificateChain(List) x509CertificateChain}, and set
|
||||
* the resulting value as the {@link #setX509CertificateSha256Thumbprint(byte[])} parameter.
|
||||
* {@link X509Certificate} in the configured {@link #x509CertificateChain(List) x509CertificateChain}, and set
|
||||
* the resulting value as the {@link #x509CertificateSha256Thumbprint(byte[])} parameter.
|
||||
*
|
||||
* <p>If no chain has been configured, or {@code enable} is {@code false}, the builder will not compute nor add a
|
||||
* {@code x5t#S256} value.</p>
|
||||
|
|
|
@ -62,7 +62,7 @@ public interface X509Mutator<T extends X509Mutator<T>> {
|
|||
* @see <a href="https://www.rfc-editor.org/rfc/rfc7515.html#section-4.1.5">JWS <code>x5u</code> (X.509 URL) Header Parameter</a>
|
||||
* @see <a href="https://www.rfc-editor.org/rfc/rfc7516.html#section-4.1.7">JWE <code>x5u</code> (X.509 URL) Header Parameter</a>
|
||||
*/
|
||||
T setX509Url(URI uri);
|
||||
T x509Url(URI uri);
|
||||
|
||||
/**
|
||||
* Sets the {@code x5c} (X.509 Certificate Chain) of the associated JWT or JWK. A {@code null} value will remove the
|
||||
|
@ -85,7 +85,7 @@ public interface X509Mutator<T extends X509Mutator<T>> {
|
|||
* @see <a href="https://www.rfc-editor.org/rfc/rfc7515.html#section-4.1.6">JWS <code>x5c</code> (X.509 Certificate Chain) Header Parameter</a>
|
||||
* @see <a href="https://www.rfc-editor.org/rfc/rfc7516.html#section-4.1.8">JWE <code>x5c</code> (X.509 Certificate Chain) Header Parameter</a>
|
||||
*/
|
||||
T setX509CertificateChain(List<X509Certificate> chain);
|
||||
T x509CertificateChain(List<X509Certificate> chain);
|
||||
|
||||
/**
|
||||
* Sets the {@code x5t} (X.509 Certificate SHA-1 Thumbprint) (a.k.a. digest) of the DER-encoding of the
|
||||
|
@ -111,7 +111,7 @@ public interface X509Mutator<T extends X509Mutator<T>> {
|
|||
* @see <a href="https://www.rfc-editor.org/rfc/rfc7515.html#section-4.1.7">JWS <code>x5t</code> (X.509 Certificate SHA-1 Thumbprint) Header Parameter</a>
|
||||
* @see <a href="https://www.rfc-editor.org/rfc/rfc7516.html#section-4.1.9">JWE <code>x5t</code> (X.509 Certificate SHA-1 Thumbprint) Header Parameter</a>
|
||||
*/
|
||||
T setX509CertificateSha1Thumbprint(byte[] thumbprint);
|
||||
T x509CertificateSha1Thumbprint(byte[] thumbprint);
|
||||
|
||||
/**
|
||||
* Sets the {@code x5t#S256} (X.509 Certificate SHA-256 Thumbprint) (a.k.a. digest) of the DER-encoding of the
|
||||
|
@ -137,5 +137,5 @@ public interface X509Mutator<T extends X509Mutator<T>> {
|
|||
* @see <a href="https://www.rfc-editor.org/rfc/rfc7515.html#section-4.1.8">JWS <code>x5t#S256</code> (X.509 Certificate SHA-256 Thumbprint) Header Parameter</a>
|
||||
* @see <a href="https://www.rfc-editor.org/rfc/rfc7516.html#section-4.1.10">JWE <code>x5t#S256</code> (X.509 Certificate SHA-256 Thumbprint) Header Parameter</a>
|
||||
*/
|
||||
T setX509CertificateSha256Thumbprint(byte[] thumbprint);
|
||||
T x509CertificateSha256Thumbprint(byte[] thumbprint);
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ public class AbstractX509Context<T extends X509Mutator<T>> extends FieldMap impl
|
|||
}
|
||||
|
||||
@Override
|
||||
public T setX509Url(URI uri) {
|
||||
public T x509Url(URI uri) {
|
||||
put(AbstractAsymmetricJwk.X5U, uri);
|
||||
return self();
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ public class AbstractX509Context<T extends X509Mutator<T>> extends FieldMap impl
|
|||
}
|
||||
|
||||
@Override
|
||||
public T setX509CertificateChain(List<X509Certificate> chain) {
|
||||
public T x509CertificateChain(List<X509Certificate> chain) {
|
||||
put(AbstractAsymmetricJwk.X5C, chain);
|
||||
return self();
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ public class AbstractX509Context<T extends X509Mutator<T>> extends FieldMap impl
|
|||
}
|
||||
|
||||
@Override
|
||||
public T setX509CertificateSha1Thumbprint(byte[] thumbprint) {
|
||||
public T x509CertificateSha1Thumbprint(byte[] thumbprint) {
|
||||
put(AbstractAsymmetricJwk.X5T, thumbprint);
|
||||
return self();
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ public class AbstractX509Context<T extends X509Mutator<T>> extends FieldMap impl
|
|||
}
|
||||
|
||||
@Override
|
||||
public T setX509CertificateSha256Thumbprint(byte[] thumbprint) {
|
||||
public T x509CertificateSha256Thumbprint(byte[] thumbprint) {
|
||||
put(AbstractAsymmetricJwk.X5T_S256, thumbprint);
|
||||
return self();
|
||||
}
|
||||
|
|
|
@ -17,60 +17,16 @@ package io.jsonwebtoken.impl;
|
|||
|
||||
import io.jsonwebtoken.Claims;
|
||||
import io.jsonwebtoken.ClaimsBuilder;
|
||||
import io.jsonwebtoken.impl.lang.DelegatingMapMutator;
|
||||
import io.jsonwebtoken.impl.lang.Field;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @since JJWT_RELEASE_VERSION
|
||||
*/
|
||||
@SuppressWarnings("unused") // used via reflection via Jwts.claims()
|
||||
public final class DefaultClaimsBuilder extends DelegatingMapMutator<String, Object, FieldMap, ClaimsBuilder>
|
||||
public final class DefaultClaimsBuilder extends DelegatingClaimsMutator<ClaimsBuilder>
|
||||
implements ClaimsBuilder {
|
||||
|
||||
public DefaultClaimsBuilder() {
|
||||
super(new FieldMap(DefaultClaims.FIELDS));
|
||||
}
|
||||
|
||||
<T> ClaimsBuilder put(Field<T> field, Object value) {
|
||||
this.DELEGATE.put(field, value);
|
||||
return self();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClaimsBuilder setIssuer(String iss) {
|
||||
return put(DefaultClaims.ISSUER, iss);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClaimsBuilder setSubject(String sub) {
|
||||
return put(DefaultClaims.SUBJECT, sub);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClaimsBuilder setAudience(String aud) {
|
||||
return put(DefaultClaims.AUDIENCE, aud);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClaimsBuilder setExpiration(Date exp) {
|
||||
return put(DefaultClaims.EXPIRATION, exp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClaimsBuilder setNotBefore(Date nbf) {
|
||||
return put(DefaultClaims.NOT_BEFORE, nbf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClaimsBuilder setIssuedAt(Date iat) {
|
||||
return put(DefaultClaims.ISSUED_AT, iat);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClaimsBuilder setId(String jti) {
|
||||
return put(DefaultClaims.JTI, jti);
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -29,8 +29,8 @@ public class DefaultJwe<P> extends DefaultProtectedJwt<JweHeader, P> implements
|
|||
|
||||
private final byte[] iv;
|
||||
|
||||
public DefaultJwe(JweHeader header, P body, byte[] iv, byte[] aadTag) {
|
||||
super(header, body, aadTag, DIGEST_NAME);
|
||||
public DefaultJwe(JweHeader header, P payload, byte[] iv, byte[] aadTag) {
|
||||
super(header, payload, aadTag, DIGEST_NAME);
|
||||
this.iv = Assert.notEmpty(iv, "Initialization vector cannot be null or empty.");
|
||||
}
|
||||
|
||||
|
|
|
@ -67,21 +67,31 @@ public class DefaultJweHeaderMutator<T extends JweHeaderMutator<T>>
|
|||
// JWT Header methods
|
||||
// =============================================================
|
||||
|
||||
@Override
|
||||
public T setAlgorithm(String alg) {
|
||||
return put(DefaultHeader.ALGORITHM, alg);
|
||||
}
|
||||
// @Override
|
||||
// public T algorithm(String alg) {
|
||||
// return put(DefaultHeader.ALGORITHM, alg);
|
||||
// }
|
||||
|
||||
@Override
|
||||
public T setContentType(String cty) {
|
||||
public T contentType(String cty) {
|
||||
return put(DefaultHeader.CONTENT_TYPE, cty);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T setType(String typ) {
|
||||
public T type(String typ) {
|
||||
return put(DefaultHeader.TYPE, typ);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T setType(String typ) {
|
||||
return type(typ);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T setContentType(String cty) {
|
||||
return contentType(cty);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T setCompressionAlgorithm(String zip) {
|
||||
return put(DefaultHeader.COMPRESSION_ALGORITHM, zip);
|
||||
|
@ -92,51 +102,60 @@ public class DefaultJweHeaderMutator<T extends JweHeaderMutator<T>>
|
|||
// =============================================================
|
||||
|
||||
@Override
|
||||
public T setJwkSetUrl(URI uri) {
|
||||
return put(DefaultProtectedHeader.JKU, uri);
|
||||
public T critical(Set<String> crit) {
|
||||
return put(DefaultProtectedHeader.CRIT, crit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T setJwk(PublicJwk<?> jwk) {
|
||||
public T jwk(PublicJwk<?> jwk) {
|
||||
return put(DefaultProtectedHeader.JWK, jwk);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T setKeyId(String kid) {
|
||||
public T jwkSetUrl(URI uri) {
|
||||
return put(DefaultProtectedHeader.JKU, uri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T keyId(String kid) {
|
||||
return put(DefaultProtectedHeader.KID, kid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T setCritical(Set<String> crit) {
|
||||
return put(DefaultProtectedHeader.CRIT, crit);
|
||||
public T setKeyId(String kid) {
|
||||
return keyId(kid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T setAlgorithm(String alg) {
|
||||
return put(DefaultHeader.ALGORITHM, alg);
|
||||
}
|
||||
|
||||
// =============================================================
|
||||
// X.509 methods
|
||||
// =============================================================
|
||||
|
||||
@Override
|
||||
public T setX509Url(URI uri) {
|
||||
this.x509.setX509Url(uri);
|
||||
public T x509Url(URI uri) {
|
||||
this.x509.x509Url(uri);
|
||||
return self();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T setX509CertificateChain(List<X509Certificate> chain) {
|
||||
this.x509.setX509CertificateChain(chain);
|
||||
public T x509CertificateChain(List<X509Certificate> chain) {
|
||||
this.x509.x509CertificateChain(chain);
|
||||
return self();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T setX509CertificateSha1Thumbprint(byte[] thumbprint) {
|
||||
this.x509.setX509CertificateSha1Thumbprint(thumbprint);
|
||||
public T x509CertificateSha1Thumbprint(byte[] thumbprint) {
|
||||
this.x509.x509CertificateSha1Thumbprint(thumbprint);
|
||||
return self();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T setX509CertificateSha256Thumbprint(byte[] thumbprint) {
|
||||
this.x509.setX509CertificateSha256Thumbprint(thumbprint);
|
||||
public T x509CertificateSha256Thumbprint(byte[] thumbprint) {
|
||||
this.x509.x509CertificateSha256Thumbprint(thumbprint);
|
||||
return self();
|
||||
}
|
||||
|
||||
|
@ -145,27 +164,27 @@ public class DefaultJweHeaderMutator<T extends JweHeaderMutator<T>>
|
|||
// =============================================================
|
||||
|
||||
@Override
|
||||
public T setAgreementPartyUInfo(byte[] info) {
|
||||
public T agreementPartyUInfo(byte[] info) {
|
||||
return put(DefaultJweHeader.APU, info);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T setAgreementPartyUInfo(String info) {
|
||||
return setAgreementPartyUInfo(Strings.utf8(Strings.clean(info)));
|
||||
public T agreementPartyUInfo(String info) {
|
||||
return agreementPartyUInfo(Strings.utf8(Strings.clean(info)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public T setAgreementPartyVInfo(byte[] info) {
|
||||
public T agreementPartyVInfo(byte[] info) {
|
||||
return put(DefaultJweHeader.APV, info);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T setAgreementPartyVInfo(String info) {
|
||||
return setAgreementPartyVInfo(Strings.utf8(Strings.clean(info)));
|
||||
public T agreementPartyVInfo(String info) {
|
||||
return agreementPartyVInfo(Strings.utf8(Strings.clean(info)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public T setPbes2Count(int count) {
|
||||
public T pbes2Count(int count) {
|
||||
return put(DefaultJweHeader.P2C, count);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,8 +25,8 @@ public class DefaultJws<P> extends DefaultProtectedJwt<JwsHeader, P> implements
|
|||
|
||||
private final String signature;
|
||||
|
||||
public DefaultJws(JwsHeader header, P body, String signature) {
|
||||
super(header, body, Decoders.BASE64URL.decode(signature), DIGEST_NAME);
|
||||
public DefaultJws(JwsHeader header, P payload, String signature) {
|
||||
super(header, payload, Decoders.BASE64URL.decode(signature), DIGEST_NAME);
|
||||
this.signature = signature;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,8 +15,7 @@
|
|||
*/
|
||||
package io.jsonwebtoken.impl;
|
||||
|
||||
import io.jsonwebtoken.Claims;
|
||||
import io.jsonwebtoken.ClaimsBuilder;
|
||||
import io.jsonwebtoken.Header;
|
||||
import io.jsonwebtoken.JweHeader;
|
||||
import io.jsonwebtoken.JwtBuilder;
|
||||
import io.jsonwebtoken.Jwts;
|
||||
|
@ -38,6 +37,7 @@ import io.jsonwebtoken.io.Serializer;
|
|||
import io.jsonwebtoken.lang.Assert;
|
||||
import io.jsonwebtoken.lang.Collections;
|
||||
import io.jsonwebtoken.lang.Objects;
|
||||
import io.jsonwebtoken.lang.Strings;
|
||||
import io.jsonwebtoken.security.AeadAlgorithm;
|
||||
import io.jsonwebtoken.security.AeadRequest;
|
||||
import io.jsonwebtoken.security.AeadResult;
|
||||
|
@ -63,14 +63,15 @@ import java.util.Map;
|
|||
|
||||
public class DefaultJwtBuilder implements JwtBuilder {
|
||||
|
||||
public static final String PUB_KEY_SIGN_MSG = "PublicKeys may not be used to create digital signatures. " + "Only PrivateKeys may be used to create digital signatures, and PublicKeys are used to verify " + "digital signatures.";
|
||||
public static final String PUB_KEY_SIGN_MSG = "PublicKeys may not be used to create digital signatures. " +
|
||||
"Only PrivateKeys may be used to create digital signatures, and PublicKeys are used to verify " +
|
||||
"digital signatures.";
|
||||
|
||||
protected Provider provider;
|
||||
protected SecureRandom secureRandom;
|
||||
|
||||
private final DefaultJwtBuilderHeader headerBuilder = new DefaultJwtBuilderHeader(this);
|
||||
|
||||
private final ClaimsBuilder claimsBuilder = new DefaultClaimsBuilder();
|
||||
private final DefaultBuilderHeader headerBuilder;
|
||||
private final DefaultBuilderClaims claimsBuilder;
|
||||
|
||||
protected byte[] content;
|
||||
|
||||
|
@ -89,22 +90,32 @@ public class DefaultJwtBuilder implements JwtBuilder {
|
|||
protected Function<Map<String, ?>, byte[]> headerSerializer;
|
||||
protected Function<Map<String, ?>, byte[]> claimsSerializer;
|
||||
|
||||
protected Encoder<byte[], String> base64UrlEncoder = Encoders.BASE64URL;
|
||||
protected Encoder<byte[], String> encoder = Encoders.BASE64URL;
|
||||
protected CompressionAlgorithm compressionAlgorithm;
|
||||
|
||||
public DefaultJwtBuilder() {
|
||||
this.headerBuilder = new DefaultBuilderHeader(this);
|
||||
this.claimsBuilder = new DefaultBuilderClaims(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtBuilder.Header header() {
|
||||
public BuilderHeader header() {
|
||||
return this.headerBuilder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtBuilder setProvider(Provider provider) {
|
||||
public BuilderClaims claims() {
|
||||
return this.claimsBuilder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtBuilder provider(Provider provider) {
|
||||
this.provider = provider;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtBuilder setSecureRandom(SecureRandom secureRandom) {
|
||||
public JwtBuilder random(SecureRandom secureRandom) {
|
||||
this.secureRandom = secureRandom;
|
||||
return this;
|
||||
}
|
||||
|
@ -130,6 +141,11 @@ public class DefaultJwtBuilder implements JwtBuilder {
|
|||
|
||||
@Override
|
||||
public JwtBuilder serializeToJsonWith(final Serializer<Map<String, ?>> serializer) {
|
||||
return serializer(serializer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtBuilder serializer(Serializer<Map<String, ?>> serializer) {
|
||||
Assert.notNull(serializer, "Serializer cannot be null.");
|
||||
this.serializer = serializer;
|
||||
this.headerSerializer = wrap(serializer, "header");
|
||||
|
@ -138,29 +154,30 @@ public class DefaultJwtBuilder implements JwtBuilder {
|
|||
}
|
||||
|
||||
@Override
|
||||
public JwtBuilder base64UrlEncodeWith(Encoder<byte[], String> base64UrlEncoder) {
|
||||
Assert.notNull(base64UrlEncoder, "base64UrlEncoder cannot be null.");
|
||||
this.base64UrlEncoder = base64UrlEncoder;
|
||||
public JwtBuilder base64UrlEncodeWith(Encoder<byte[], String> encoder) {
|
||||
return encoder(encoder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtBuilder encoder(Encoder<byte[], String> encoder) {
|
||||
Assert.notNull(encoder, "encoder cannot be null.");
|
||||
this.encoder = encoder;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtBuilder setHeader(Map<String, ?> map) {
|
||||
this.headerBuilder.clear();
|
||||
this.headerBuilder.putAll(map);
|
||||
return this;
|
||||
return this.headerBuilder.empty().add(map).and();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtBuilder setHeaderParams(Map<String, ?> params) {
|
||||
this.headerBuilder.putAll(params);
|
||||
return this;
|
||||
return this.headerBuilder.add(params).and();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtBuilder setHeaderParam(String name, Object value) {
|
||||
this.headerBuilder.put(name, value);
|
||||
return this;
|
||||
return this.headerBuilder.add(name, value).and();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked") // TODO: remove for 1.0
|
||||
|
@ -227,7 +244,8 @@ public class DefaultJwtBuilder implements JwtBuilder {
|
|||
public JwtBuilder signWith(io.jsonwebtoken.SignatureAlgorithm alg, byte[] secretKeyBytes) throws InvalidKeyException {
|
||||
Assert.notNull(alg, "SignatureAlgorithm cannot be null.");
|
||||
Assert.notEmpty(secretKeyBytes, "secret key byte array cannot be null or empty.");
|
||||
Assert.isTrue(alg.isHmac(), "Key bytes may only be specified for HMAC signatures. If using RSA or Elliptic Curve, use the signWith(SignatureAlgorithm, Key) method instead.");
|
||||
Assert.isTrue(alg.isHmac(), "Key bytes may only be specified for HMAC signatures. " +
|
||||
"If using RSA or Elliptic Curve, use the signWith(SignatureAlgorithm, Key) method instead.");
|
||||
SecretKey key = new SecretKeySpec(secretKeyBytes, alg.getJcaName());
|
||||
return signWith(key, alg);
|
||||
}
|
||||
|
@ -236,7 +254,8 @@ public class DefaultJwtBuilder implements JwtBuilder {
|
|||
@Override
|
||||
public JwtBuilder signWith(io.jsonwebtoken.SignatureAlgorithm alg, String base64EncodedSecretKey) throws InvalidKeyException {
|
||||
Assert.hasText(base64EncodedSecretKey, "base64-encoded secret key cannot be null or empty.");
|
||||
Assert.isTrue(alg.isHmac(), "Base64-encoded key bytes may only be specified for HMAC signatures. If using RSA or Elliptic Curve, use the signWith(SignatureAlgorithm, Key) method instead.");
|
||||
Assert.isTrue(alg.isHmac(), "Base64-encoded key bytes may only be specified for HMAC signatures. " +
|
||||
"If using RSA or Elliptic Curve, use the signWith(SignatureAlgorithm, Key) method instead.");
|
||||
byte[] bytes = Decoders.BASE64.decode(base64EncodedSecretKey);
|
||||
return signWith(alg, bytes);
|
||||
}
|
||||
|
@ -293,90 +312,119 @@ public class DefaultJwtBuilder implements JwtBuilder {
|
|||
|
||||
@Override
|
||||
public JwtBuilder setPayload(String payload) {
|
||||
byte[] bytes = payload != null ? payload.getBytes(StandardCharsets.UTF_8) : null;
|
||||
return setContent(bytes);
|
||||
return content(Strings.utf8(payload));
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtBuilder setContent(byte[] content) {
|
||||
public JwtBuilder content(byte[] content) {
|
||||
this.content = content;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtBuilder setContent(byte[] content, String cty) {
|
||||
public JwtBuilder content(byte[] content, String cty) {
|
||||
Assert.notEmpty(content, "content byte array cannot be null or empty.");
|
||||
Assert.hasText(cty, "Content Type String cannot be null or empty.");
|
||||
cty = CompactMediaTypeIdConverter.INSTANCE.applyFrom(cty);
|
||||
this.headerBuilder.setContentType(cty);
|
||||
return setContent(content);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtBuilder setClaims(Claims claims) {
|
||||
Assert.notNull(claims, "Claims argument cannot be null.");
|
||||
return setClaims((Map<String, ?>) claims);
|
||||
this.headerBuilder.contentType(cty);
|
||||
return content(content);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtBuilder setClaims(Map<String, ?> claims) {
|
||||
Assert.notNull(claims, "Claims map cannot be null.");
|
||||
this.claimsBuilder.empty();
|
||||
this.claimsBuilder.set(claims);
|
||||
return this;
|
||||
return this.claimsBuilder.empty().add(claims).and();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtBuilder addClaims(Map<String, ?> claims) {
|
||||
this.claimsBuilder.set(claims);
|
||||
return this;
|
||||
return claims(claims);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtBuilder claims(Map<String, ?> claims) {
|
||||
return claims().add(claims).and();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtBuilder claim(String name, Object value) {
|
||||
return claims().add(name, value).and();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtBuilder setIssuer(String iss) {
|
||||
this.claimsBuilder.setIssuer(iss);
|
||||
return issuer(iss);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtBuilder issuer(String iss) {
|
||||
this.claimsBuilder.issuer(iss);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtBuilder setSubject(String sub) {
|
||||
this.claimsBuilder.setSubject(sub);
|
||||
return subject(sub);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtBuilder subject(String sub) {
|
||||
this.claimsBuilder.subject(sub);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtBuilder setAudience(String aud) {
|
||||
this.claimsBuilder.setAudience(aud);
|
||||
return audience(aud);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtBuilder audience(String aud) {
|
||||
this.claimsBuilder.audience(aud);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtBuilder setExpiration(Date exp) {
|
||||
this.claimsBuilder.setExpiration(exp);
|
||||
return expiration(exp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtBuilder expiration(Date exp) {
|
||||
this.claimsBuilder.expiration(exp);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtBuilder setNotBefore(Date nbf) {
|
||||
this.claimsBuilder.setNotBefore(nbf);
|
||||
return notBefore(nbf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtBuilder notBefore(Date nbf) {
|
||||
this.claimsBuilder.notBefore(nbf);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtBuilder setIssuedAt(Date iat) {
|
||||
this.claimsBuilder.setIssuedAt(iat);
|
||||
return issuedAt(iat);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtBuilder issuedAt(Date iat) {
|
||||
this.claimsBuilder.issuedAt(iat);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtBuilder setId(String jti) {
|
||||
this.claimsBuilder.setId(jti);
|
||||
return this;
|
||||
return id(jti);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtBuilder claim(String name, Object value) {
|
||||
this.claimsBuilder.set(name, value);
|
||||
public JwtBuilder id(String jti) {
|
||||
this.claimsBuilder.id(jti);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -390,7 +438,7 @@ public class DefaultJwtBuilder implements JwtBuilder {
|
|||
throw new IllegalStateException(msg);
|
||||
}
|
||||
|
||||
final Claims claims = this.claimsBuilder.build();
|
||||
final io.jsonwebtoken.Claims claims = this.claimsBuilder.build();
|
||||
|
||||
if (Objects.isEmpty(content) && Collections.isEmpty(claims)) {
|
||||
if (jwe) { // JWE payload can never be empty:
|
||||
|
@ -406,7 +454,7 @@ public class DefaultJwtBuilder implements JwtBuilder {
|
|||
|
||||
if (this.serializer == null) { // try to find one based on the services available
|
||||
//noinspection unchecked
|
||||
serializeToJsonWith(Services.loadFirst(Serializer.class));
|
||||
serializer(Services.loadFirst(Serializer.class));
|
||||
}
|
||||
|
||||
byte[] payload = content;
|
||||
|
@ -415,7 +463,7 @@ public class DefaultJwtBuilder implements JwtBuilder {
|
|||
}
|
||||
if (!Objects.isEmpty(payload) && compressionAlgorithm != null) {
|
||||
payload = compressionAlgorithm.compress(payload);
|
||||
this.headerBuilder.setCompressionAlgorithm(compressionAlgorithm.getId());
|
||||
this.headerBuilder.add(DefaultHeader.COMPRESSION_ALGORITHM.getId(), compressionAlgorithm.getId());
|
||||
}
|
||||
|
||||
if (jwe) {
|
||||
|
@ -425,25 +473,17 @@ public class DefaultJwtBuilder implements JwtBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
private io.jsonwebtoken.Header buildHeader() {
|
||||
return new DefaultJwtHeaderBuilder(this.headerBuilder).build();
|
||||
}
|
||||
|
||||
private String compact(byte[] payload) {
|
||||
|
||||
Assert.stateNotNull(sigAlg, "SignatureAlgorithm is required."); // invariant
|
||||
|
||||
// if (this.key != null && !(header instanceof JwsHeader)) {
|
||||
// header = new DefaultJwsHeader(header);
|
||||
// }
|
||||
this.headerBuilder.add(DefaultHeader.ALGORITHM.getId(), sigAlg.getId());
|
||||
|
||||
this.headerBuilder.setAlgorithm(sigAlg.getId());
|
||||
|
||||
final io.jsonwebtoken.Header header = buildHeader();
|
||||
final Header header = this.headerBuilder.build();
|
||||
|
||||
byte[] headerBytes = headerSerializer.apply(header);
|
||||
String base64UrlEncodedHeader = base64UrlEncoder.encode(headerBytes);
|
||||
String base64UrlEncodedBody = base64UrlEncoder.encode(payload);
|
||||
String base64UrlEncodedHeader = encoder.encode(headerBytes);
|
||||
String base64UrlEncodedBody = encoder.encode(payload);
|
||||
|
||||
String jwt = base64UrlEncodedHeader + DefaultJwtParser.SEPARATOR_CHAR + base64UrlEncodedBody;
|
||||
|
||||
|
@ -453,7 +493,7 @@ public class DefaultJwtBuilder implements JwtBuilder {
|
|||
byte[] data = jwt.getBytes(StandardCharsets.US_ASCII);
|
||||
SecureRequest<byte[], Key> request = new DefaultSecureRequest<>(data, provider, secureRandom, key);
|
||||
byte[] signature = signFunction.apply(request);
|
||||
String base64UrlSignature = base64UrlEncoder.encode(signature);
|
||||
String base64UrlSignature = encoder.encode(signature);
|
||||
jwt += DefaultJwtParser.SEPARATOR_CHAR + base64UrlSignature;
|
||||
} else {
|
||||
// no signature (unprotected JWT), but must terminate w/ a period, see
|
||||
|
@ -483,13 +523,13 @@ public class DefaultJwtBuilder implements JwtBuilder {
|
|||
SecretKey cek = Assert.notNull(keyResult.getKey(), "KeyResult must return a content encryption key.");
|
||||
byte[] encryptedCek = Assert.notNull(keyResult.getPayload(), "KeyResult must return an encrypted key byte array, even if empty.");
|
||||
|
||||
this.headerBuilder.setAlgorithm(keyAlg.getId());
|
||||
this.headerBuilder.add(DefaultHeader.ALGORITHM.getId(), keyAlg.getId());
|
||||
this.headerBuilder.put(DefaultJweHeader.ENCRYPTION_ALGORITHM.getId(), enc.getId());
|
||||
|
||||
final io.jsonwebtoken.Header header = buildHeader();
|
||||
final Header header = this.headerBuilder.build();
|
||||
|
||||
byte[] headerBytes = this.headerSerializer.apply(header);
|
||||
final String base64UrlEncodedHeader = base64UrlEncoder.encode(headerBytes);
|
||||
final String base64UrlEncodedHeader = encoder.encode(headerBytes);
|
||||
byte[] aad = base64UrlEncodedHeader.getBytes(StandardCharsets.US_ASCII);
|
||||
|
||||
AeadRequest encRequest = new DefaultAeadRequest(payload, provider, secureRandom, cek, aad);
|
||||
|
@ -499,20 +539,43 @@ public class DefaultJwtBuilder implements JwtBuilder {
|
|||
byte[] ciphertext = Assert.notEmpty(encResult.getPayload(), "Encryption result must have non-empty ciphertext (result.getData()).");
|
||||
byte[] tag = Assert.notEmpty(encResult.getDigest(), "Encryption result must have a non-empty authentication tag.");
|
||||
|
||||
String base64UrlEncodedEncryptedCek = base64UrlEncoder.encode(encryptedCek);
|
||||
String base64UrlEncodedIv = base64UrlEncoder.encode(iv);
|
||||
String base64UrlEncodedCiphertext = base64UrlEncoder.encode(ciphertext);
|
||||
String base64UrlEncodedTag = base64UrlEncoder.encode(tag);
|
||||
String base64UrlEncodedEncryptedCek = encoder.encode(encryptedCek);
|
||||
String base64UrlEncodedIv = encoder.encode(iv);
|
||||
String base64UrlEncodedCiphertext = encoder.encode(ciphertext);
|
||||
String base64UrlEncodedTag = encoder.encode(tag);
|
||||
|
||||
return base64UrlEncodedHeader + DefaultJwtParser.SEPARATOR_CHAR + base64UrlEncodedEncryptedCek + DefaultJwtParser.SEPARATOR_CHAR + base64UrlEncodedIv + DefaultJwtParser.SEPARATOR_CHAR + base64UrlEncodedCiphertext + DefaultJwtParser.SEPARATOR_CHAR + base64UrlEncodedTag;
|
||||
return base64UrlEncodedHeader + DefaultJwtParser.SEPARATOR_CHAR +
|
||||
base64UrlEncodedEncryptedCek + DefaultJwtParser.SEPARATOR_CHAR +
|
||||
base64UrlEncodedIv + DefaultJwtParser.SEPARATOR_CHAR +
|
||||
base64UrlEncodedCiphertext + DefaultJwtParser.SEPARATOR_CHAR +
|
||||
base64UrlEncodedTag;
|
||||
}
|
||||
|
||||
private static class DefaultJwtBuilderHeader extends DefaultJweHeaderBuilder<Header>
|
||||
implements JwtBuilder.Header {
|
||||
private static class DefaultBuilderClaims extends DelegatingClaimsMutator<BuilderClaims>
|
||||
implements BuilderClaims {
|
||||
|
||||
private final JwtBuilder builder;
|
||||
|
||||
public DefaultJwtBuilderHeader(JwtBuilder builder) {
|
||||
private DefaultBuilderClaims(JwtBuilder builder) {
|
||||
super();
|
||||
this.builder = builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtBuilder and() {
|
||||
return this.builder;
|
||||
}
|
||||
|
||||
private io.jsonwebtoken.Claims build() {
|
||||
return new DefaultClaims(this.DELEGATE);
|
||||
}
|
||||
}
|
||||
|
||||
private static class DefaultBuilderHeader extends DefaultJweHeaderBuilder<BuilderHeader> implements BuilderHeader {
|
||||
|
||||
private final JwtBuilder builder;
|
||||
|
||||
private DefaultBuilderHeader(JwtBuilder builder) {
|
||||
super();
|
||||
this.builder = Assert.notNull(builder, "JwtBuilder cannot be null.");
|
||||
}
|
||||
|
@ -521,5 +584,9 @@ public class DefaultJwtBuilder implements JwtBuilder {
|
|||
public JwtBuilder and() {
|
||||
return builder;
|
||||
}
|
||||
|
||||
private Header build() {
|
||||
return new DefaultJwtHeaderBuilder(this).build();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -95,18 +95,17 @@ public class DefaultJwtParser implements JwtParser {
|
|||
"the compact JWE string is missing the required signature.";
|
||||
|
||||
public static final String MISSING_JWE_DIGEST_MSG_FMT = "The JWE header references key management algorithm '%s' " +
|
||||
"but the compact JWE string is missing the " + "required AAD authentication tag.";
|
||||
"but the compact JWE string is missing the required AAD authentication tag.";
|
||||
|
||||
private static final String MISSING_ENC_MSG = "JWE header does not contain a required " +
|
||||
"'enc' (Encryption Algorithm) header parameter. " + "This header parameter is mandatory per the JWE " +
|
||||
"Specification, Section 4.1.2. See " +
|
||||
"https://www.rfc-editor.org/rfc/rfc7516.html#section-4.1.2 for more information.";
|
||||
private static final String MISSING_ENC_MSG = "JWE header does not contain a required 'enc' (Encryption " +
|
||||
"Algorithm) header parameter. This header parameter is mandatory per the JWE Specification, " +
|
||||
"Section 4.1.2. See https://www.rfc-editor.org/rfc/rfc7516.html#section-4.1.2 for more information.";
|
||||
|
||||
private static final String UNSECURED_DISABLED_MSG_PREFIX = "Unsecured JWSs (those with an " +
|
||||
DefaultHeader.ALGORITHM + " header value of '" + Jwts.SIG.NONE.getId() + "') are disallowed by " +
|
||||
"default as mandated by https://www.rfc-editor.org/rfc/rfc7518.html#section-3.6. If you wish to " +
|
||||
"allow them to be parsed, call the JwtParserBuilder.enableUnsecuredJws() method (but please read the " +
|
||||
"security considerations covered in that method's JavaDoc before doing so). Header: ";
|
||||
"allow them to be parsed, call the JwtParserBuilder.enableUnsecured() method, but please read the " +
|
||||
"security considerations covered in that method's JavaDoc before doing so. Header: ";
|
||||
|
||||
private static final String JWE_NONE_MSG = "JWEs do not support key management " + DefaultHeader.ALGORITHM +
|
||||
" header value '" + Jwts.SIG.NONE.getId() + "' per " +
|
||||
|
@ -121,15 +120,15 @@ public class DefaultJwtParser implements JwtParser {
|
|||
"against [Denial of Service attacks](" +
|
||||
"https://www.usenix.org/system/files/conference/usenixsecurity15/sec15-paper-pellegrino.pdf). If you " +
|
||||
"wish to enable Unsecure JWS payload decompression, call the JwtParserBuilder." +
|
||||
"enableUnsecuredDecompression() method (but please read the security considerations covered in that " +
|
||||
"method's JavaDoc before doing so).";
|
||||
"enableUnsecuredDecompression() method, but please read the security considerations covered in that " +
|
||||
"method's JavaDoc before doing so.";
|
||||
|
||||
private final Provider provider;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private final SigningKeyResolver signingKeyResolver;
|
||||
|
||||
private final boolean enableUnsecuredJws;
|
||||
private final boolean enableUnsecured;
|
||||
|
||||
private final boolean enableUnsecuredDecompression;
|
||||
|
||||
|
@ -143,7 +142,7 @@ public class DefaultJwtParser implements JwtParser {
|
|||
|
||||
private final Locator<? extends Key> keyLocator;
|
||||
|
||||
private final Decoder<String, byte[]> base64UrlDecoder;
|
||||
private final Decoder<String, byte[]> decoder;
|
||||
|
||||
private final Deserializer<Map<String, ?>> deserializer;
|
||||
|
||||
|
@ -157,7 +156,7 @@ public class DefaultJwtParser implements JwtParser {
|
|||
@SuppressWarnings("deprecation")
|
||||
DefaultJwtParser(Provider provider,
|
||||
SigningKeyResolver signingKeyResolver,
|
||||
boolean enableUnsecuredJws,
|
||||
boolean enableUnsecured,
|
||||
boolean enableUnsecuredDecompression,
|
||||
Locator<? extends Key> keyLocator,
|
||||
Clock clock,
|
||||
|
@ -171,14 +170,14 @@ public class DefaultJwtParser implements JwtParser {
|
|||
Collection<KeyAlgorithm<?, ?>> extraKeyAlgs,
|
||||
Collection<AeadAlgorithm> extraEncAlgs) {
|
||||
this.provider = provider;
|
||||
this.enableUnsecuredJws = enableUnsecuredJws;
|
||||
this.enableUnsecured = enableUnsecured;
|
||||
this.enableUnsecuredDecompression = enableUnsecuredDecompression;
|
||||
this.signingKeyResolver = signingKeyResolver;
|
||||
this.keyLocator = Assert.notNull(keyLocator, "Key Locator cannot be null.");
|
||||
this.clock = Assert.notNull(clock, "Clock cannot be null.");
|
||||
this.allowedClockSkewMillis = allowedClockSkewMillis;
|
||||
this.expectedClaims = Jwts.claims().set(expectedClaims);
|
||||
this.base64UrlDecoder = Assert.notNull(base64UrlDecoder, "base64UrlDecoder cannot be null.");
|
||||
this.expectedClaims = Jwts.claims().add(expectedClaims);
|
||||
this.decoder = Assert.notNull(base64UrlDecoder, "base64UrlDecoder cannot be null.");
|
||||
this.deserializer = Assert.notNull(deserializer, "Deserializer cannot be null.");
|
||||
|
||||
this.sigAlgFn = new IdLocator<>(DefaultHeader.ALGORITHM, Jwts.SIG.get(), extraSigAlgs, MISSING_JWS_ALG_MSG);
|
||||
|
@ -305,10 +304,10 @@ public class DefaultJwtParser implements JwtParser {
|
|||
}
|
||||
|
||||
//re-create the jwt part without the signature. This is what is needed for signature verification:
|
||||
String jwtWithoutSignature = tokenized.getProtected() + SEPARATOR_CHAR + tokenized.getBody();
|
||||
String jwtWithoutSignature = tokenized.getProtected() + SEPARATOR_CHAR + tokenized.getPayload();
|
||||
|
||||
byte[] data = jwtWithoutSignature.getBytes(StandardCharsets.US_ASCII);
|
||||
byte[] signature = base64UrlDecode(tokenized.getDigest(), "JWS signature");
|
||||
byte[] signature = decode(tokenized.getDigest(), "JWS signature");
|
||||
|
||||
try {
|
||||
VerifySecureDigestRequest<Key> request =
|
||||
|
@ -346,8 +345,8 @@ public class DefaultJwtParser implements JwtParser {
|
|||
}
|
||||
|
||||
// =============== Header =================
|
||||
final byte[] headerBytes = base64UrlDecode(base64UrlHeader, "protected header");
|
||||
Map<String, ?> m = readValue(headerBytes, "protected header");
|
||||
final byte[] headerBytes = decode(base64UrlHeader, "protected header");
|
||||
Map<String, ?> m = deserialize(headerBytes, "protected header");
|
||||
Header header;
|
||||
try {
|
||||
header = tokenized.createHeader(m);
|
||||
|
@ -376,7 +375,7 @@ public class DefaultJwtParser implements JwtParser {
|
|||
throw new MalformedJwtException(JWE_NONE_MSG);
|
||||
}
|
||||
// Unsecured JWTs are disabled by default per the RFC:
|
||||
if (!enableUnsecuredJws) {
|
||||
if (!enableUnsecured) {
|
||||
String msg = UNSECURED_DISABLED_MSG_PREFIX + header;
|
||||
throw new UnsupportedJwtException(msg);
|
||||
}
|
||||
|
@ -389,9 +388,9 @@ public class DefaultJwtParser implements JwtParser {
|
|||
throw new MalformedJwtException(msg);
|
||||
}
|
||||
|
||||
// =============== Body =================
|
||||
byte[] payload = base64UrlDecode(tokenized.getBody(), "payload");
|
||||
if (tokenized instanceof TokenizedJwe && Arrays.length(payload) == 0) { // Only JWS body can be empty per https://github.com/jwtk/jjwt/pull/540
|
||||
// =============== Payload =================
|
||||
byte[] payload = decode(tokenized.getPayload(), "payload");
|
||||
if (tokenized instanceof TokenizedJwe && Arrays.length(payload) == 0) { // Only JWS payload can be empty per https://github.com/jwtk/jjwt/pull/540
|
||||
String msg = "Compact JWE strings MUST always contain a payload (ciphertext).";
|
||||
throw new MalformedJwtException(msg);
|
||||
}
|
||||
|
@ -406,7 +405,7 @@ public class DefaultJwtParser implements JwtParser {
|
|||
byte[] cekBytes = Bytes.EMPTY; //ignored unless using an encrypted key algorithm
|
||||
String base64Url = tokenizedJwe.getEncryptedKey();
|
||||
if (Strings.hasText(base64Url)) {
|
||||
cekBytes = base64UrlDecode(base64Url, "JWE encrypted key");
|
||||
cekBytes = decode(base64Url, "JWE encrypted key");
|
||||
if (Arrays.length(cekBytes) == 0) {
|
||||
String msg = "Compact JWE string represents an encrypted key, but the key is empty.";
|
||||
throw new MalformedJwtException(msg);
|
||||
|
@ -415,7 +414,7 @@ public class DefaultJwtParser implements JwtParser {
|
|||
|
||||
base64Url = tokenizedJwe.getIv();
|
||||
if (Strings.hasText(base64Url)) {
|
||||
iv = base64UrlDecode(base64Url, "JWE Initialization Vector");
|
||||
iv = decode(base64Url, "JWE Initialization Vector");
|
||||
}
|
||||
if (Arrays.length(iv) == 0) {
|
||||
String msg = "Compact JWE strings must always contain an Initialization Vector.";
|
||||
|
@ -430,7 +429,7 @@ public class DefaultJwtParser implements JwtParser {
|
|||
base64Url = base64UrlDigest;
|
||||
//guaranteed to be non-empty via the `alg` + digest check above:
|
||||
Assert.hasText(base64Url, "JWE AAD Authentication Tag cannot be null or empty.");
|
||||
tag = base64UrlDecode(base64Url, "JWE AAD Authentication Tag");
|
||||
tag = decode(base64Url, "JWE AAD Authentication Tag");
|
||||
if (Arrays.length(tag) == 0) {
|
||||
String msg = "Compact JWE strings must always contain an AAD Authentication Tag.";
|
||||
throw new MalformedJwtException(msg);
|
||||
|
@ -467,7 +466,7 @@ public class DefaultJwtParser implements JwtParser {
|
|||
payload = result.getPayload();
|
||||
|
||||
} else if (hasDigest && this.signingKeyResolver == null) { //TODO: for 1.0, remove the == null check
|
||||
// not using a signing key resolver, so we can verify the signature before reading the body, which is
|
||||
// not using a signing key resolver, so we can verify the signature before reading the payload, which is
|
||||
// always safer:
|
||||
verifySignature(tokenized, ((JwsHeader) header), alg, new LocatingKeyResolver(this.keyLocator), null, null);
|
||||
}
|
||||
|
@ -490,7 +489,7 @@ public class DefaultJwtParser implements JwtParser {
|
|||
// parameter is performed by the JWS application."
|
||||
//
|
||||
&& isLikelyJson(payload)) { // likely to be json, parse it:
|
||||
Map<String, ?> claimsMap = readValue(payload, "claims");
|
||||
Map<String, ?> claimsMap = deserialize(payload, "claims");
|
||||
try {
|
||||
claims = new DefaultClaims(claimsMap);
|
||||
} catch (Exception e) {
|
||||
|
@ -708,16 +707,16 @@ public class DefaultJwtParser implements JwtParser {
|
|||
});
|
||||
}
|
||||
|
||||
protected byte[] base64UrlDecode(String base64UrlEncoded, String name) {
|
||||
protected byte[] decode(String base64UrlEncoded, String name) {
|
||||
try {
|
||||
return base64UrlDecoder.decode(base64UrlEncoded);
|
||||
return decoder.decode(base64UrlEncoded);
|
||||
} catch (DecodingException e) {
|
||||
String msg = "Invalid Base64Url " + name + ": " + base64UrlEncoded;
|
||||
throw new MalformedJwtException(msg, e);
|
||||
}
|
||||
}
|
||||
|
||||
protected Map<String, ?> readValue(byte[] bytes, final String name) {
|
||||
protected Map<String, ?> deserialize(byte[] bytes, final String name) {
|
||||
try {
|
||||
return deserializer.deserialize(bytes);
|
||||
} catch (MalformedJwtException | DeserializationException e) {
|
||||
|
|
|
@ -36,8 +36,11 @@ import io.jsonwebtoken.security.KeyAlgorithm;
|
|||
import io.jsonwebtoken.security.Keys;
|
||||
import io.jsonwebtoken.security.SecureDigestAlgorithm;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
import java.security.Key;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.Provider;
|
||||
import java.security.PublicKey;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedHashSet;
|
||||
|
@ -62,7 +65,7 @@ public class DefaultJwtParserBuilder implements JwtParserBuilder {
|
|||
|
||||
private Provider provider;
|
||||
|
||||
private boolean enableUnsecuredJws = false;
|
||||
private boolean enableUnsecured = false;
|
||||
|
||||
private boolean enableUnsecuredDecompression = false;
|
||||
|
||||
|
@ -82,7 +85,7 @@ public class DefaultJwtParserBuilder implements JwtParserBuilder {
|
|||
@SuppressWarnings("deprecation")
|
||||
private CompressionCodecResolver compressionCodecResolver;
|
||||
|
||||
private Decoder<String, byte[]> base64UrlDecoder = Decoders.BASE64URL;
|
||||
private Decoder<String, byte[]> decoder = Decoders.BASE64URL;
|
||||
|
||||
private Deserializer<Map<String, ?>> deserializer;
|
||||
|
||||
|
@ -96,8 +99,8 @@ public class DefaultJwtParserBuilder implements JwtParserBuilder {
|
|||
private Key decryptionKey;
|
||||
|
||||
@Override
|
||||
public JwtParserBuilder enableUnsecuredJws() {
|
||||
this.enableUnsecuredJws = true;
|
||||
public JwtParserBuilder enableUnsecured() {
|
||||
this.enableUnsecured = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -108,22 +111,32 @@ public class DefaultJwtParserBuilder implements JwtParserBuilder {
|
|||
}
|
||||
|
||||
@Override
|
||||
public JwtParserBuilder setProvider(Provider provider) {
|
||||
public JwtParserBuilder provider(Provider provider) {
|
||||
this.provider = provider;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtParserBuilder deserializeJsonWith(Deserializer<Map<String, ?>> deserializer) {
|
||||
return deserializer(deserializer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtParserBuilder deserializer(Deserializer<Map<String, ?>> deserializer) {
|
||||
Assert.notNull(deserializer, "deserializer cannot be null.");
|
||||
this.deserializer = deserializer;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtParserBuilder base64UrlDecodeWith(Decoder<String, byte[]> base64UrlDecoder) {
|
||||
Assert.notNull(base64UrlDecoder, "base64UrlDecoder cannot be null.");
|
||||
this.base64UrlDecoder = base64UrlDecoder;
|
||||
public JwtParserBuilder base64UrlDecodeWith(Decoder<String, byte[]> decoder) {
|
||||
return decoder(decoder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtParserBuilder decoder(Decoder<String, byte[]> decoder) {
|
||||
Assert.notNull(decoder, "decoder cannot be null.");
|
||||
this.decoder = decoder;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -173,12 +186,17 @@ public class DefaultJwtParserBuilder implements JwtParserBuilder {
|
|||
public JwtParserBuilder require(String claimName, Object value) {
|
||||
Assert.hasText(claimName, "claim name cannot be null or empty.");
|
||||
Assert.notNull(value, "The value cannot be null for claim name: " + claimName);
|
||||
expectedClaims.set(claimName, value);
|
||||
expectedClaims.add(claimName, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtParserBuilder setClock(Clock clock) {
|
||||
return clock(clock);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtParserBuilder clock(Clock clock) {
|
||||
Assert.notNull(clock, "Clock instance cannot be null.");
|
||||
this.clock = clock;
|
||||
return this;
|
||||
|
@ -186,6 +204,11 @@ public class DefaultJwtParserBuilder implements JwtParserBuilder {
|
|||
|
||||
@Override
|
||||
public JwtParserBuilder setAllowedClockSkewSeconds(long seconds) throws IllegalArgumentException {
|
||||
return clockSkewSeconds(seconds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtParserBuilder clockSkewSeconds(long seconds) throws IllegalArgumentException {
|
||||
Assert.isTrue(seconds <= MAX_CLOCK_SKEW_MILLIS, MAX_CLOCK_SKEW_ILLEGAL_MSG);
|
||||
this.allowedClockSkewMillis = Math.max(0, seconds * MILLISECONDS_PER_SECOND);
|
||||
return this;
|
||||
|
@ -210,13 +233,31 @@ public class DefaultJwtParserBuilder implements JwtParserBuilder {
|
|||
}
|
||||
|
||||
@Override
|
||||
public JwtParserBuilder verifyWith(Key key) {
|
||||
public JwtParserBuilder verifyWith(SecretKey key) {
|
||||
return verifyWith((Key) key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtParserBuilder verifyWith(PublicKey key) {
|
||||
return verifyWith((Key) key);
|
||||
}
|
||||
|
||||
private JwtParserBuilder verifyWith(Key key) {
|
||||
this.signatureVerificationKey = Assert.notNull(key, "signature verification key cannot be null.");
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtParserBuilder decryptWith(final Key key) {
|
||||
public JwtParserBuilder decryptWith(SecretKey key) {
|
||||
return decryptWith((Key) key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtParserBuilder decryptWith(PrivateKey key) {
|
||||
return decryptWith((Key) key);
|
||||
}
|
||||
|
||||
private JwtParserBuilder decryptWith(final Key key) {
|
||||
this.decryptionKey = Assert.notNull(key, "decryption key cannot be null.");
|
||||
return this;
|
||||
}
|
||||
|
@ -229,23 +270,23 @@ public class DefaultJwtParserBuilder implements JwtParserBuilder {
|
|||
}
|
||||
|
||||
@Override
|
||||
public JwtParserBuilder addEncryptionAlgorithms(Collection<? extends AeadAlgorithm> encAlgs) {
|
||||
Assert.notEmpty(encAlgs, "Additional AeadAlgorithm collection cannot be null or empty.");
|
||||
this.extraEncAlgs.addAll(encAlgs);
|
||||
public JwtParserBuilder addEncryptionAlgorithms(Collection<? extends AeadAlgorithm> algs) {
|
||||
Assert.notEmpty(algs, "Additional AeadAlgorithm collection cannot be null or empty.");
|
||||
this.extraEncAlgs.addAll(algs);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtParserBuilder addSignatureAlgorithms(Collection<? extends SecureDigestAlgorithm<?, ?>> sigAlgs) {
|
||||
Assert.notEmpty(sigAlgs, "Additional SignatureAlgorithm collection cannot be null or empty.");
|
||||
this.extraSigAlgs.addAll(sigAlgs);
|
||||
public JwtParserBuilder addSignatureAlgorithms(Collection<? extends SecureDigestAlgorithm<?, ?>> algs) {
|
||||
Assert.notEmpty(algs, "Additional SignatureAlgorithm collection cannot be null or empty.");
|
||||
this.extraSigAlgs.addAll(algs);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtParserBuilder addKeyAlgorithms(Collection<? extends KeyAlgorithm<?, ?>> keyAlgs) {
|
||||
Assert.notEmpty(keyAlgs, "Additional KeyAlgorithm collection cannot be null or empty.");
|
||||
this.extraKeyAlgs.addAll(keyAlgs);
|
||||
public JwtParserBuilder addKeyAlgorithms(Collection<? extends KeyAlgorithm<?, ?>> algs) {
|
||||
Assert.notEmpty(algs, "Additional KeyAlgorithm collection cannot be null or empty.");
|
||||
this.extraKeyAlgs.addAll(algs);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -258,7 +299,7 @@ public class DefaultJwtParserBuilder implements JwtParserBuilder {
|
|||
}
|
||||
|
||||
@Override
|
||||
public JwtParserBuilder setKeyLocator(Locator<Key> keyLocator) {
|
||||
public JwtParserBuilder keyLocator(Locator<Key> keyLocator) {
|
||||
this.keyLocator = Assert.notNull(keyLocator, "Key locator cannot be null.");
|
||||
return this;
|
||||
}
|
||||
|
@ -304,8 +345,8 @@ public class DefaultJwtParserBuilder implements JwtParserBuilder {
|
|||
keyLocator = new ConstantKeyLocator(this.signatureVerificationKey, this.decryptionKey);
|
||||
}
|
||||
|
||||
if (!enableUnsecuredJws && enableUnsecuredDecompression) {
|
||||
String msg = "'enableUnsecuredDecompression' is only relevant if 'enableUnsecuredJws' is also " +
|
||||
if (!enableUnsecured && enableUnsecuredDecompression) {
|
||||
String msg = "'enableUnsecuredDecompression' is only relevant if 'enableUnsecured' is also " +
|
||||
"configured. Please read the JavaDoc of both features before enabling either " +
|
||||
"due to their security implications.";
|
||||
throw new IllegalStateException(msg);
|
||||
|
@ -324,13 +365,13 @@ public class DefaultJwtParserBuilder implements JwtParserBuilder {
|
|||
return new DefaultJwtParser(
|
||||
provider,
|
||||
signingKeyResolver,
|
||||
enableUnsecuredJws,
|
||||
enableUnsecured,
|
||||
enableUnsecuredDecompression,
|
||||
keyLocator,
|
||||
clock,
|
||||
allowedClockSkewMillis,
|
||||
expClaims,
|
||||
base64UrlDecoder,
|
||||
decoder,
|
||||
new JwtDeserializer<>(deserializer),
|
||||
compressionCodecResolver,
|
||||
extraZipAlgs,
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2015 jsonwebtoken.io
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.jsonwebtoken.impl;
|
||||
|
||||
/**
|
||||
* @deprecated since 0.10.0
|
||||
*/
|
||||
@Deprecated //remove just before 1.0.0 release
|
||||
public class DefaultTextCodecFactory implements TextCodecFactory {
|
||||
|
||||
protected String getSystemProperty(String key) {
|
||||
return System.getProperty(key);
|
||||
}
|
||||
|
||||
protected boolean isAndroid() {
|
||||
|
||||
String name = getSystemProperty("java.vm.name");
|
||||
if (name != null) {
|
||||
String lcase = name.toLowerCase();
|
||||
return lcase.contains("dalvik");
|
||||
}
|
||||
|
||||
name = getSystemProperty("java.vm.vendor");
|
||||
if (name != null) {
|
||||
String lcase = name.toLowerCase();
|
||||
return lcase.contains("android");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public TextCodec getTextCodec() {
|
||||
|
||||
if (isAndroid()) {
|
||||
return new AndroidBase64Codec();
|
||||
}
|
||||
|
||||
return new Base64Codec();
|
||||
}
|
||||
}
|
|
@ -24,12 +24,12 @@ import java.util.Map;
|
|||
class DefaultTokenizedJwt implements TokenizedJwt {
|
||||
|
||||
private final String protectedHeader;
|
||||
private final String body;
|
||||
private final String payload;
|
||||
private final String digest;
|
||||
|
||||
DefaultTokenizedJwt(String protectedHeader, String body, String digest) {
|
||||
DefaultTokenizedJwt(String protectedHeader, String payload, String digest) {
|
||||
this.protectedHeader = protectedHeader;
|
||||
this.body = body;
|
||||
this.payload = payload;
|
||||
this.digest = digest;
|
||||
}
|
||||
|
||||
|
@ -39,8 +39,8 @@ class DefaultTokenizedJwt implements TokenizedJwt {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String getBody() {
|
||||
return this.body;
|
||||
public String getPayload() {
|
||||
return this.payload;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* Copyright © 2023 jsonwebtoken.io
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.jsonwebtoken.impl;
|
||||
|
||||
import io.jsonwebtoken.ClaimsMutator;
|
||||
import io.jsonwebtoken.impl.lang.DelegatingMapMutator;
|
||||
import io.jsonwebtoken.impl.lang.Field;
|
||||
import io.jsonwebtoken.lang.MapMutator;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @param <T> subclass type
|
||||
* @since JJWT_RELEASE_VERSION
|
||||
*/
|
||||
public class DelegatingClaimsMutator<T extends MapMutator<String, Object, T> & ClaimsMutator<T>>
|
||||
extends DelegatingMapMutator<String, Object, FieldMap, T>
|
||||
implements ClaimsMutator<T> {
|
||||
|
||||
protected DelegatingClaimsMutator() {
|
||||
super(new FieldMap(DefaultClaims.FIELDS));
|
||||
}
|
||||
|
||||
<F> T put(Field<F> field, Object value) {
|
||||
this.DELEGATE.put(field, value);
|
||||
return self();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T setIssuer(String iss) {
|
||||
return issuer(iss);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T issuer(String iss) {
|
||||
return put(DefaultClaims.ISSUER, iss);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T setSubject(String sub) {
|
||||
return subject(sub);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T subject(String sub) {
|
||||
return put(DefaultClaims.SUBJECT, sub);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T setAudience(String aud) {
|
||||
return audience(aud);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T audience(String aud) {
|
||||
return put(DefaultClaims.AUDIENCE, aud);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T setExpiration(Date exp) {
|
||||
return expiration(exp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T expiration(Date exp) {
|
||||
return put(DefaultClaims.EXPIRATION, exp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T setNotBefore(Date nbf) {
|
||||
return notBefore(nbf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T notBefore(Date nbf) {
|
||||
return put(DefaultClaims.NOT_BEFORE, nbf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T setIssuedAt(Date iat) {
|
||||
return issuedAt(iat);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T issuedAt(Date iat) {
|
||||
return put(DefaultClaims.ISSUED_AT, iat);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T setId(String jti) {
|
||||
return id(jti);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T id(String jti) {
|
||||
return put(DefaultClaims.JTI, jti);
|
||||
}
|
||||
}
|
|
@ -47,9 +47,22 @@ public class IdLocator<H extends Header, R extends Identifiable> implements Loca
|
|||
this.valueRequired = Strings.hasText(this.requiredMsg);
|
||||
Assert.notEmpty(registry, "Registry cannot be null or empty.");
|
||||
Collection<R> all = new LinkedHashSet<>(Collections.size(registry) + Collections.size(extras));
|
||||
all.addAll(registry.values()); // defaults MUST come before extras to allow extras to override if necessary
|
||||
all.addAll(extras);
|
||||
all.addAll(registry.values());
|
||||
this.registry = new IdRegistry<>(field.getName(), all);
|
||||
|
||||
// The registry requires CaSe-SeNsItIvE keys on purpose - all JWA standard algorithm identifiers
|
||||
// (JWS 'alg', JWE 'enc', JWK 'kty', etc) are all case-sensitive per via the following RFC language:
|
||||
//
|
||||
// This name is a case-sensitive ASCII string. Names may not match other registered names in a
|
||||
// case-insensitive manner unless the Designated Experts state that there is a compelling reason to
|
||||
// allow an exception.
|
||||
//
|
||||
// References:
|
||||
// - JWS/JWE alg and JWE enc 'Algorithm Name': https://www.rfc-editor.org/rfc/rfc7518.html#section-7.1.1
|
||||
// - JWE zip 'Compression Algorithm Value': https://www.rfc-editor.org/rfc/rfc7518.html#section-7.3.1
|
||||
// - JWK '"kty" Parameter Value': https://www.rfc-editor.org/rfc/rfc7518.html#section-7.4.1
|
||||
|
||||
this.registry = new IdRegistry<>(field.getName(), all); // do not use the caseSensitive ctor argument - must be false
|
||||
}
|
||||
|
||||
private static String type(Header header) {
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2015 jsonwebtoken.io
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.jsonwebtoken.impl;
|
||||
|
||||
/**
|
||||
* @deprecated since 0.10.0
|
||||
*/
|
||||
@Deprecated
|
||||
public interface TextCodecFactory {
|
||||
|
||||
TextCodec getTextCodec();
|
||||
}
|
|
@ -33,7 +33,7 @@ public interface TokenizedJwt {
|
|||
*
|
||||
* @return the Payload for a JWS or Ciphertext for a JWE.
|
||||
*/
|
||||
String getBody();
|
||||
String getPayload();
|
||||
|
||||
/**
|
||||
* Returns the Signature for JWS or AAD Tag for JWE.
|
||||
|
|
|
@ -41,13 +41,13 @@ public class DelegatingMapMutator<K, V, D extends Map<K, V>, T extends MapMutato
|
|||
}
|
||||
|
||||
@Override
|
||||
public T set(K key, V value) {
|
||||
public T add(K key, V value) {
|
||||
put(key, value);
|
||||
return self();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T set(Map<? extends K, ? extends V> m) {
|
||||
public T add(Map<? extends K, ? extends V> m) {
|
||||
putAll(m);
|
||||
return self();
|
||||
}
|
||||
|
|
|
@ -69,7 +69,7 @@ abstract class AbstractAsymmetricJwkBuilder<K extends Key, J extends AsymmetricJ
|
|||
}
|
||||
|
||||
@Override
|
||||
public T setPublicKeyUse(String use) {
|
||||
public T publicKeyUse(String use) {
|
||||
Assert.hasText(use, "publicKeyUse cannot be null or empty.");
|
||||
this.DELEGATE.setPublicKeyUse(use);
|
||||
return self();
|
||||
|
@ -83,16 +83,16 @@ abstract class AbstractAsymmetricJwkBuilder<K extends Key, J extends AsymmetricJ
|
|||
*/
|
||||
|
||||
@Override
|
||||
public T setX509CertificateChain(List<X509Certificate> chain) {
|
||||
public T x509CertificateChain(List<X509Certificate> chain) {
|
||||
Assert.notEmpty(chain, "X509Certificate chain cannot be null or empty.");
|
||||
this.x509.setX509CertificateChain(chain);
|
||||
this.x509.x509CertificateChain(chain);
|
||||
return self();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T setX509Url(URI uri) {
|
||||
public T x509Url(URI uri) {
|
||||
Assert.notNull(uri, "X509Url cannot be null.");
|
||||
this.x509.setX509Url(uri);
|
||||
this.x509.x509Url(uri);
|
||||
return self();
|
||||
}
|
||||
|
||||
|
@ -105,14 +105,14 @@ abstract class AbstractAsymmetricJwkBuilder<K extends Key, J extends AsymmetricJ
|
|||
*/
|
||||
|
||||
@Override
|
||||
public T setX509CertificateSha1Thumbprint(byte[] thumbprint) {
|
||||
this.x509.setX509CertificateSha1Thumbprint(thumbprint);
|
||||
public T x509CertificateSha1Thumbprint(byte[] thumbprint) {
|
||||
this.x509.x509CertificateSha1Thumbprint(thumbprint);
|
||||
return self();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T setX509CertificateSha256Thumbprint(byte[] thumbprint) {
|
||||
this.x509.setX509CertificateSha256Thumbprint(thumbprint);
|
||||
public T x509CertificateSha256Thumbprint(byte[] thumbprint) {
|
||||
this.x509.x509CertificateSha256Thumbprint(thumbprint);
|
||||
return self();
|
||||
}
|
||||
|
||||
|
@ -145,10 +145,10 @@ abstract class AbstractAsymmetricJwkBuilder<K extends Key, J extends AsymmetricJ
|
|||
}
|
||||
|
||||
@Override
|
||||
public P setPrivateKey(L privateKey) {
|
||||
public P privateKey(L privateKey) {
|
||||
Assert.notNull(privateKey, "PrivateKey argument cannot be null.");
|
||||
final K publicKey = Assert.notNull(DELEGATE.getKey(), "PublicKey cannot be null.");
|
||||
return newPrivateBuilder(newContext(privateKey)).setPublicKey(publicKey);
|
||||
return newPrivateBuilder(newContext(privateKey)).publicKey(publicKey);
|
||||
}
|
||||
|
||||
protected abstract P newPrivateBuilder(JwkContext<L> ctx);
|
||||
|
@ -170,7 +170,7 @@ abstract class AbstractAsymmetricJwkBuilder<K extends Key, J extends AsymmetricJ
|
|||
}
|
||||
|
||||
@Override
|
||||
public T setPublicKey(L publicKey) {
|
||||
public T publicKey(L publicKey) {
|
||||
this.DELEGATE.setPublicKey(publicKey);
|
||||
return self();
|
||||
}
|
||||
|
|
|
@ -54,26 +54,26 @@ abstract class AbstractJwkBuilder<K extends Key, J extends Jwk<K>, T extends Jwk
|
|||
}
|
||||
|
||||
@Override
|
||||
public T setProvider(Provider provider) {
|
||||
public T provider(Provider provider) {
|
||||
this.DELEGATE.setProvider(provider);
|
||||
return self();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T setRandom(SecureRandom random) {
|
||||
public T random(SecureRandom random) {
|
||||
this.DELEGATE.setRandom(random);
|
||||
return self();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T setAlgorithm(String alg) {
|
||||
public T algorithm(String alg) {
|
||||
Assert.hasText(alg, "Algorithm cannot be null or empty.");
|
||||
this.DELEGATE.setAlgorithm(alg);
|
||||
return self();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T setId(String id) {
|
||||
public T id(String id) {
|
||||
Assert.hasText(id, "Id cannot be null or empty.");
|
||||
this.DELEGATE.setIdThumbprintAlgorithm(null); //clear out any previously set value
|
||||
this.DELEGATE.setId(id);
|
||||
|
@ -81,12 +81,12 @@ abstract class AbstractJwkBuilder<K extends Key, J extends Jwk<K>, T extends Jwk
|
|||
}
|
||||
|
||||
@Override
|
||||
public T setIdFromThumbprint() {
|
||||
return setIdFromThumbprint(Jwks.HASH.SHA256);
|
||||
public T idFromThumbprint() {
|
||||
return idFromThumbprint(Jwks.HASH.SHA256);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T setIdFromThumbprint(HashAlgorithm alg) {
|
||||
public T idFromThumbprint(HashAlgorithm alg) {
|
||||
Assert.notNull(alg, "Thumbprint HashAlgorithm cannot be null.");
|
||||
Assert.notNull(alg.getId(), "Thumbprint HashAlgorithm ID cannot be null.");
|
||||
this.DELEGATE.setId(null); // clear out any previous value
|
||||
|
@ -95,7 +95,7 @@ abstract class AbstractJwkBuilder<K extends Key, J extends Jwk<K>, T extends Jwk
|
|||
}
|
||||
|
||||
@Override
|
||||
public T setOperations(Set<String> ops) {
|
||||
public T operations(Set<String> ops) {
|
||||
Assert.notEmpty(ops, "Operations cannot be null or empty.");
|
||||
this.DELEGATE.setOperations(ops);
|
||||
return self();
|
||||
|
|
|
@ -81,7 +81,7 @@ abstract class AesAlgorithm extends CryptoAlgorithm implements KeyBuilderSupplie
|
|||
}
|
||||
|
||||
@Override
|
||||
public SecretKeyBuilder keyBuilder() {
|
||||
public SecretKeyBuilder key() {
|
||||
return new DefaultSecretKeyBuilder(KEY_ALG_NAME, getKeyBitLength());
|
||||
}
|
||||
|
||||
|
|
|
@ -92,8 +92,8 @@ abstract class CryptoAlgorithm implements Identifiable {
|
|||
|
||||
protected SecretKey generateKey(KeyRequest<?> request) {
|
||||
AeadAlgorithm enc = Assert.notNull(request.getEncryptionAlgorithm(), "Request encryptionAlgorithm cannot be null.");
|
||||
SecretKeyBuilder builder = Assert.notNull(enc.keyBuilder(), "Request encryptionAlgorithm keyBuilder cannot be null.");
|
||||
SecretKey key = builder.setProvider(getProvider(request)).setRandom(request.getSecureRandom()).build();
|
||||
SecretKeyBuilder builder = Assert.notNull(enc.key(), "Request encryptionAlgorithm KeyBuilder cannot be null.");
|
||||
SecretKey key = builder.provider(getProvider(request)).random(request.getSecureRandom()).build();
|
||||
return Assert.notNull(key, "Request encryptionAlgorithm SecretKeyBuilder cannot produce null keys.");
|
||||
}
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ class DefaultCurve implements Curve {
|
|||
return ID;
|
||||
}
|
||||
|
||||
public KeyPairBuilder keyPairBuilder() {
|
||||
return new DefaultKeyPairBuilder(this.JCA_NAME).setProvider(this.PROVIDER);
|
||||
public KeyPairBuilder keyPair() {
|
||||
return new DefaultKeyPairBuilder(this.JCA_NAME).provider(this.PROVIDER);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,16 +15,15 @@
|
|||
*/
|
||||
package io.jsonwebtoken.impl.security;
|
||||
|
||||
import io.jsonwebtoken.lang.Arrays;
|
||||
import io.jsonwebtoken.lang.Assert;
|
||||
import io.jsonwebtoken.lang.Strings;
|
||||
import io.jsonwebtoken.security.DynamicJwkBuilder;
|
||||
import io.jsonwebtoken.security.EcPrivateJwkBuilder;
|
||||
import io.jsonwebtoken.security.EcPublicJwkBuilder;
|
||||
import io.jsonwebtoken.security.Jwk;
|
||||
import io.jsonwebtoken.security.OctetPrivateJwkBuilder;
|
||||
import io.jsonwebtoken.security.OctetPublicJwkBuilder;
|
||||
import io.jsonwebtoken.security.PrivateJwkBuilder;
|
||||
import io.jsonwebtoken.security.ProtoJwkBuilder;
|
||||
import io.jsonwebtoken.security.PublicJwkBuilder;
|
||||
import io.jsonwebtoken.security.RsaPrivateJwkBuilder;
|
||||
import io.jsonwebtoken.security.RsaPublicJwkBuilder;
|
||||
|
@ -44,35 +43,35 @@ import java.security.interfaces.RSAPublicKey;
|
|||
import java.util.List;
|
||||
|
||||
@SuppressWarnings("unused") //used via reflection by io.jsonwebtoken.security.Jwks
|
||||
public class DefaultProtoJwkBuilder<K extends Key, J extends Jwk<K>>
|
||||
extends AbstractJwkBuilder<K, J, ProtoJwkBuilder<K, J>> implements ProtoJwkBuilder<K, J> {
|
||||
public class DefaultDynamicJwkBuilder<K extends Key, J extends Jwk<K>>
|
||||
extends AbstractJwkBuilder<K, J, DynamicJwkBuilder<K, J>> implements DynamicJwkBuilder<K, J> {
|
||||
|
||||
public DefaultProtoJwkBuilder() {
|
||||
public DefaultDynamicJwkBuilder() {
|
||||
super(new DefaultJwkContext<K>());
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecretJwkBuilder forKey(SecretKey key) {
|
||||
public SecretJwkBuilder key(SecretKey key) {
|
||||
return new AbstractJwkBuilder.DefaultSecretJwkBuilder(newContext(key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public RsaPublicJwkBuilder forKey(RSAPublicKey key) {
|
||||
public RsaPublicJwkBuilder key(RSAPublicKey key) {
|
||||
return new AbstractAsymmetricJwkBuilder.DefaultRsaPublicJwkBuilder(newContext(key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public RsaPrivateJwkBuilder forKey(RSAPrivateKey key) {
|
||||
public RsaPrivateJwkBuilder key(RSAPrivateKey key) {
|
||||
return new AbstractAsymmetricJwkBuilder.DefaultRsaPrivateJwkBuilder(newContext(key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public EcPublicJwkBuilder forKey(ECPublicKey key) {
|
||||
public EcPublicJwkBuilder key(ECPublicKey key) {
|
||||
return new AbstractAsymmetricJwkBuilder.DefaultEcPublicJwkBuilder(newContext(key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public EcPrivateJwkBuilder forKey(ECPrivateKey key) {
|
||||
public EcPrivateJwkBuilder key(ECPrivateKey key) {
|
||||
return new AbstractAsymmetricJwkBuilder.DefaultEcPrivateJwkBuilder(newContext(key));
|
||||
}
|
||||
|
||||
|
@ -84,14 +83,14 @@ public class DefaultProtoJwkBuilder<K extends Key, J extends Jwk<K>>
|
|||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <A extends PublicKey, B extends PrivateKey> PublicJwkBuilder<A, B, ?, ?, ?, ?> forKey(A key) {
|
||||
public <A extends PublicKey, B extends PrivateKey> PublicJwkBuilder<A, B, ?, ?, ?, ?> key(A key) {
|
||||
if (key instanceof RSAPublicKey) {
|
||||
return (PublicJwkBuilder<A, B, ?, ?, ?, ?>) forKey((RSAPublicKey) key);
|
||||
return (PublicJwkBuilder<A, B, ?, ?, ?, ?>) key((RSAPublicKey) key);
|
||||
} else if (key instanceof ECPublicKey) {
|
||||
return (PublicJwkBuilder<A, B, ?, ?, ?, ?>) forKey((ECPublicKey) key);
|
||||
return (PublicJwkBuilder<A, B, ?, ?, ?, ?>) key((ECPublicKey) key);
|
||||
} else {
|
||||
try {
|
||||
return forOctetKey(key);
|
||||
return octetKey(key);
|
||||
} catch (Exception e) {
|
||||
throw unsupportedKey(key, e);
|
||||
}
|
||||
|
@ -100,15 +99,15 @@ public class DefaultProtoJwkBuilder<K extends Key, J extends Jwk<K>>
|
|||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <A extends PublicKey, B extends PrivateKey> PrivateJwkBuilder<B, A, ?, ?, ?> forKey(B key) {
|
||||
public <A extends PublicKey, B extends PrivateKey> PrivateJwkBuilder<B, A, ?, ?, ?> key(B key) {
|
||||
Assert.notNull(key, "Key cannot be null.");
|
||||
if (key instanceof RSAPrivateKey) {
|
||||
return (PrivateJwkBuilder<B, A, ?, ?, ?>) forKey((RSAPrivateKey) key);
|
||||
return (PrivateJwkBuilder<B, A, ?, ?, ?>) key((RSAPrivateKey) key);
|
||||
} else if (key instanceof ECPrivateKey) {
|
||||
return (PrivateJwkBuilder<B, A, ?, ?, ?>) forKey((ECPrivateKey) key);
|
||||
return (PrivateJwkBuilder<B, A, ?, ?, ?>) key((ECPrivateKey) key);
|
||||
} else {
|
||||
try {
|
||||
return forOctetKey(key);
|
||||
return octetKey(key);
|
||||
} catch (Exception e) {
|
||||
throw unsupportedKey(key, e);
|
||||
}
|
||||
|
@ -116,84 +115,85 @@ public class DefaultProtoJwkBuilder<K extends Key, J extends Jwk<K>>
|
|||
}
|
||||
|
||||
@Override
|
||||
public <A extends PublicKey, B extends PrivateKey> OctetPublicJwkBuilder<A, B> forOctetKey(A key) {
|
||||
public <A extends PublicKey, B extends PrivateKey> OctetPublicJwkBuilder<A, B> octetKey(A key) {
|
||||
return new AbstractAsymmetricJwkBuilder.DefaultOctetPublicJwkBuilder<>(newContext(key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <A extends PrivateKey, B extends PublicKey> OctetPrivateJwkBuilder<A, B> forOctetKey(A key) {
|
||||
public <A extends PrivateKey, B extends PublicKey> OctetPrivateJwkBuilder<A, B> octetKey(A key) {
|
||||
return new AbstractAsymmetricJwkBuilder.DefaultOctetPrivateJwkBuilder<>(newContext(key));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public RsaPublicJwkBuilder forRsaChain(X509Certificate... chain) {
|
||||
public <A extends PublicKey, B extends PrivateKey> PublicJwkBuilder<A, B, ?, ?, ?, ?> chain(List<X509Certificate> chain)
|
||||
throws UnsupportedKeyException {
|
||||
Assert.notEmpty(chain, "chain cannot be null or empty.");
|
||||
return forRsaChain(Arrays.asList(chain));
|
||||
X509Certificate cert = Assert.notNull(chain.get(0), "The first X509Certificate cannot be null.");
|
||||
PublicKey key = Assert.notNull(cert.getPublicKey(), "The first X509Certificate's PublicKey cannot be null.");
|
||||
return this.<A,B>key((A)key).x509CertificateChain(chain);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RsaPublicJwkBuilder forRsaChain(List<X509Certificate> chain) {
|
||||
public RsaPublicJwkBuilder rsaChain(List<X509Certificate> chain) {
|
||||
Assert.notEmpty(chain, "X509Certificate chain cannot be empty.");
|
||||
X509Certificate cert = chain.get(0);
|
||||
PublicKey key = cert.getPublicKey();
|
||||
RSAPublicKey pubKey = KeyPairs.assertKey(key, RSAPublicKey.class, "The first X509Certificate's ");
|
||||
return forKey(pubKey).setX509CertificateChain(chain);
|
||||
return key(pubKey).x509CertificateChain(chain);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EcPublicJwkBuilder forEcChain(X509Certificate... chain) {
|
||||
Assert.notEmpty(chain, "chain cannot be null or empty.");
|
||||
return forEcChain(Arrays.asList(chain));
|
||||
}
|
||||
|
||||
@Override
|
||||
public EcPublicJwkBuilder forEcChain(List<X509Certificate> chain) {
|
||||
public EcPublicJwkBuilder ecChain(List<X509Certificate> chain) {
|
||||
Assert.notEmpty(chain, "X509Certificate chain cannot be empty.");
|
||||
X509Certificate cert = chain.get(0);
|
||||
PublicKey key = cert.getPublicKey();
|
||||
ECPublicKey pubKey = KeyPairs.assertKey(key, ECPublicKey.class, "The first X509Certificate's ");
|
||||
return forKey(pubKey).setX509CertificateChain(chain);
|
||||
return key(pubKey).x509CertificateChain(chain);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked") // ok because of the EdwardsCurve.assertEdwards calls
|
||||
@Override
|
||||
public <A extends PrivateKey, B extends PublicKey> OctetPrivateJwkBuilder<A, B> forOctetKeyPair(KeyPair pair) {
|
||||
public <A extends PrivateKey, B extends PublicKey> OctetPrivateJwkBuilder<A, B> octetKeyPair(KeyPair pair) {
|
||||
PublicKey pub = KeyPairs.getKey(pair, PublicKey.class);
|
||||
PrivateKey priv = KeyPairs.getKey(pair, PrivateKey.class);
|
||||
EdwardsCurve.assertEdwards(pub);
|
||||
EdwardsCurve.assertEdwards(priv);
|
||||
return (OctetPrivateJwkBuilder<A, B>) forOctetKey(priv).setPublicKey(pub);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <A extends PublicKey, B extends PrivateKey> OctetPublicJwkBuilder<A, B> forOctetChain(X509Certificate... chain) {
|
||||
Assert.notEmpty(chain, "X509Certificate chain cannot be null or empty.");
|
||||
return forOctetChain(Arrays.asList(chain));
|
||||
return (OctetPrivateJwkBuilder<A, B>) octetKey(priv).publicKey(pub);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked") // ok because of the EdwardsCurve.assertEdwards calls
|
||||
@Override
|
||||
public <A extends PublicKey, B extends PrivateKey> OctetPublicJwkBuilder<A, B> forOctetChain(List<X509Certificate> chain) {
|
||||
public <A extends PublicKey, B extends PrivateKey> OctetPublicJwkBuilder<A, B> octetChain(List<X509Certificate> chain) {
|
||||
Assert.notEmpty(chain, "X509Certificate chain cannot be empty.");
|
||||
X509Certificate cert = chain.get(0);
|
||||
PublicKey key = cert.getPublicKey();
|
||||
Assert.notNull(key, "The first X509Certificate's PublicKey cannot be null.");
|
||||
EdwardsCurve.assertEdwards(key);
|
||||
return this.<A, B>forOctetKey((A) key).setX509CertificateChain(chain);
|
||||
return this.<A, B>octetKey((A) key).x509CertificateChain(chain);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RsaPrivateJwkBuilder forRsaKeyPair(KeyPair pair) {
|
||||
public RsaPrivateJwkBuilder rsaKeyPair(KeyPair pair) {
|
||||
RSAPublicKey pub = KeyPairs.getKey(pair, RSAPublicKey.class);
|
||||
RSAPrivateKey priv = KeyPairs.getKey(pair, RSAPrivateKey.class);
|
||||
return forKey(priv).setPublicKey(pub);
|
||||
return key(priv).publicKey(pub);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EcPrivateJwkBuilder forEcKeyPair(KeyPair pair) {
|
||||
public EcPrivateJwkBuilder ecKeyPair(KeyPair pair) {
|
||||
ECPublicKey pub = KeyPairs.getKey(pair, ECPublicKey.class);
|
||||
ECPrivateKey priv = KeyPairs.getKey(pair, ECPrivateKey.class);
|
||||
return forKey(priv).setPublicKey(pub);
|
||||
return key(priv).publicKey(pub);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <A extends PublicKey, B extends PrivateKey> PrivateJwkBuilder<B, A, ?, ?, ?> keyPair(KeyPair keyPair)
|
||||
throws UnsupportedKeyException {
|
||||
A pub = (A)KeyPairs.getKey(keyPair, PublicKey.class);
|
||||
B priv = (B)KeyPairs.getKey(keyPair, PrivateKey.class);
|
||||
return this.<A,B>key(priv).publicKey(pub);
|
||||
}
|
||||
|
||||
@Override
|
|
@ -59,9 +59,9 @@ public class DefaultJwkParser implements JwkParser {
|
|||
JwkBuilder<?, ?, ?> builder = Jwks.builder();
|
||||
|
||||
if (this.provider != null) {
|
||||
builder.setProvider(this.provider);
|
||||
builder.provider(this.provider);
|
||||
}
|
||||
|
||||
return builder.set(data).build();
|
||||
return builder.add(data).build();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ public class DefaultJwkParserBuilder implements JwkParserBuilder {
|
|||
private Deserializer<Map<String,?>> deserializer;
|
||||
|
||||
@Override
|
||||
public JwkParserBuilder setProvider(Provider provider) {
|
||||
public JwkParserBuilder provider(Provider provider) {
|
||||
this.provider = provider;
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -50,13 +50,13 @@ public class DefaultKeyPairBuilder implements KeyPairBuilder {
|
|||
}
|
||||
|
||||
@Override
|
||||
public KeyPairBuilder setProvider(Provider provider) {
|
||||
public KeyPairBuilder provider(Provider provider) {
|
||||
this.provider = provider;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeyPairBuilder setRandom(SecureRandom random) {
|
||||
public KeyPairBuilder random(SecureRandom random) {
|
||||
this.random = random;
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -81,7 +81,7 @@ public class DefaultMacAlgorithm extends AbstractSecureDigestAlgorithm<SecretKey
|
|||
}
|
||||
|
||||
@Override
|
||||
public SecretKeyBuilder keyBuilder() {
|
||||
public SecretKeyBuilder key() {
|
||||
return new DefaultSecretKeyBuilder(getJcaName(), getKeyBitLength());
|
||||
}
|
||||
|
||||
|
@ -142,8 +142,8 @@ public class DefaultMacAlgorithm extends AbstractSecureDigestAlgorithm<SecretKey
|
|||
msg += " The JWT " +
|
||||
"JWA Specification (RFC 7518, Section 3.2) states that keys used with " + id + " MUST have a " +
|
||||
"size >= " + minKeyBitLength + " bits (the key size must be greater than or equal to the hash " +
|
||||
"output size). Consider using the Jwts.SIG." + id + ".keyBuilder() " +
|
||||
"method to create a key guaranteed to be secure enough for " + id + ". See " +
|
||||
"output size). Consider using the Jwts.SIG." + id + ".key() " +
|
||||
"builder to create a key guaranteed to be secure enough for " + id + ". See " +
|
||||
"https://tools.ietf.org/html/rfc7518#section-3.2 for more information.";
|
||||
} else { //custom algorithm - just indicate required key length:
|
||||
msg += " The " + id + " algorithm requires keys to have a size >= " + minKeyBitLength + " bits.";
|
||||
|
|
|
@ -39,17 +39,17 @@ public class DefaultSecretKeyBuilder implements SecretKeyBuilder {
|
|||
throw new IllegalArgumentException(msg);
|
||||
}
|
||||
this.BIT_LENGTH = Assert.gt(bitLength, 0, "bitLength must be > 0");
|
||||
setRandom(Randoms.secureRandom());
|
||||
random(Randoms.secureRandom());
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecretKeyBuilder setProvider(Provider provider) {
|
||||
public SecretKeyBuilder provider(Provider provider) {
|
||||
this.provider = provider;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecretKeyBuilder setRandom(SecureRandom random) {
|
||||
public SecretKeyBuilder random(SecureRandom random) {
|
||||
this.random = random != null ? random : Randoms.secureRandom();
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ public class ECCurve extends DefaultCurve {
|
|||
}
|
||||
|
||||
@Override
|
||||
public KeyPairBuilder keyPairBuilder() {
|
||||
public KeyPairBuilder keyPair() {
|
||||
return new DefaultKeyPairBuilder(KEY_PAIR_GENERATOR_JCA_NAME, toParameterSpec());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -100,10 +100,10 @@ public class EcSignatureAlgorithm extends AbstractSignatureAlgorithm {
|
|||
}
|
||||
|
||||
@Override
|
||||
public KeyPairBuilder keyPairBuilder() {
|
||||
public KeyPairBuilder keyPair() {
|
||||
return new DefaultKeyPairBuilder(ECCurve.KEY_PAIR_GENERATOR_JCA_NAME, this.KEY_PAIR_GEN_PARAMS)
|
||||
.setProvider(getProvider())
|
||||
.setRandom(Randoms.secureRandom());
|
||||
.provider(getProvider())
|
||||
.random(Randoms.secureRandom());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -25,6 +25,7 @@ import io.jsonwebtoken.lang.Arrays;
|
|||
import io.jsonwebtoken.lang.Assert;
|
||||
import io.jsonwebtoken.security.AeadAlgorithm;
|
||||
import io.jsonwebtoken.security.DecryptionKeyRequest;
|
||||
import io.jsonwebtoken.security.DynamicJwkBuilder;
|
||||
import io.jsonwebtoken.security.EcPublicJwk;
|
||||
import io.jsonwebtoken.security.InvalidKeyException;
|
||||
import io.jsonwebtoken.security.Jwks;
|
||||
|
@ -33,7 +34,6 @@ import io.jsonwebtoken.security.KeyLengthSupplier;
|
|||
import io.jsonwebtoken.security.KeyRequest;
|
||||
import io.jsonwebtoken.security.KeyResult;
|
||||
import io.jsonwebtoken.security.OctetPublicJwk;
|
||||
import io.jsonwebtoken.security.ProtoJwkBuilder;
|
||||
import io.jsonwebtoken.security.PublicJwk;
|
||||
import io.jsonwebtoken.security.Request;
|
||||
import io.jsonwebtoken.security.SecureRequest;
|
||||
|
@ -98,7 +98,7 @@ class EcdhKeyAlgorithm extends CryptoAlgorithm implements KeyAlgorithm<PublicKey
|
|||
|
||||
//visible for testing, for Edwards elliptic curves
|
||||
protected KeyPair generateKeyPair(SecureRandom random, EdwardsCurve curve, Provider provider) {
|
||||
return curve.keyPairBuilder().setProvider(provider).setRandom(random).build();
|
||||
return curve.keyPair().provider(provider).random(random).build();
|
||||
}
|
||||
|
||||
protected byte[] generateZ(final KeyRequest<?> request, final PublicKey pub, final PrivateKey priv) {
|
||||
|
@ -183,7 +183,7 @@ class EcdhKeyAlgorithm extends CryptoAlgorithm implements KeyAlgorithm<PublicKey
|
|||
|
||||
KeyPair pair; // generated (ephemeral) key pair
|
||||
final SecureRandom random = ensureSecureRandom(request);
|
||||
ProtoJwkBuilder<?, ?> jwkBuilder = Jwks.builder().setRandom(random);
|
||||
DynamicJwkBuilder<?, ?> jwkBuilder = Jwks.builder().random(random);
|
||||
|
||||
if (publicKey instanceof ECKey) {
|
||||
ECKey ecPublicKey = (ECKey) publicKey;
|
||||
|
@ -204,13 +204,13 @@ class EcdhKeyAlgorithm extends CryptoAlgorithm implements KeyAlgorithm<PublicKey
|
|||
request.getHeader(), request.getEncryptionAlgorithm());
|
||||
}
|
||||
pair = generateKeyPair(random, curve, provider);
|
||||
jwkBuilder.setProvider(provider);
|
||||
jwkBuilder.provider(provider);
|
||||
}
|
||||
|
||||
Assert.stateNotNull(pair, "Internal implementation state: KeyPair cannot be null.");
|
||||
|
||||
// This asserts that the generated public key (and therefore the request key) is on a JWK-supported curve:
|
||||
PublicJwk<?> jwk = jwkBuilder.forKey(pair.getPublic()).build();
|
||||
PublicJwk<?> jwk = jwkBuilder.key(pair.getPublic()).build();
|
||||
|
||||
final SecretKey derived = deriveKey(request, publicKey, pair.getPrivate());
|
||||
|
||||
|
|
|
@ -64,8 +64,8 @@ public class EdSignatureAlgorithm extends AbstractSignatureAlgorithm {
|
|||
}
|
||||
|
||||
@Override
|
||||
public KeyPairBuilder keyPairBuilder() {
|
||||
return this.preferredCurve.keyPairBuilder();
|
||||
public KeyPairBuilder keyPair() {
|
||||
return this.preferredCurve.keyPair();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -357,8 +357,8 @@ public class EdwardsCurve extends DefaultCurve implements KeyLengthSupplier {
|
|||
}
|
||||
|
||||
@Override
|
||||
public KeyPairBuilder keyPairBuilder() {
|
||||
return new DefaultKeyPairBuilder(getJcaName(), KEY_PAIR_GENERATOR_BIT_LENGTH).setProvider(getProvider());
|
||||
public KeyPairBuilder keyPair() {
|
||||
return new DefaultKeyPairBuilder(getJcaName(), KEY_PAIR_GENERATOR_BIT_LENGTH).provider(getProvider());
|
||||
}
|
||||
|
||||
public static boolean isEdwards(Key key) {
|
||||
|
|
|
@ -51,7 +51,7 @@ final class EdwardsPublicKeyDeriver implements Function<PrivateKey, PublicKey> {
|
|||
// Since we already have a private key, we provide a RNG that 'generates' the existing private key
|
||||
// instead of a random one, and the corresponding public key will be computed for us automatically.
|
||||
SecureRandom random = new ConstantRandom(pkBytes);
|
||||
KeyPair pair = curve.keyPairBuilder().setRandom(random).build();
|
||||
KeyPair pair = curve.keyPair().random(random).build();
|
||||
Assert.stateNotNull(pair, "Edwards curve generated keypair cannot be null.");
|
||||
return Assert.stateNotNull(pair.getPublic(), "Edwards curve KeyPair must have a PublicKey");
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ public class HmacAesAeadAlgorithm extends AesAlgorithm implements AeadAlgorithm
|
|||
}
|
||||
|
||||
@Override
|
||||
public SecretKeyBuilder keyBuilder() {
|
||||
public SecretKeyBuilder key() {
|
||||
// The Sun JCE KeyGenerator throws an exception if bitLengths are not standard AES 128, 192 or 256 values.
|
||||
// Since the JWA HmacAes algorithms require double that, we use secure-random keys instead:
|
||||
return new RandomSecretKeyBuilder(KEY_ALG_NAME, getKeyBitLength());
|
||||
|
|
|
@ -121,7 +121,7 @@ public final class JwkConverter<T extends Jwk<?>> implements Converter<T, Object
|
|||
throw new IllegalArgumentException(msg);
|
||||
}
|
||||
String skey = (String) key;
|
||||
builder.set(skey, entry.getValue());
|
||||
builder.add(skey, entry.getValue());
|
||||
}
|
||||
|
||||
Jwk<?> jwk = builder.build();
|
||||
|
|
|
@ -30,7 +30,7 @@ public final class KeysBridge {
|
|||
private KeysBridge() {
|
||||
}
|
||||
|
||||
public static Password forPassword(char[] password) {
|
||||
public static Password password(char[] password) {
|
||||
return new PasswordSpec(password);
|
||||
}
|
||||
|
||||
|
|
|
@ -78,10 +78,10 @@ public class RsaSignatureAlgorithm extends AbstractSignatureAlgorithm {
|
|||
}
|
||||
|
||||
@Override
|
||||
public KeyPairBuilder keyPairBuilder() {
|
||||
public KeyPairBuilder keyPair() {
|
||||
return new DefaultKeyPairBuilder("RSA", this.preferredKeyBitLength)
|
||||
.setProvider(getProvider())
|
||||
.setRandom(Randoms.secureRandom());
|
||||
.provider(getProvider())
|
||||
.random(Randoms.secureRandom());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -144,8 +144,8 @@ public final class StandardKeyAlgorithms extends DelegatingRegistry<String, KeyA
|
|||
for (int i = 0; points.size() < NUM_SAMPLES; i++) {
|
||||
|
||||
char[] password = randomChars(PASSWORD_LENGTH);
|
||||
Password key = Keys.forPassword(password);
|
||||
HEADER.setPbes2Count(workFactor);
|
||||
Password key = Keys.password(password);
|
||||
HEADER.pbes2Count(workFactor);
|
||||
KeyRequest<Password> request = new DefaultKeyRequest<>(null, null, key, HEADER, ENC_ALG);
|
||||
|
||||
long start = System.currentTimeMillis();
|
||||
|
|
|
@ -72,25 +72,25 @@ public class X509BuilderSupport implements X509Builder<X509BuilderSupport> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public X509BuilderSupport setX509Url(URI uri) {
|
||||
public X509BuilderSupport x509Url(URI uri) {
|
||||
this.fieldMap.put(AbstractAsymmetricJwk.X5U.getId(), uri);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public X509BuilderSupport setX509CertificateChain(List<X509Certificate> chain) {
|
||||
public X509BuilderSupport x509CertificateChain(List<X509Certificate> chain) {
|
||||
this.fieldMap.put(AbstractAsymmetricJwk.X5C.getId(), chain);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public X509BuilderSupport setX509CertificateSha1Thumbprint(byte[] thumbprint) {
|
||||
public X509BuilderSupport x509CertificateSha1Thumbprint(byte[] thumbprint) {
|
||||
this.fieldMap.put(AbstractAsymmetricJwk.X5T.getId(), thumbprint);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public X509BuilderSupport setX509CertificateSha256Thumbprint(byte[] thumbprint) {
|
||||
public X509BuilderSupport x509CertificateSha256Thumbprint(byte[] thumbprint) {
|
||||
this.fieldMap.put(AbstractAsymmetricJwk.X5T_S256.getId(), thumbprint);
|
||||
return this;
|
||||
}
|
||||
|
@ -118,11 +118,11 @@ public class X509BuilderSupport implements X509Builder<X509BuilderSupport> {
|
|||
if (firstCert != null) {
|
||||
if (computeX509Sha1Thumbprint) {
|
||||
byte[] thumbprint = computeThumbprint(firstCert, DefaultHashAlgorithm.SHA1);
|
||||
setX509CertificateSha1Thumbprint(thumbprint);
|
||||
x509CertificateSha1Thumbprint(thumbprint);
|
||||
}
|
||||
if (computeX509Sha256) {
|
||||
byte[] thumbprint = computeThumbprint(firstCert, Jwks.HASH.SHA256);
|
||||
setX509CertificateSha256Thumbprint(thumbprint);
|
||||
x509CertificateSha256Thumbprint(thumbprint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,13 +37,13 @@ class CustomObjectDeserializationTest {
|
|||
String jwtString = Jwts.builder().claim("cust", customBean).compact()
|
||||
|
||||
// no custom deserialization, object is a map
|
||||
Jwt<Header, Claims> jwt = Jwts.parser().enableUnsecuredJws().build().parseClaimsJwt(jwtString)
|
||||
Jwt<Header, Claims> jwt = Jwts.parser().enableUnsecured().build().parseClaimsJwt(jwtString)
|
||||
assertNotNull jwt
|
||||
assertEquals jwt.getPayload().get('cust'), [key1: 'value1', key2: 42]
|
||||
|
||||
// custom type for 'cust' claim
|
||||
Deserializer deserializer = new JacksonDeserializer([cust: CustomBean])
|
||||
jwt = Jwts.parser().enableUnsecuredJws().deserializeJsonWith(deserializer).build().parseClaimsJwt(jwtString)
|
||||
jwt = Jwts.parser().enableUnsecured().deserializeJsonWith(deserializer).build().parseClaimsJwt(jwtString)
|
||||
assertNotNull jwt
|
||||
CustomBean result = jwt.getPayload().get("cust", CustomBean)
|
||||
assertEquals customBean, result
|
||||
|
|
|
@ -69,7 +69,7 @@ class JwtParserTest {
|
|||
String bad = base64Url('{"alg":"none"}') + '.' + base64Url(junkPayload) + '.'
|
||||
|
||||
try {
|
||||
Jwts.parser().enableUnsecuredJws().build().parse(bad)
|
||||
Jwts.parser().enableUnsecured().build().parse(bad)
|
||||
fail()
|
||||
} catch (MalformedJwtException expected) {
|
||||
assertEquals 'Unable to read claims JSON: ' + junkPayload, expected.getMessage()
|
||||
|
@ -129,7 +129,7 @@ class JwtParserTest {
|
|||
String bad = base64Url(header) + '.' + base64Url(payload) + '.' + base64Url(badSig)
|
||||
|
||||
try {
|
||||
Jwts.parser().enableUnsecuredJws().setSigningKey(randomKey()).build().parse(bad)
|
||||
Jwts.parser().enableUnsecured().setSigningKey(randomKey()).build().parse(bad)
|
||||
fail()
|
||||
} catch (MalformedJwtException se) {
|
||||
assertEquals 'The JWS header references signature algorithm \'none\' yet the compact JWS string contains a signature. This is not permitted per https://tools.ietf.org/html/rfc7518#section-3.6.', se.getMessage()
|
||||
|
@ -202,7 +202,7 @@ class JwtParserTest {
|
|||
@Test
|
||||
void testParseNullPayloadWithoutKey() {
|
||||
String compact = Jwts.builder().compact()
|
||||
def jwt = Jwts.parser().enableUnsecuredJws().build().parse(compact)
|
||||
def jwt = Jwts.parser().enableUnsecured().build().parse(compact)
|
||||
assertEquals 'none', jwt.header.alg
|
||||
assertEquals '', new String(jwt.payload as byte[], StandardCharsets.UTF_8)
|
||||
}
|
||||
|
@ -219,7 +219,7 @@ class JwtParserTest {
|
|||
String compact = Jwts.builder().setSubject('Joe').setExpiration(exp).compact()
|
||||
|
||||
try {
|
||||
Jwts.parser().enableUnsecuredJws().setClock(fixedClock).build().parse(compact)
|
||||
Jwts.parser().enableUnsecured().setClock(fixedClock).build().parse(compact)
|
||||
fail()
|
||||
} catch (ExpiredJwtException e) {
|
||||
// https://github.com/jwtk/jjwt/issues/107 (the Z designator at the end of the timestamp):
|
||||
|
@ -237,7 +237,7 @@ class JwtParserTest {
|
|||
String compact = Jwts.builder().setSubject('Joe').setNotBefore(nbf).compact()
|
||||
|
||||
try {
|
||||
Jwts.parser().enableUnsecuredJws().build().parse(compact)
|
||||
Jwts.parser().enableUnsecured().build().parse(compact)
|
||||
fail()
|
||||
} catch (PrematureJwtException e) {
|
||||
assertTrue e.getMessage().startsWith('JWT must not be accepted before ')
|
||||
|
@ -254,7 +254,7 @@ class JwtParserTest {
|
|||
String subject = 'Joe'
|
||||
String compact = Jwts.builder().setSubject(subject).setExpiration(exp).compact()
|
||||
|
||||
Jwt<Header, Claims> jwt = Jwts.parser().enableUnsecuredJws().setAllowedClockSkewSeconds(10).build().parse(compact)
|
||||
Jwt<Header, Claims> jwt = Jwts.parser().enableUnsecured().setAllowedClockSkewSeconds(10).build().parse(compact)
|
||||
|
||||
assertEquals jwt.getPayload().getSubject(), subject
|
||||
}
|
||||
|
@ -266,7 +266,7 @@ class JwtParserTest {
|
|||
String compact = Jwts.builder().setSubject('Joe').setExpiration(exp).compact()
|
||||
|
||||
try {
|
||||
Jwts.parser().enableUnsecuredJws().setAllowedClockSkewSeconds(1).build().parse(compact)
|
||||
Jwts.parser().enableUnsecured().setAllowedClockSkewSeconds(1).build().parse(compact)
|
||||
fail()
|
||||
} catch (ExpiredJwtException e) {
|
||||
assertTrue e.getMessage().startsWith('JWT expired at ')
|
||||
|
@ -280,7 +280,7 @@ class JwtParserTest {
|
|||
String subject = 'Joe'
|
||||
String compact = Jwts.builder().setSubject(subject).setNotBefore(exp).compact()
|
||||
|
||||
Jwt<Header, Claims> jwt = Jwts.parser().enableUnsecuredJws().setAllowedClockSkewSeconds(10).build().parse(compact)
|
||||
Jwt<Header, Claims> jwt = Jwts.parser().enableUnsecured().setAllowedClockSkewSeconds(10).build().parse(compact)
|
||||
|
||||
assertEquals jwt.getPayload().getSubject(), subject
|
||||
}
|
||||
|
@ -292,7 +292,7 @@ class JwtParserTest {
|
|||
String compact = Jwts.builder().setSubject('Joe').setNotBefore(exp).compact()
|
||||
|
||||
try {
|
||||
Jwts.parser().enableUnsecuredJws().setAllowedClockSkewSeconds(1).build().parse(compact)
|
||||
Jwts.parser().enableUnsecured().setAllowedClockSkewSeconds(1).build().parse(compact)
|
||||
fail()
|
||||
} catch (PrematureJwtException e) {
|
||||
assertTrue e.getMessage().startsWith('JWT must not be accepted before ')
|
||||
|
@ -310,7 +310,7 @@ class JwtParserTest {
|
|||
|
||||
String compact = Jwts.builder().setPayload(payload).compact()
|
||||
|
||||
def jwt = Jwts.parser().enableUnsecuredJws().build().parseContentJwt(compact)
|
||||
def jwt = Jwts.parser().enableUnsecured().build().parseContentJwt(compact)
|
||||
|
||||
assertEquals payload, new String(jwt.payload, StandardCharsets.UTF_8)
|
||||
}
|
||||
|
@ -321,7 +321,7 @@ class JwtParserTest {
|
|||
String compact = Jwts.builder().setSubject('Joe').compact()
|
||||
|
||||
try {
|
||||
Jwts.parser().enableUnsecuredJws().build().parseContentJwt(compact)
|
||||
Jwts.parser().enableUnsecured().build().parseContentJwt(compact)
|
||||
fail()
|
||||
} catch (UnsupportedJwtException e) {
|
||||
assertEquals e.getMessage(), 'Unprotected Claims JWTs are not supported.'
|
||||
|
@ -368,7 +368,7 @@ class JwtParserTest {
|
|||
|
||||
String compact = Jwts.builder().setSubject(subject).compact()
|
||||
|
||||
Jwt<Header, Claims> jwt = Jwts.parser().enableUnsecuredJws().build().parseClaimsJwt(compact)
|
||||
Jwt<Header, Claims> jwt = Jwts.parser().enableUnsecured().build().parseClaimsJwt(compact)
|
||||
|
||||
assertEquals jwt.getPayload().getSubject(), subject
|
||||
}
|
||||
|
@ -381,7 +381,7 @@ class JwtParserTest {
|
|||
String compact = Jwts.builder().setPayload(payload).compact()
|
||||
|
||||
try {
|
||||
Jwts.parser().enableUnsecuredJws().build().parseClaimsJwt(compact)
|
||||
Jwts.parser().enableUnsecured().build().parseClaimsJwt(compact)
|
||||
fail()
|
||||
} catch (UnsupportedJwtException e) {
|
||||
assertEquals 'Unprotected content JWTs are not supported.', e.getMessage()
|
||||
|
@ -427,7 +427,7 @@ class JwtParserTest {
|
|||
String compact = Jwts.builder().setSubject('Joe').setExpiration(exp).compact()
|
||||
|
||||
try {
|
||||
Jwts.parser().enableUnsecuredJws().build().parseClaimsJwt(compact)
|
||||
Jwts.parser().enableUnsecured().build().parseClaimsJwt(compact)
|
||||
fail()
|
||||
} catch (ExpiredJwtException e) {
|
||||
assertTrue e.getMessage().startsWith('JWT expired at ')
|
||||
|
@ -442,7 +442,7 @@ class JwtParserTest {
|
|||
String compact = Jwts.builder().setSubject('Joe').setNotBefore(nbf).compact()
|
||||
|
||||
try {
|
||||
Jwts.parser().enableUnsecuredJws().build().parseClaimsJwt(compact)
|
||||
Jwts.parser().enableUnsecured().build().parseClaimsJwt(compact)
|
||||
fail()
|
||||
} catch (PrematureJwtException e) {
|
||||
assertTrue e.getMessage().startsWith('JWT must not be accepted before ')
|
||||
|
@ -480,7 +480,7 @@ class JwtParserTest {
|
|||
String compact = Jwts.builder().setPayload(payload).compact()
|
||||
|
||||
try {
|
||||
Jwts.parser().enableUnsecuredJws().setSigningKey(key).build().parseContentJws(compact)
|
||||
Jwts.parser().enableUnsecured().setSigningKey(key).build().parseContentJws(compact)
|
||||
fail()
|
||||
} catch (UnsupportedJwtException e) {
|
||||
assertEquals 'Unprotected content JWTs are not supported.', e.getMessage()
|
||||
|
@ -497,7 +497,7 @@ class JwtParserTest {
|
|||
String compact = Jwts.builder().setSubject(subject).compact()
|
||||
|
||||
try {
|
||||
Jwts.parser().enableUnsecuredJws().setSigningKey(key).build().parseContentJws(compact)
|
||||
Jwts.parser().enableUnsecured().setSigningKey(key).build().parseContentJws(compact)
|
||||
fail()
|
||||
} catch (UnsupportedJwtException e) {
|
||||
assertEquals 'Unprotected Claims JWTs are not supported.', e.getMessage()
|
||||
|
@ -593,7 +593,7 @@ class JwtParserTest {
|
|||
String compact = Jwts.builder().setPayload(payload).compact()
|
||||
|
||||
try {
|
||||
Jwts.parser().enableUnsecuredJws().setSigningKey(key).build().parseClaimsJws(compact)
|
||||
Jwts.parser().enableUnsecured().setSigningKey(key).build().parseClaimsJws(compact)
|
||||
fail()
|
||||
} catch (UnsupportedJwtException e) {
|
||||
assertEquals 'Unprotected content JWTs are not supported.', e.getMessage()
|
||||
|
@ -610,7 +610,7 @@ class JwtParserTest {
|
|||
String compact = Jwts.builder().setSubject(subject).compact()
|
||||
|
||||
try {
|
||||
Jwts.parser().enableUnsecuredJws().setSigningKey(key).
|
||||
Jwts.parser().enableUnsecured().setSigningKey(key).
|
||||
build().
|
||||
parseClaimsJws(compact)
|
||||
fail()
|
||||
|
@ -1492,7 +1492,7 @@ class JwtParserTest {
|
|||
|
||||
String compact = Jwts.builder().setSubject('Joe').setExpiration(expiry).compact()
|
||||
|
||||
Jwts.parser().enableUnsecuredJws().setClock(new FixedClock(beforeExpiry)).build().parse(compact)
|
||||
Jwts.parser().enableUnsecured().setClock(new FixedClock(beforeExpiry)).build().parse(compact)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -1512,7 +1512,7 @@ class JwtParserTest {
|
|||
String compact = Jwts.builder().setSubject('Joe').setExpiration(expiry).compact()
|
||||
|
||||
try {
|
||||
Jwts.parser().enableUnsecuredJws().setClock(new DefaultClock()).build().parse(compact)
|
||||
Jwts.parser().enableUnsecured().setClock(new DefaultClock()).build().parse(compact)
|
||||
fail()
|
||||
} catch (ExpiredJwtException e) {
|
||||
assertTrue e.getMessage().startsWith('JWT expired at ')
|
||||
|
@ -1585,7 +1585,7 @@ class JwtParserTest {
|
|||
String jwtStr = base64Url(header) + '.' + base64Url(payload) + '.' + base64Url(sig)
|
||||
|
||||
try {
|
||||
Jwts.parser().enableUnsecuredJws().build().parse(jwtStr)
|
||||
Jwts.parser().enableUnsecured().build().parse(jwtStr)
|
||||
fail()
|
||||
} catch (MalformedJwtException se) {
|
||||
assertEquals 'The JWS header references signature algorithm \'none\' yet the compact JWS string contains a signature. This is not permitted per https://tools.ietf.org/html/rfc7518#section-3.6.', se.message
|
||||
|
|
|
@ -88,7 +88,7 @@ class JwtsTest {
|
|||
|
||||
@Test
|
||||
void testHeaderWithMapArg() {
|
||||
def header = Jwts.header().set([alg: "HS256"]).build()
|
||||
def header = Jwts.header().add([alg: "HS256"]).build()
|
||||
assertTrue header instanceof DefaultJwsHeader
|
||||
assertEquals 'HS256', header.getAlgorithm()
|
||||
assertEquals 'HS256', header.alg
|
||||
|
@ -165,8 +165,8 @@ class JwtsTest {
|
|||
void testSetContentWithContentType() {
|
||||
String s = 'Hello JJWT'
|
||||
String cty = 'text/plain'
|
||||
String compact = Jwts.builder().setContent(s.getBytes(StandardCharsets.UTF_8), cty).compact()
|
||||
def jwt = Jwts.parser().enableUnsecuredJws().build().parseContentJwt(compact)
|
||||
String compact = Jwts.builder().content(s.getBytes(StandardCharsets.UTF_8), cty).compact()
|
||||
def jwt = Jwts.parser().enableUnsecured().build().parseContentJwt(compact)
|
||||
assertEquals cty, jwt.header.getContentType()
|
||||
assertEquals s, new String(jwt.payload, StandardCharsets.UTF_8)
|
||||
}
|
||||
|
@ -176,8 +176,8 @@ class JwtsTest {
|
|||
String s = 'Hello JJWT'
|
||||
String subtype = 'foo'
|
||||
String cty = "application/$subtype"
|
||||
String compact = Jwts.builder().setContent(s.getBytes(StandardCharsets.UTF_8), cty).compact()
|
||||
def jwt = Jwts.parser().enableUnsecuredJws().build().parseContentJwt(compact)
|
||||
String compact = Jwts.builder().content(s.getBytes(StandardCharsets.UTF_8), cty).compact()
|
||||
def jwt = Jwts.parser().enableUnsecured().build().parseContentJwt(compact)
|
||||
assertEquals subtype, jwt.header.getContentType() // assert that the compact form was used
|
||||
assertEquals s, new String(jwt.payload, StandardCharsets.UTF_8)
|
||||
}
|
||||
|
@ -187,8 +187,8 @@ class JwtsTest {
|
|||
String s = 'Hello JJWT'
|
||||
String subtype = 'foo'
|
||||
String cty = "application/$subtype;part=1/2"
|
||||
String compact = Jwts.builder().setContent(s.getBytes(StandardCharsets.UTF_8), cty).compact()
|
||||
def jwt = Jwts.parser().enableUnsecuredJws().build().parseContentJwt(compact)
|
||||
String compact = Jwts.builder().content(s.getBytes(StandardCharsets.UTF_8), cty).compact()
|
||||
def jwt = Jwts.parser().enableUnsecured().build().parseContentJwt(compact)
|
||||
assertEquals cty, jwt.header.getContentType() // two slashes, can't compact
|
||||
assertEquals s, new String(jwt.payload, StandardCharsets.UTF_8)
|
||||
}
|
||||
|
@ -198,9 +198,9 @@ class JwtsTest {
|
|||
|
||||
def claims = [iss: 'joe', exp: later(), 'https://example.com/is_root': true]
|
||||
|
||||
String jwt = Jwts.builder().setClaims(claims).compact()
|
||||
String jwt = Jwts.builder().claims().add(claims).and().compact()
|
||||
|
||||
def token = Jwts.parser().enableUnsecuredJws().build().parse(jwt)
|
||||
def token = Jwts.parser().enableUnsecured().build().parse(jwt)
|
||||
|
||||
//noinspection GrEqualsBetweenInconvertibleTypes
|
||||
assert token.payload == claims
|
||||
|
@ -230,7 +230,7 @@ class JwtsTest {
|
|||
String claims = Encoders.BASE64URL.encode(claimsJson.getBytes(StandardCharsets.UTF_8))
|
||||
|
||||
String compact = header + '.' + claims + '.'
|
||||
def jwt = Jwts.parser().enableUnsecuredJws().build().parseClaimsJwt(compact)
|
||||
def jwt = Jwts.parser().enableUnsecured().build().parseClaimsJwt(compact)
|
||||
assertEquals 'none', jwt.header.getAlgorithm()
|
||||
assertEquals 'joe', jwt.payload.getSubject()
|
||||
}
|
||||
|
@ -274,7 +274,7 @@ class JwtsTest {
|
|||
@Test
|
||||
void testParseWithHeaderOnly() {
|
||||
String unsecuredJwt = base64Url("{\"alg\":\"none\"}") + ".."
|
||||
Jwt jwt = Jwts.parser().enableUnsecuredJws().build().parse(unsecuredJwt)
|
||||
Jwt jwt = Jwts.parser().enableUnsecured().build().parse(unsecuredJwt)
|
||||
assertEquals "none", jwt.getHeader().get("alg")
|
||||
}
|
||||
|
||||
|
@ -290,12 +290,12 @@ class JwtsTest {
|
|||
|
||||
@Test
|
||||
void testParseWithMissingRequiredSignature() {
|
||||
Key key = Jwts.SIG.HS256.keyBuilder().build()
|
||||
Key key = Jwts.SIG.HS256.key().build()
|
||||
String compact = Jwts.builder().setSubject('foo').signWith(key).compact()
|
||||
int i = compact.lastIndexOf('.')
|
||||
String missingSig = compact.substring(0, i + 1)
|
||||
try {
|
||||
Jwts.parser().enableUnsecuredJws().setSigningKey(key).build().parseClaimsJws(missingSig)
|
||||
Jwts.parser().enableUnsecured().setSigningKey(key).build().parseClaimsJws(missingSig)
|
||||
fail()
|
||||
} catch (MalformedJwtException expected) {
|
||||
String s = String.format(DefaultJwtParser.MISSING_JWS_DIGEST_MSG_FMT, 'HS256')
|
||||
|
@ -306,7 +306,7 @@ class JwtsTest {
|
|||
@Test
|
||||
void testWithInvalidCompressionAlgorithm() {
|
||||
try {
|
||||
Jwts.builder().setHeaderParam(DefaultHeader.COMPRESSION_ALGORITHM.getId(), "CUSTOM").setId("andId").compact()
|
||||
Jwts.builder().header().add('zip', 'CUSTOM').and().id("andId").compact()
|
||||
} catch (CompressionException e) {
|
||||
assertEquals "Unsupported compression algorithm 'CUSTOM'", e.getMessage()
|
||||
}
|
||||
|
@ -315,7 +315,7 @@ class JwtsTest {
|
|||
@Test
|
||||
void testConvenienceIssuer() {
|
||||
String compact = Jwts.builder().setIssuer("Me").compact()
|
||||
Claims claims = Jwts.parser().enableUnsecuredJws().build().parse(compact).payload as Claims
|
||||
Claims claims = Jwts.parser().enableUnsecured().build().parse(compact).payload as Claims
|
||||
assertEquals 'Me', claims.getIssuer()
|
||||
|
||||
compact = Jwts.builder().setSubject("Joe")
|
||||
|
@ -323,14 +323,14 @@ class JwtsTest {
|
|||
.setIssuer(null) //null should remove it
|
||||
.compact()
|
||||
|
||||
claims = Jwts.parser().enableUnsecuredJws().build().parse(compact).payload as Claims
|
||||
claims = Jwts.parser().enableUnsecured().build().parse(compact).payload as Claims
|
||||
assertNull claims.getIssuer()
|
||||
}
|
||||
|
||||
@Test
|
||||
void testConvenienceSubject() {
|
||||
String compact = Jwts.builder().setSubject("Joe").compact()
|
||||
Claims claims = Jwts.parser().enableUnsecuredJws().build().parse(compact).payload as Claims
|
||||
Claims claims = Jwts.parser().enableUnsecured().build().parse(compact).payload as Claims
|
||||
assertEquals 'Joe', claims.getSubject()
|
||||
|
||||
compact = Jwts.builder().setIssuer("Me")
|
||||
|
@ -338,14 +338,14 @@ class JwtsTest {
|
|||
.setSubject(null) //null should remove it
|
||||
.compact()
|
||||
|
||||
claims = Jwts.parser().enableUnsecuredJws().build().parse(compact).payload as Claims
|
||||
claims = Jwts.parser().enableUnsecured().build().parse(compact).payload as Claims
|
||||
assertNull claims.getSubject()
|
||||
}
|
||||
|
||||
@Test
|
||||
void testConvenienceAudience() {
|
||||
String compact = Jwts.builder().setAudience("You").compact()
|
||||
Claims claims = Jwts.parser().enableUnsecuredJws().build().parse(compact).payload as Claims
|
||||
Claims claims = Jwts.parser().enableUnsecured().build().parse(compact).payload as Claims
|
||||
assertEquals 'You', claims.getAudience()
|
||||
|
||||
compact = Jwts.builder().setIssuer("Me")
|
||||
|
@ -353,7 +353,7 @@ class JwtsTest {
|
|||
.setAudience(null) //null should remove it
|
||||
.compact()
|
||||
|
||||
claims = Jwts.parser().enableUnsecuredJws().build().parse(compact).payload as Claims
|
||||
claims = Jwts.parser().enableUnsecured().build().parse(compact).payload as Claims
|
||||
assertNull claims.getAudience()
|
||||
}
|
||||
|
||||
|
@ -361,7 +361,7 @@ class JwtsTest {
|
|||
void testConvenienceExpiration() {
|
||||
Date then = laterDate(10000)
|
||||
String compact = Jwts.builder().setExpiration(then).compact()
|
||||
Claims claims = Jwts.parser().enableUnsecuredJws().build().parse(compact).payload as Claims
|
||||
Claims claims = Jwts.parser().enableUnsecured().build().parse(compact).payload as Claims
|
||||
def claimedDate = claims.getExpiration()
|
||||
assertEquals then, claimedDate
|
||||
|
||||
|
@ -370,7 +370,7 @@ class JwtsTest {
|
|||
.setExpiration(null) //null should remove it
|
||||
.compact()
|
||||
|
||||
claims = Jwts.parser().enableUnsecuredJws().build().parse(compact).payload as Claims
|
||||
claims = Jwts.parser().enableUnsecured().build().parse(compact).payload as Claims
|
||||
assertNull claims.getExpiration()
|
||||
}
|
||||
|
||||
|
@ -378,7 +378,7 @@ class JwtsTest {
|
|||
void testConvenienceNotBefore() {
|
||||
Date now = now() //jwt exp only supports *seconds* since epoch:
|
||||
String compact = Jwts.builder().setNotBefore(now).compact()
|
||||
Claims claims = Jwts.parser().enableUnsecuredJws().build().parse(compact).payload as Claims
|
||||
Claims claims = Jwts.parser().enableUnsecured().build().parse(compact).payload as Claims
|
||||
def claimedDate = claims.getNotBefore()
|
||||
assertEquals now, claimedDate
|
||||
|
||||
|
@ -387,7 +387,7 @@ class JwtsTest {
|
|||
.setNotBefore(null) //null should remove it
|
||||
.compact()
|
||||
|
||||
claims = Jwts.parser().enableUnsecuredJws().build().parse(compact).payload as Claims
|
||||
claims = Jwts.parser().enableUnsecured().build().parse(compact).payload as Claims
|
||||
assertNull claims.getNotBefore()
|
||||
}
|
||||
|
||||
|
@ -395,7 +395,7 @@ class JwtsTest {
|
|||
void testConvenienceIssuedAt() {
|
||||
Date now = now() //jwt exp only supports *seconds* since epoch:
|
||||
String compact = Jwts.builder().setIssuedAt(now).compact()
|
||||
Claims claims = Jwts.parser().enableUnsecuredJws().build().parse(compact).payload as Claims
|
||||
Claims claims = Jwts.parser().enableUnsecured().build().parse(compact).payload as Claims
|
||||
def claimedDate = claims.getIssuedAt()
|
||||
assertEquals now, claimedDate
|
||||
|
||||
|
@ -404,7 +404,7 @@ class JwtsTest {
|
|||
.setIssuedAt(null) //null should remove it
|
||||
.compact()
|
||||
|
||||
claims = Jwts.parser().enableUnsecuredJws().build().parse(compact).payload as Claims
|
||||
claims = Jwts.parser().enableUnsecured().build().parse(compact).payload as Claims
|
||||
assertNull claims.getIssuedAt()
|
||||
}
|
||||
|
||||
|
@ -412,7 +412,7 @@ class JwtsTest {
|
|||
void testConvenienceId() {
|
||||
String id = UUID.randomUUID().toString()
|
||||
String compact = Jwts.builder().setId(id).compact()
|
||||
Claims claims = Jwts.parser().enableUnsecuredJws().build().parse(compact).payload as Claims
|
||||
Claims claims = Jwts.parser().enableUnsecured().build().parse(compact).payload as Claims
|
||||
assertEquals id, claims.getId()
|
||||
|
||||
compact = Jwts.builder().setIssuer("Me")
|
||||
|
@ -420,7 +420,7 @@ class JwtsTest {
|
|||
.setId(null) //null should remove it
|
||||
.compact()
|
||||
|
||||
claims = Jwts.parser().enableUnsecuredJws().build().parse(compact).payload as Claims
|
||||
claims = Jwts.parser().enableUnsecured().build().parse(compact).payload as Claims
|
||||
assertNull claims.getId()
|
||||
}
|
||||
|
||||
|
@ -428,7 +428,7 @@ class JwtsTest {
|
|||
void testUncompressedJwt() {
|
||||
|
||||
def alg = Jwts.SIG.HS256
|
||||
SecretKey key = alg.keyBuilder().build()
|
||||
SecretKey key = alg.key().build()
|
||||
|
||||
String id = UUID.randomUUID().toString()
|
||||
|
||||
|
@ -450,7 +450,7 @@ class JwtsTest {
|
|||
void testCompressedJwtWithDeflate() {
|
||||
|
||||
def alg = Jwts.SIG.HS256
|
||||
SecretKey key = alg.keyBuilder().build()
|
||||
SecretKey key = alg.key().build()
|
||||
|
||||
String id = UUID.randomUUID().toString()
|
||||
|
||||
|
@ -472,7 +472,7 @@ class JwtsTest {
|
|||
void testCompressedJwtWithGZIP() {
|
||||
|
||||
def alg = Jwts.SIG.HS256
|
||||
SecretKey key = alg.keyBuilder().build()
|
||||
SecretKey key = alg.key().build()
|
||||
|
||||
String id = UUID.randomUUID().toString()
|
||||
|
||||
|
@ -494,7 +494,7 @@ class JwtsTest {
|
|||
void testCompressedWithCustomResolver() {
|
||||
|
||||
def alg = Jwts.SIG.HS256
|
||||
SecretKey key = alg.keyBuilder().build()
|
||||
SecretKey key = alg.key().build()
|
||||
|
||||
String id = UUID.randomUUID().toString()
|
||||
|
||||
|
@ -533,7 +533,7 @@ class JwtsTest {
|
|||
void testCompressedJwtWithUnrecognizedHeader() {
|
||||
|
||||
def alg = Jwts.SIG.HS256
|
||||
SecretKey key = alg.keyBuilder().build()
|
||||
SecretKey key = alg.key().build()
|
||||
|
||||
String id = UUID.randomUUID().toString()
|
||||
|
||||
|
@ -552,7 +552,7 @@ class JwtsTest {
|
|||
void testCompressStringPayloadWithDeflate() {
|
||||
|
||||
def alg = Jwts.SIG.HS256
|
||||
SecretKey key = alg.keyBuilder().build()
|
||||
SecretKey key = alg.key().build()
|
||||
|
||||
String payload = "this is my test for a payload"
|
||||
|
||||
|
@ -673,8 +673,8 @@ class JwtsTest {
|
|||
void testParseClaimsJwsWithWeakHmacKey() {
|
||||
|
||||
def alg = Jwts.SIG.HS384
|
||||
def key = alg.keyBuilder().build()
|
||||
def weakKey = Jwts.SIG.HS256.keyBuilder().build()
|
||||
def key = alg.key().build()
|
||||
def weakKey = Jwts.SIG.HS256.key().build()
|
||||
|
||||
String jws = Jwts.builder().setSubject("Foo").signWith(key, alg).compact()
|
||||
|
||||
|
@ -744,7 +744,7 @@ class JwtsTest {
|
|||
def withoutSignature = "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0ZXN0IjoidGVzdCIsImlhdCI6MTQ2NzA2NTgyN30"
|
||||
def invalidEncodedSignature = "_____wAAAAD__________7zm-q2nF56E87nKwvxjJVH_____AAAAAP__________vOb6racXnoTzucrC_GMlUQ"
|
||||
String jws = withoutSignature + '.' + invalidEncodedSignature
|
||||
def keypair = Jwts.SIG.ES256.keyPairBuilder().build()
|
||||
def keypair = Jwts.SIG.ES256.keyPair().build()
|
||||
Jwts.parser().setSigningKey(keypair.public).build().parseClaimsJws(jws)
|
||||
}
|
||||
|
||||
|
@ -754,12 +754,12 @@ class JwtsTest {
|
|||
|
||||
//create random signing key for testing:
|
||||
def alg = Jwts.SIG.HS256
|
||||
SecretKey key = alg.keyBuilder().build()
|
||||
SecretKey key = alg.key().build()
|
||||
|
||||
String notSigned = Jwts.builder().setSubject("Foo").compact()
|
||||
|
||||
try {
|
||||
Jwts.parser().enableUnsecuredJws().setSigningKey(key).build().parseClaimsJws(notSigned)
|
||||
Jwts.parser().enableUnsecured().setSigningKey(key).build().parseClaimsJws(notSigned)
|
||||
fail('parseClaimsJws must fail for unsigned JWTs')
|
||||
} catch (UnsupportedJwtException expected) {
|
||||
assertEquals 'Unprotected Claims JWTs are not supported.', expected.message
|
||||
|
@ -1025,8 +1025,8 @@ class JwtsTest {
|
|||
def id = realAlg.getId() + 'X' // custom id
|
||||
def alg = new MacAlgorithm() {
|
||||
@Override
|
||||
SecretKeyBuilder keyBuilder() {
|
||||
return realAlg.keyBuilder()
|
||||
SecretKeyBuilder key() {
|
||||
return realAlg.key()
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1065,7 +1065,7 @@ class JwtsTest {
|
|||
@Test
|
||||
void testParseJweWithCustomEncryptionAlgorithm() {
|
||||
def realAlg = Jwts.ENC.A128GCM // any alg will do, we're going to wrap it
|
||||
def key = realAlg.keyBuilder().build()
|
||||
def key = realAlg.key().build()
|
||||
def enc = realAlg.getId() + 'X' // custom id
|
||||
def encAlg = new AeadAlgorithm() {
|
||||
@Override
|
||||
|
@ -1084,8 +1084,8 @@ class JwtsTest {
|
|||
}
|
||||
|
||||
@Override
|
||||
SecretKeyBuilder keyBuilder() {
|
||||
return realAlg.keyBuilder()
|
||||
SecretKeyBuilder key() {
|
||||
return realAlg.key()
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1135,7 +1135,7 @@ class JwtsTest {
|
|||
|
||||
try {
|
||||
Jwts.parser()
|
||||
.setKeyLocator(new ConstantKeyLocator(TestKeys.HS256, TestKeys.A128GCM))
|
||||
.keyLocator(new ConstantKeyLocator(TestKeys.HS256, TestKeys.A128GCM))
|
||||
.addKeyAlgorithms([badKeyAlg]) // <-- add bad alg here
|
||||
.build()
|
||||
.parseClaimsJwe(compact)
|
||||
|
@ -1165,7 +1165,7 @@ class JwtsTest {
|
|||
|
||||
//create random signing key for testing:
|
||||
def alg = Jwts.SIG.HS256
|
||||
SecretKey key = alg.keyBuilder().build()
|
||||
SecretKey key = alg.key().build()
|
||||
|
||||
//this is a 'real', valid JWT:
|
||||
String compact = Jwts.builder().setSubject("Joe").signWith(key, alg).compact()
|
||||
|
@ -1178,14 +1178,14 @@ class JwtsTest {
|
|||
String forged = Jwts.builder().setSubject("Not Joe").compact()
|
||||
|
||||
//assert that our forged header has a 'NONE' algorithm:
|
||||
assertEquals 'none', Jwts.parser().enableUnsecuredJws().build().parseClaimsJwt(forged).getHeader().get('alg')
|
||||
assertEquals 'none', Jwts.parser().enableUnsecured().build().parseClaimsJwt(forged).getHeader().get('alg')
|
||||
|
||||
//now let's forge it by appending the signature the server expects:
|
||||
forged += signature
|
||||
|
||||
//now assert that, when the server tries to parse the forged token, parsing fails:
|
||||
try {
|
||||
Jwts.parser().enableUnsecuredJws().setSigningKey(key).build().parse(forged)
|
||||
Jwts.parser().enableUnsecured().setSigningKey(key).build().parse(forged)
|
||||
fail("Parsing must fail for a forged token.")
|
||||
} catch (MalformedJwtException expected) {
|
||||
assertEquals 'The JWS header references signature algorithm \'none\' yet the compact JWS string contains a signature. This is not permitted per https://tools.ietf.org/html/rfc7518#section-3.6.', expected.message
|
||||
|
@ -1300,8 +1300,8 @@ class JwtsTest {
|
|||
for (AeadAlgorithm enc : Jwts.ENC.get().values()) {
|
||||
|
||||
SecretKey key = alg instanceof SecretKeyAlgorithm ?
|
||||
((SecretKeyAlgorithm) alg).keyBuilder().build() :
|
||||
enc.keyBuilder().build()
|
||||
((SecretKeyAlgorithm) alg).key().build() :
|
||||
enc.key().build()
|
||||
|
||||
// encrypt:
|
||||
String jwe = Jwts.builder()
|
||||
|
@ -1328,7 +1328,7 @@ class JwtsTest {
|
|||
|
||||
for (AeadAlgorithm enc : Jwts.ENC.get().values()) {
|
||||
|
||||
SecretKey key = enc.keyBuilder().build()
|
||||
SecretKey key = enc.key().build()
|
||||
|
||||
// encrypt and compress:
|
||||
String jwe = Jwts.builder()
|
||||
|
@ -1354,7 +1354,7 @@ class JwtsTest {
|
|||
it instanceof Pbes2HsAkwAlgorithm
|
||||
})// as Collection<KeyAlgorithm<SecretKey, SecretKey>>
|
||||
|
||||
Password key = Keys.forPassword("12345678".toCharArray())
|
||||
Password key = Keys.password("12345678".toCharArray())
|
||||
|
||||
for (KeyAlgorithm alg : algs) {
|
||||
|
||||
|
@ -1379,7 +1379,7 @@ class JwtsTest {
|
|||
@Test
|
||||
void testPasswordJweWithoutSpecifyingAlg() {
|
||||
|
||||
Password key = Keys.forPassword("12345678".toCharArray())
|
||||
Password key = Keys.password("12345678".toCharArray())
|
||||
|
||||
// encrypt:
|
||||
String jwe = Jwts.builder()
|
||||
|
@ -1571,7 +1571,7 @@ class JwtsTest {
|
|||
|
||||
def claims = new DefaultClaims([iss: 'joe', exp: later(), 'https://example.com/is_root': true])
|
||||
|
||||
String jwt = Jwts.builder().setClaims(claims).signWith(privateKey, alg).compact()
|
||||
String jwt = Jwts.builder().claims().add(claims).and().signWith(privateKey, alg).compact()
|
||||
|
||||
def key = publicKey
|
||||
if (verifyWithPrivateKey) {
|
||||
|
@ -1587,11 +1587,11 @@ class JwtsTest {
|
|||
static void testHmac(MacAlgorithm alg) {
|
||||
|
||||
//create random signing key for testing:
|
||||
SecretKey key = alg.keyBuilder().build()
|
||||
SecretKey key = alg.key().build()
|
||||
|
||||
def claims = new DefaultClaims([iss: 'joe', exp: later(), 'https://example.com/is_root': true])
|
||||
|
||||
String jwt = Jwts.builder().setClaims(claims).signWith(key, alg).compact()
|
||||
String jwt = Jwts.builder().claims().add(claims).and().signWith(key, alg).compact()
|
||||
|
||||
def token = Jwts.parser().verifyWith(key).build().parse(jwt)
|
||||
|
||||
|
@ -1607,7 +1607,7 @@ class JwtsTest {
|
|||
|
||||
def claims = new DefaultClaims([iss: 'joe', exp: later(), 'https://example.com/is_root': true])
|
||||
|
||||
String jwt = Jwts.builder().setClaims(claims).signWith(privateKey, alg).compact()
|
||||
String jwt = Jwts.builder().claims().add(claims).and().signWith(privateKey, alg).compact()
|
||||
|
||||
def key = publicKey
|
||||
if (verifyWithPrivateKey) {
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
package io.jsonwebtoken.impl
|
||||
|
||||
import io.jsonwebtoken.Jwts
|
||||
import io.jsonwebtoken.impl.security.Randoms
|
||||
import io.jsonwebtoken.impl.security.TestKeys
|
||||
import io.jsonwebtoken.io.Encoders
|
||||
|
@ -56,7 +57,7 @@ class AbstractProtectedHeaderTest {
|
|||
@Test
|
||||
void testJku() {
|
||||
URI uri = URI.create('https://github.com')
|
||||
def header = h([jku: uri])
|
||||
def header = Jwts.header().jwkSetUrl(uri).build() as DefaultProtectedHeader
|
||||
assertEquals uri.toString(), header.get('jku')
|
||||
assertEquals uri, header.getJwkSetUrl()
|
||||
}
|
||||
|
@ -108,7 +109,7 @@ class AbstractProtectedHeaderTest {
|
|||
|
||||
@Test
|
||||
void testJwkWithJwk() {
|
||||
EcPrivateJwk jwk = Jwks.builder().forEcKeyPair(TestKeys.ES256.pair).build()
|
||||
EcPrivateJwk jwk = Jwks.builder().ecKeyPair(TestKeys.ES256.pair).build()
|
||||
EcPublicJwk pubJwk = jwk.toPublicJwk()
|
||||
def header = h([jwk: pubJwk])
|
||||
assertEquals pubJwk, header.getJwk()
|
||||
|
@ -116,7 +117,7 @@ class AbstractProtectedHeaderTest {
|
|||
|
||||
@Test
|
||||
void testJwkWithMap() {
|
||||
EcPrivateJwk jwk = Jwks.builder().forEcKeyPair(TestKeys.ES256.pair).build()
|
||||
EcPrivateJwk jwk = Jwks.builder().ecKeyPair(TestKeys.ES256.pair).build()
|
||||
EcPublicJwk pubJwk = jwk.toPublicJwk()
|
||||
Map<String, ?> m = new LinkedHashMap<>(pubJwk)
|
||||
def header = h([jwk: m])
|
||||
|
@ -138,7 +139,7 @@ class AbstractProtectedHeaderTest {
|
|||
|
||||
@Test
|
||||
void testJwkWithSecretJwk() {
|
||||
SecretJwk jwk = Jwks.builder().forKey(TestKeys.HS256).build()
|
||||
SecretJwk jwk = Jwks.builder().key(TestKeys.HS256).build()
|
||||
try {
|
||||
h([jwk: jwk])
|
||||
fail()
|
||||
|
@ -151,7 +152,7 @@ class AbstractProtectedHeaderTest {
|
|||
|
||||
@Test
|
||||
void testJwkWithPrivateJwk() {
|
||||
EcPrivateJwk jwk = Jwks.builder().forEcKeyPair(TestKeys.ES256.pair).build()
|
||||
EcPrivateJwk jwk = Jwks.builder().ecKeyPair(TestKeys.ES256.pair).build()
|
||||
try {
|
||||
h([jwk: jwk])
|
||||
fail()
|
||||
|
@ -212,7 +213,7 @@ class AbstractProtectedHeaderTest {
|
|||
@Test
|
||||
void testCritical() {
|
||||
Set<String> crits = Collections.setOf('foo', 'bar')
|
||||
def header = h([crit: crits])
|
||||
def header = Jwts.header().critical(crits).build() as DefaultProtectedHeader
|
||||
assertEquals crits, header.getCritical()
|
||||
}
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ class DefaultJweHeaderTest {
|
|||
|
||||
@Test
|
||||
void testEpkWithSecretJwk() {
|
||||
def jwk = Jwks.builder().forKey(TestKeys.HS256).build()
|
||||
def jwk = Jwks.builder().key(TestKeys.HS256).build()
|
||||
def values = new LinkedHashMap(jwk) //extract values to remove JWK type
|
||||
try {
|
||||
h([epk: values])
|
||||
|
@ -71,7 +71,7 @@ class DefaultJweHeaderTest {
|
|||
|
||||
@Test
|
||||
void testEpkWithPrivateJwk() {
|
||||
def jwk = Jwks.builder().forKey(TestKeys.ES256.pair.private as ECPrivateKey).build()
|
||||
def jwk = Jwks.builder().key(TestKeys.ES256.pair.private as ECPrivateKey).build()
|
||||
def values = new LinkedHashMap(jwk) //extract values to remove JWK type
|
||||
try {
|
||||
h([epk: values])
|
||||
|
@ -86,7 +86,7 @@ class DefaultJweHeaderTest {
|
|||
|
||||
@Test
|
||||
void testEpkWithRsaPublicJwk() {
|
||||
def jwk = Jwks.builder().forKey(TestKeys.RS256.pair.public as RSAPublicKey).build()
|
||||
def jwk = Jwks.builder().key(TestKeys.RS256.pair.public as RSAPublicKey).build()
|
||||
def values = new LinkedHashMap(jwk) //extract values to remove JWK type
|
||||
def epk = h([epk: values]).getEphemeralPublicKey()
|
||||
assertTrue epk instanceof RsaPublicJwk
|
||||
|
@ -95,14 +95,14 @@ class DefaultJweHeaderTest {
|
|||
|
||||
@Test
|
||||
void testEpkWithEcPublicJwkValues() {
|
||||
def jwk = Jwks.builder().forKey(TestKeys.ES256.pair.public as ECPublicKey).build()
|
||||
def jwk = Jwks.builder().key(TestKeys.ES256.pair.public as ECPublicKey).build()
|
||||
def values = new LinkedHashMap(jwk) //extract values to remove JWK type
|
||||
assertEquals jwk, h([epk: values]).get('epk')
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEpkWithInvalidEcPublicJwk() {
|
||||
def jwk = Jwks.builder().forKey(TestKeys.ES256.pair.public as ECPublicKey).build()
|
||||
def jwk = Jwks.builder().key(TestKeys.ES256.pair.public as ECPublicKey).build()
|
||||
def values = new LinkedHashMap(jwk) // copy fields so we can mutate
|
||||
// We have a public JWK for a point on the curve, now swap out the x coordinate for something invalid:
|
||||
values.put('x', 'Kg')
|
||||
|
@ -121,7 +121,7 @@ class DefaultJweHeaderTest {
|
|||
|
||||
@Test
|
||||
void testEpkWithEcPublicJwk() {
|
||||
def jwk = Jwks.builder().forKey(TestKeys.ES256.pair.public as ECPublicKey).build()
|
||||
def jwk = Jwks.builder().key(TestKeys.ES256.pair.public as ECPublicKey).build()
|
||||
header = h([epk: jwk])
|
||||
assertEquals jwk, header.get('epk')
|
||||
assertEquals jwk, header.getEphemeralPublicKey()
|
||||
|
@ -131,7 +131,7 @@ class DefaultJweHeaderTest {
|
|||
void testEpkWithEdPublicJwk() {
|
||||
def keys = TestKeys.EdEC.collect({it -> it.pair.public as PublicKey})
|
||||
for(PublicKey key : keys) {
|
||||
def jwk = Jwks.builder().forKey((PublicKey)key as PublicKey).build()
|
||||
def jwk = Jwks.builder().key((PublicKey)key as PublicKey).build()
|
||||
header = h([epk: jwk])
|
||||
assertEquals jwk, header.get('epk')
|
||||
assertEquals jwk, header.getEphemeralPublicKey()
|
||||
|
|
|
@ -28,7 +28,7 @@ class DefaultJweTest {
|
|||
@Test
|
||||
void testToString() {
|
||||
def alg = Jwts.ENC.A128CBC_HS256 as AeadAlgorithm
|
||||
def key = alg.keyBuilder().build()
|
||||
def key = alg.key().build()
|
||||
String compact = Jwts.builder().claim('foo', 'bar').encryptWith(key, alg).compact()
|
||||
def jwe = Jwts.parser().decryptWith(key).build().parseClaimsJwe(compact)
|
||||
String encodedIv = Encoders.BASE64URL.encode(jwe.initializationVector)
|
||||
|
@ -40,7 +40,7 @@ class DefaultJweTest {
|
|||
@Test
|
||||
void testEqualsAndHashCode() {
|
||||
def alg = Jwts.ENC.A128CBC_HS256 as AeadAlgorithm
|
||||
def key = alg.keyBuilder().build()
|
||||
def key = alg.key().build()
|
||||
String compact = Jwts.builder().claim('foo', 'bar').encryptWith(key, alg).compact()
|
||||
def parser = Jwts.parser().decryptWith(key).build()
|
||||
def jwe1 = parser.parseClaimsJwe(compact)
|
||||
|
|
|
@ -36,7 +36,7 @@ class DefaultJwsTest {
|
|||
void testToString() {
|
||||
//create random signing key for testing:
|
||||
def alg = Jwts.SIG.HS256
|
||||
def key = alg.keyBuilder().build()
|
||||
def key = alg.key().build()
|
||||
String compact = Jwts.builder().claim('foo', 'bar').signWith(key, alg).compact()
|
||||
int i = compact.lastIndexOf('.')
|
||||
String signature = compact.substring(i + 1)
|
||||
|
@ -47,7 +47,7 @@ class DefaultJwsTest {
|
|||
@Test
|
||||
void testEqualsAndHashCode() {
|
||||
def alg = Jwts.SIG.HS256
|
||||
def key = alg.keyBuilder().build()
|
||||
def key = alg.key().build()
|
||||
String compact = Jwts.builder().claim('foo', 'bar').signWith(key, alg).compact()
|
||||
def parser = Jwts.parser().verifyWith(key).build()
|
||||
def jws1 = parser.parseClaimsJws(compact)
|
||||
|
|
|
@ -70,7 +70,7 @@ class DefaultJwtBuilderTest {
|
|||
}
|
||||
|
||||
@Override
|
||||
KeyPairBuilder keyPairBuilder() {
|
||||
KeyPairBuilder keyPair() {
|
||||
throw new IllegalStateException("should not be called during build")
|
||||
}
|
||||
|
||||
|
@ -81,8 +81,8 @@ class DefaultJwtBuilderTest {
|
|||
}
|
||||
|
||||
replay provider
|
||||
def b = new DefaultJwtBuilder().setProvider(provider)
|
||||
.setSubject('me').signWith(Jwts.SIG.HS256.keyBuilder().build(), alg)
|
||||
def b = new DefaultJwtBuilder().provider(provider)
|
||||
.setSubject('me').signWith(Jwts.SIG.HS256.key().build(), alg)
|
||||
assertSame provider, b.provider
|
||||
b.compact()
|
||||
verify provider
|
||||
|
@ -113,7 +113,7 @@ class DefaultJwtBuilderTest {
|
|||
}
|
||||
|
||||
@Override
|
||||
KeyPairBuilder keyPairBuilder() {
|
||||
KeyPairBuilder keyPair() {
|
||||
throw new IllegalStateException("should not be called during build")
|
||||
}
|
||||
|
||||
|
@ -123,8 +123,8 @@ class DefaultJwtBuilderTest {
|
|||
}
|
||||
}
|
||||
|
||||
def b = new DefaultJwtBuilder().setSecureRandom(random)
|
||||
.setSubject('me').signWith(Jwts.SIG.HS256.keyBuilder().build(), alg)
|
||||
def b = new DefaultJwtBuilder().random(random)
|
||||
.setSubject('me').signWith(Jwts.SIG.HS256.key().build(), alg)
|
||||
assertSame random, b.secureRandom
|
||||
b.compact()
|
||||
assertTrue called[0]
|
||||
|
@ -132,44 +132,53 @@ class DefaultJwtBuilderTest {
|
|||
|
||||
@Test
|
||||
void testSetHeader() {
|
||||
def h = Jwts.header().set('foo', 'bar').build()
|
||||
def h = Jwts.header().add('foo', 'bar').build()
|
||||
builder.setHeader(h)
|
||||
assertEquals h, builder.buildHeader()
|
||||
assertEquals h, builder.headerBuilder.build()
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetHeaderFromMap() {
|
||||
def m = [foo: 'bar']
|
||||
builder.setHeader(m)
|
||||
assertEquals builder.buildHeader().foo, 'bar'
|
||||
assertEquals builder.headerBuilder.build().foo, 'bar'
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetHeaderParams() {
|
||||
def m = [a: 'b', c: 'd']
|
||||
builder.setHeaderParams(m)
|
||||
assertEquals builder.buildHeader().a, 'b'
|
||||
assertEquals builder.buildHeader().c, 'd'
|
||||
assertEquals builder.headerBuilder.build().a, 'b'
|
||||
assertEquals builder.headerBuilder.build().c, 'd'
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetHeaderParam() {
|
||||
builder.setHeaderParam('foo', 'bar')
|
||||
assertEquals builder.buildHeader().foo, 'bar'
|
||||
assertEquals builder.headerBuilder.build().foo, 'bar'
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetClaims() {
|
||||
Claims c = Jwts.claims().set('foo', 'bar').build()
|
||||
Claims c = Jwts.claims().add('foo', 'bar').build()
|
||||
builder.setClaims(c)
|
||||
assertEquals c, builder.claimsBuilder
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetClaimsMap() {
|
||||
def m = [foo: 'bar']
|
||||
builder.setClaims(m)
|
||||
assertEquals 1, builder.claimsBuilder.size()
|
||||
assertTrue builder.claimsBuilder.containsKey('foo')
|
||||
assertTrue builder.claimsBuilder.containsValue('bar')
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAddClaims() {
|
||||
def b = new DefaultJwtBuilder()
|
||||
def c = Jwts.claims([initial: 'initial'])
|
||||
b.setClaims(c)
|
||||
b.claims().add(c)
|
||||
def c2 = [foo: 'bar', baz: 'buz']
|
||||
b.addClaims(c2)
|
||||
assertEquals 'initial', b.claimsBuilder.get('initial')
|
||||
|
@ -203,8 +212,8 @@ class DefaultJwtBuilderTest {
|
|||
|
||||
@Test
|
||||
void testExistingClaimsAndSetClaim() {
|
||||
Claims c = Jwts.claims().set('foo', 'bar').build()
|
||||
builder.setClaims(c)
|
||||
Claims c = Jwts.claims().add('foo', 'bar').build()
|
||||
builder.claims().add(c)
|
||||
assertEquals c, builder.claimsBuilder
|
||||
assertEquals builder.claimsBuilder.size(), 1
|
||||
assertEquals c.size(), 1
|
||||
|
@ -253,7 +262,7 @@ class DefaultJwtBuilderTest {
|
|||
@Test
|
||||
void testCompactWithJwsHeader() {
|
||||
def b = new DefaultJwtBuilder()
|
||||
b.header().setKeyId('a')
|
||||
b.header().keyId('a')
|
||||
b.setPayload('foo')
|
||||
def alg = SignatureAlgorithm.HS256
|
||||
def key = Keys.secretKeyFor(alg)
|
||||
|
@ -273,7 +282,7 @@ class DefaultJwtBuilderTest {
|
|||
throw new SerializationException('foo', new Exception())
|
||||
}
|
||||
}
|
||||
def b = new DefaultJwtBuilder().serializeToJsonWith(serializer)
|
||||
def b = new DefaultJwtBuilder().serializer(serializer)
|
||||
try {
|
||||
b.setPayload('foo').compact()
|
||||
fail()
|
||||
|
@ -306,7 +315,7 @@ class DefaultJwtBuilderTest {
|
|||
void testSignWithKeyOnly() {
|
||||
|
||||
def b = new DefaultJwtBuilder()
|
||||
b.header().setKeyId('a')
|
||||
b.header().keyId('a')
|
||||
b.setPayload('foo')
|
||||
|
||||
def key = KeyGenerator.getInstance('HmacSHA256').generateKey()
|
||||
|
@ -417,8 +426,8 @@ class DefaultJwtBuilderTest {
|
|||
return null
|
||||
}
|
||||
}
|
||||
def b = new DefaultJwtBuilder().base64UrlEncodeWith(encoder)
|
||||
assertSame encoder, b.base64UrlEncoder
|
||||
def b = new DefaultJwtBuilder().encoder(encoder)
|
||||
assertSame encoder, b.encoder
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException)
|
||||
|
@ -474,7 +483,7 @@ class DefaultJwtBuilderTest {
|
|||
@Test
|
||||
void testCompactSimplestPayload() {
|
||||
def enc = Jwts.ENC.A128GCM
|
||||
def key = enc.keyBuilder().build()
|
||||
def key = enc.key().build()
|
||||
def jwe = builder.setPayload("me").encryptWith(key, enc).compact()
|
||||
def jwt = Jwts.parser().decryptWith(key).build().parseContentJwe(jwe)
|
||||
assertEquals 'me', new String(jwt.getPayload(), StandardCharsets.UTF_8)
|
||||
|
@ -483,7 +492,7 @@ class DefaultJwtBuilderTest {
|
|||
@Test
|
||||
void testCompactSimplestClaims() {
|
||||
def enc = Jwts.ENC.A128GCM
|
||||
def key = enc.keyBuilder().build()
|
||||
def key = enc.key().build()
|
||||
def jwe = builder.setSubject('joe').encryptWith(key, enc).compact()
|
||||
def jwt = Jwts.parser().decryptWith(key).build().parseClaimsJwe(jwe)
|
||||
assertEquals 'joe', jwt.getPayload().getSubject()
|
||||
|
|
|
@ -47,7 +47,11 @@ class DefaultJwtHeaderBuilderTest {
|
|||
@SuppressWarnings('GroovyAssignabilityCheck')
|
||||
private static void assertSymmetry(String propName, def val) {
|
||||
def name = Strings.capitalize(propName)
|
||||
builder."set$name"(val)
|
||||
switch (propName) {
|
||||
case 'algorithm': builder.add('alg', val); break // no setter
|
||||
case 'compressionAlgorithm': builder.add('zip', val); break // no setter
|
||||
default: builder."$propName"(val)
|
||||
}
|
||||
header = builder.build()
|
||||
if (val instanceof byte[]) {
|
||||
assertArrayEquals val, header."get$name"()
|
||||
|
@ -192,7 +196,7 @@ class DefaultJwtHeaderBuilderTest {
|
|||
@Test
|
||||
void testPutAll() {
|
||||
def m = ['foo': 'bar', 'baz': 'bat']
|
||||
def header = builder.set(m).build()
|
||||
def header = builder.add(m).build()
|
||||
assertEquals m, header
|
||||
}
|
||||
|
||||
|
@ -208,7 +212,7 @@ class DefaultJwtHeaderBuilderTest {
|
|||
@Test
|
||||
void testClear() {
|
||||
def m = ['foo': 'bar', 'baz': 'bat']
|
||||
builder.set(m)
|
||||
builder.add(m)
|
||||
builder.clear()
|
||||
def header = builder.build()
|
||||
assertTrue header.isEmpty()
|
||||
|
@ -217,7 +221,7 @@ class DefaultJwtHeaderBuilderTest {
|
|||
@Test
|
||||
void testEmpty() {
|
||||
def m = ['foo': 'bar', 'baz': 'bat']
|
||||
def header = builder.set(m).empty().build()
|
||||
def header = builder.add(m).empty().build()
|
||||
assertTrue header.isEmpty()
|
||||
}
|
||||
|
||||
|
@ -259,6 +263,15 @@ class DefaultJwtHeaderBuilderTest {
|
|||
assertSymmetry('compressionAlgorithm', 'DEF')
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDeprecatedSetters() { // TODO: remove before 1.0
|
||||
assertEquals 'foo', builder.setType('foo').build().getType()
|
||||
assertEquals 'foo', builder.setContentType('foo').build().getContentType()
|
||||
assertEquals 'foo', builder.setCompressionAlgorithm('foo').build().getCompressionAlgorithm()
|
||||
assertEquals 'foo', builder.setKeyId('foo').build().getKeyId()
|
||||
assertEquals 'foo', builder.setAlgorithm('foo').build().getAlgorithm()
|
||||
}
|
||||
|
||||
// ====================== Protected Header Methods =======================
|
||||
|
||||
/**
|
||||
|
@ -277,7 +290,7 @@ class DefaultJwtHeaderBuilderTest {
|
|||
*/
|
||||
@Test
|
||||
void testJwk() {
|
||||
def jwk = Jwks.builder().forKey(TestKeys.RS256.pair.public as RSAPublicKey).build()
|
||||
def jwk = Jwks.builder().key(TestKeys.RS256.pair.public as RSAPublicKey).build()
|
||||
assertJws('jwk', jwk)
|
||||
}
|
||||
|
||||
|
@ -332,7 +345,7 @@ class DefaultJwtHeaderBuilderTest {
|
|||
def x5t = DefaultHashAlgorithm.SHA1.digest(request)
|
||||
String encoded = Encoders.BASE64URL.encode(x5t)
|
||||
|
||||
builder.setX509CertificateSha1Thumbprint(x5t)
|
||||
builder.x509CertificateSha1Thumbprint(x5t)
|
||||
header = builder.build() as JwsHeader
|
||||
assertTrue header instanceof JwsHeader
|
||||
assertArrayEquals x5t, header.getX509CertificateSha1Thumbprint()
|
||||
|
@ -345,7 +358,7 @@ class DefaultJwtHeaderBuilderTest {
|
|||
Request<byte[]> request = new DefaultRequest(chain[0].getEncoded(), null, null)
|
||||
def x5t = DefaultHashAlgorithm.SHA1.digest(request)
|
||||
String encoded = Encoders.BASE64URL.encode(x5t)
|
||||
def header = builder.setX509CertificateChain(chain).withX509Sha1Thumbprint(true).build() as JwsHeader
|
||||
def header = builder.x509CertificateChain(chain).withX509Sha1Thumbprint(true).build() as JwsHeader
|
||||
assertTrue header instanceof JwsHeader
|
||||
assertArrayEquals x5t, header.getX509CertificateSha1Thumbprint()
|
||||
assertEquals encoded, header.get('x5t')
|
||||
|
@ -361,7 +374,7 @@ class DefaultJwtHeaderBuilderTest {
|
|||
def x5tS256 = Jwks.HASH.@SHA256.digest(request)
|
||||
String encoded = Encoders.BASE64URL.encode(x5tS256)
|
||||
|
||||
builder.setX509CertificateSha256Thumbprint(x5tS256)
|
||||
builder.x509CertificateSha256Thumbprint(x5tS256)
|
||||
header = builder.build() as JwsHeader
|
||||
assertTrue header instanceof JwsHeader
|
||||
assertArrayEquals x5tS256, header.getX509CertificateSha256Thumbprint()
|
||||
|
@ -374,7 +387,7 @@ class DefaultJwtHeaderBuilderTest {
|
|||
Request<byte[]> request = new DefaultRequest(chain[0].getEncoded(), null, null)
|
||||
def x5tS256 = Jwks.HASH.SHA256.digest(request)
|
||||
String encoded = Encoders.BASE64URL.encode(x5tS256)
|
||||
def header = builder.setX509CertificateChain(chain).withX509Sha256Thumbprint(true).build() as JwsHeader
|
||||
def header = builder.x509CertificateChain(chain).withX509Sha256Thumbprint(true).build() as JwsHeader
|
||||
assertTrue header instanceof JwsHeader
|
||||
assertArrayEquals x5tS256, header.getX509CertificateSha256Thumbprint()
|
||||
assertEquals encoded, header.get('x5t#S256')
|
||||
|
@ -393,7 +406,7 @@ class DefaultJwtHeaderBuilderTest {
|
|||
@Test
|
||||
void testEphemeralPublicKey() {
|
||||
def key = TestKeys.ES256.pair.public
|
||||
def jwk = Jwks.builder().forKey(key).build()
|
||||
def jwk = Jwks.builder().key(key).build()
|
||||
builder.put('epk', jwk)
|
||||
header = builder.build() as JweHeader
|
||||
assertEquals jwk, header.getEphemeralPublicKey()
|
||||
|
@ -409,7 +422,7 @@ class DefaultJwtHeaderBuilderTest {
|
|||
void testAgreementPartyUInfoString() {
|
||||
def s = "UInfo"
|
||||
def info = Strings.utf8(s)
|
||||
builder.setAgreementPartyUInfo(s).build()
|
||||
builder.agreementPartyUInfo(s).build()
|
||||
header = builder.build() as JweHeader
|
||||
assertArrayEquals info, header.getAgreementPartyUInfo()
|
||||
}
|
||||
|
@ -424,7 +437,7 @@ class DefaultJwtHeaderBuilderTest {
|
|||
void testAgreementPartyVInfoString() {
|
||||
def s = "VInfo"
|
||||
def info = Strings.utf8(s)
|
||||
builder.setAgreementPartyVInfo(s)
|
||||
builder.agreementPartyVInfo(s)
|
||||
header = builder.build() as JweHeader
|
||||
assertArrayEquals info, header.getAgreementPartyVInfo()
|
||||
}
|
||||
|
@ -465,7 +478,7 @@ class DefaultJwtHeaderBuilderTest {
|
|||
assertEquals new DefaultHeader([foo: 'bar']), builder.build()
|
||||
|
||||
// add JWS-required property:
|
||||
builder.setAlgorithm('HS256')
|
||||
builder.put(DefaultHeader.ALGORITHM.getId(), 'HS256')
|
||||
assertEquals new DefaultJwsHeader([foo: 'bar', alg: 'HS256']), builder.build()
|
||||
|
||||
// add JWE required property:
|
||||
|
|
|
@ -24,10 +24,12 @@ import io.jsonwebtoken.io.Decoder
|
|||
import io.jsonwebtoken.io.DecodingException
|
||||
import io.jsonwebtoken.io.DeserializationException
|
||||
import io.jsonwebtoken.io.Deserializer
|
||||
import io.jsonwebtoken.security.*
|
||||
import org.hamcrest.CoreMatchers
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
|
||||
import javax.crypto.SecretKey
|
||||
import java.security.Provider
|
||||
|
||||
import static org.easymock.EasyMock.*
|
||||
|
@ -53,7 +55,7 @@ class DefaultJwtParserBuilderTest {
|
|||
Provider provider = createMock(Provider)
|
||||
replay provider
|
||||
|
||||
def parser = builder.setProvider(provider).build()
|
||||
def parser = builder.provider(provider).build()
|
||||
|
||||
assertSame provider, parser.provider
|
||||
verify provider
|
||||
|
@ -63,7 +65,7 @@ class DefaultJwtParserBuilderTest {
|
|||
void testKeyLocatorAndVerificationKeyConfigured() {
|
||||
try {
|
||||
builder
|
||||
.setKeyLocator(new ConstantKeyLocator(null, null))
|
||||
.keyLocator(new ConstantKeyLocator(null, null))
|
||||
.verifyWith(TestKeys.HS256)
|
||||
.build()
|
||||
fail()
|
||||
|
@ -77,7 +79,7 @@ class DefaultJwtParserBuilderTest {
|
|||
void testKeyLocatorAndDecryptionKeyConfigured() {
|
||||
try {
|
||||
builder
|
||||
.setKeyLocator(new ConstantKeyLocator(null, null))
|
||||
.keyLocator(new ConstantKeyLocator(null, null))
|
||||
.decryptWith(TestKeys.A128GCM)
|
||||
.build()
|
||||
fail()
|
||||
|
@ -101,7 +103,7 @@ class DefaultJwtParserBuilderTest {
|
|||
}
|
||||
}
|
||||
def b = builder.base64UrlDecodeWith(decoder).build()
|
||||
assertSame decoder, b.base64UrlDecoder
|
||||
assertSame decoder, b.decoder
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException)
|
||||
|
@ -121,7 +123,7 @@ class DefaultJwtParserBuilderTest {
|
|||
assertSame deserializer, p.deserializer
|
||||
|
||||
def alg = Jwts.SIG.HS256
|
||||
def key = alg.keyBuilder().build()
|
||||
def key = alg.key().build()
|
||||
|
||||
String jws = Jwts.builder().claim('foo', 'bar').signWith(key, alg).compact()
|
||||
|
||||
|
@ -161,10 +163,122 @@ class DefaultJwtParserBuilderTest {
|
|||
void testAddCompressionAlgorithms() {
|
||||
def codec = new TestCompressionCodec(id: 'test')
|
||||
def parser = builder.addCompressionAlgorithms([codec] as Set<CompressionCodec>).build()
|
||||
def header = Jwts.header().setCompressionAlgorithm(codec.getId()).build()
|
||||
def header = Jwts.header().add('zip', codec.getId()).build()
|
||||
assertSame codec, parser.zipAlgFn.locate(header)
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAddCompressionAlgorithmsOverrideDefaults() {
|
||||
def header = Jwts.header().add('zip', 'DEF').build()
|
||||
def parser = builder.build()
|
||||
assertSame Jwts.ZIP.DEF, parser.zipAlgFn.apply(header) // standard implementation default
|
||||
|
||||
def alg = new TestCompressionCodec(id: 'DEF') // custom impl with standard identifier
|
||||
parser = builder.addCompressionAlgorithms([alg]).build()
|
||||
assertSame alg, parser.zipAlgFn.apply(header) // custom one, not standard impl
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCaseSensitiveCompressionAlgorithm() {
|
||||
def standard = Jwts.header().add('zip', 'DEF').build()
|
||||
def nonStandard = Jwts.header().add('zip', 'def').build()
|
||||
def parser = builder.build()
|
||||
assertSame Jwts.ZIP.DEF, parser.zipAlgFn.apply(standard) // standard implementation default
|
||||
try {
|
||||
parser.zipAlgFn.apply(nonStandard)
|
||||
fail()
|
||||
} catch (UnsupportedJwtException e) {
|
||||
String msg = "Unrecognized JWT ${DefaultHeader.COMPRESSION_ALGORITHM} header value: def"
|
||||
assertEquals msg, e.getMessage()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAddEncryptionAlgorithmsOverrideDefaults() {
|
||||
final String standardId = Jwts.ENC.A256GCM.getId()
|
||||
def header = Jwts.header().add('enc', standardId).build()
|
||||
def parser = builder.build()
|
||||
assertSame Jwts.ENC.A256GCM, parser.encAlgFn.apply(header) // standard implementation default
|
||||
|
||||
def custom = new TestAeadAlgorithm(id: standardId) // custom impl with standard identifier
|
||||
parser = builder.addEncryptionAlgorithms([custom]).build()
|
||||
assertSame custom, parser.encAlgFn.apply(header) // custom one, not standard impl
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCaseSensitiveEncryptionAlgorithm() {
|
||||
def alg = Jwts.ENC.A256GCM
|
||||
def standard = Jwts.header().add('enc', alg.id).build()
|
||||
def nonStandard = Jwts.header().add('enc', alg.id.toLowerCase()).build()
|
||||
def parser = builder.build()
|
||||
assertSame alg, parser.encAlgFn.apply(standard) // standard id
|
||||
try {
|
||||
parser.encAlgFn.apply(nonStandard) // non-standard id
|
||||
fail()
|
||||
} catch (UnsupportedJwtException e) {
|
||||
String msg = "Unrecognized JWE ${DefaultJweHeader.ENCRYPTION_ALGORITHM} header value: ${alg.id.toLowerCase()}"
|
||||
assertEquals msg, e.getMessage()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAddKeyAlgorithmsOverrideDefaults() {
|
||||
final String standardId = Jwts.KEY.A256GCMKW.id
|
||||
def header = Jwts.header().add('enc', Jwts.ENC.A256GCM.id).add('alg', standardId).build()
|
||||
def parser = builder.build()
|
||||
assertSame Jwts.KEY.A256GCMKW, parser.keyAlgFn.apply(header) // standard implementation default
|
||||
|
||||
def custom = new TestKeyAlgorithm(id: standardId) // custom impl with standard identifier
|
||||
parser = builder.addKeyAlgorithms([custom]).build()
|
||||
assertSame custom, parser.keyAlgFn.apply(header) // custom one, not standard impl
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCaseSensitiveKeyAlgorithm() {
|
||||
def alg = Jwts.KEY.A256GCMKW
|
||||
def hb = Jwts.header().add('enc', Jwts.ENC.A256GCM.id)
|
||||
def standard = hb.add('alg', alg.id).build()
|
||||
def nonStandard = hb.add('alg', alg.id.toLowerCase()).build()
|
||||
def parser = builder.build()
|
||||
assertSame alg, parser.keyAlgFn.apply(standard) // standard id
|
||||
try {
|
||||
parser.keyAlgFn.apply(nonStandard) // non-standard id
|
||||
fail()
|
||||
} catch (UnsupportedJwtException e) {
|
||||
String msg = "Unrecognized JWE ${DefaultJweHeader.ALGORITHM} header value: ${alg.id.toLowerCase()}"
|
||||
assertEquals msg, e.getMessage()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAddSignatureAlgorithmsOverrideDefaults() {
|
||||
final String standardId = Jwts.SIG.HS256.id
|
||||
def header = Jwts.header().add('alg', standardId).build()
|
||||
def parser = builder.build()
|
||||
assertSame Jwts.SIG.HS256, parser.sigAlgFn.apply(header) // standard implementation default
|
||||
|
||||
def custom = new TestMacAlgorithm(id: standardId) // custom impl with standard identifier
|
||||
parser = builder.addSignatureAlgorithms([custom]).build()
|
||||
assertSame custom, parser.sigAlgFn.apply(header) // custom one, not standard impl
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCaseSensitiveSignatureAlgorithm() {
|
||||
def alg = Jwts.SIG.HS256
|
||||
def hb = Jwts.header().add('alg', alg.id)
|
||||
def standard = hb.build()
|
||||
def nonStandard = hb.add('alg', alg.id.toLowerCase()).build()
|
||||
def parser = builder.build()
|
||||
assertSame alg, parser.sigAlgFn.apply(standard) // standard id
|
||||
try {
|
||||
parser.sigAlgFn.apply(nonStandard) // non-standard id
|
||||
fail()
|
||||
} catch (UnsupportedJwtException e) {
|
||||
String msg = "Unrecognized JWS ${DefaultJwsHeader.ALGORITHM} header value: ${alg.id.toLowerCase()}"
|
||||
assertEquals msg, e.getMessage()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCompressionCodecResolverAndExtraCompressionCodecs() {
|
||||
def codec = new TestCompressionCodec(id: 'test')
|
||||
|
@ -189,7 +303,7 @@ class DefaultJwtParserBuilderTest {
|
|||
builder.enableUnsecuredDecompression().build()
|
||||
fail()
|
||||
} catch (IllegalStateException ise) {
|
||||
String expected = "'enableUnsecuredDecompression' is only relevant if 'enableUnsecuredJws' " + "is also configured. Please read the JavaDoc of both features before enabling either " + "due to their security implications."
|
||||
String expected = "'enableUnsecuredDecompression' is only relevant if 'enableUnsecured' " + "is also configured. Please read the JavaDoc of both features before enabling either " + "due to their security implications."
|
||||
assertEquals expected, ise.getMessage()
|
||||
}
|
||||
}
|
||||
|
@ -199,7 +313,7 @@ class DefaultJwtParserBuilderTest {
|
|||
def codec = Jwts.ZIP.GZIP
|
||||
String jwt = Jwts.builder().compressWith(codec).setSubject('joe').compact()
|
||||
try {
|
||||
builder.enableUnsecuredJws().build().parse(jwt)
|
||||
builder.enableUnsecured().build().parse(jwt)
|
||||
fail()
|
||||
} catch (UnsupportedJwtException e) {
|
||||
String expected = String.format(DefaultJwtParser.UNPROTECTED_DECOMPRESSION_MSG, codec.getId())
|
||||
|
@ -211,7 +325,7 @@ class DefaultJwtParserBuilderTest {
|
|||
void testDecompressUnprotectedJwtEnabled() {
|
||||
def codec = Jwts.ZIP.GZIP
|
||||
String jws = Jwts.builder().compressWith(codec).setSubject('joe').compact()
|
||||
def jwt = builder.enableUnsecuredJws().enableUnsecuredDecompression().build().parse(jws)
|
||||
def jwt = builder.enableUnsecured().enableUnsecuredDecompression().build().parse(jws)
|
||||
assertEquals 'joe', ((Claims) jwt.getPayload()).getSubject()
|
||||
}
|
||||
|
||||
|
@ -252,6 +366,11 @@ class DefaultJwtParserBuilderTest {
|
|||
return this.id
|
||||
}
|
||||
|
||||
@Override
|
||||
String getId() {
|
||||
return this.id
|
||||
}
|
||||
|
||||
@Override
|
||||
byte[] compress(byte[] content) throws CompressionException {
|
||||
return new byte[0]
|
||||
|
@ -261,10 +380,87 @@ class DefaultJwtParserBuilderTest {
|
|||
byte[] decompress(byte[] compressed) throws CompressionException {
|
||||
return new byte[0]
|
||||
}
|
||||
}
|
||||
|
||||
static class TestAeadAlgorithm implements AeadAlgorithm {
|
||||
|
||||
String id
|
||||
int keyBitLength = 256
|
||||
|
||||
@Override
|
||||
String getId() {
|
||||
return this.id
|
||||
return id
|
||||
}
|
||||
|
||||
@Override
|
||||
AeadResult encrypt(AeadRequest request) throws SecurityException {
|
||||
return null
|
||||
}
|
||||
|
||||
@Override
|
||||
Message<byte[]> decrypt(DecryptAeadRequest request) throws SecurityException {
|
||||
return null
|
||||
}
|
||||
|
||||
@Override
|
||||
SecretKeyBuilder key() {
|
||||
return null
|
||||
}
|
||||
|
||||
@Override
|
||||
int getKeyBitLength() {
|
||||
return keyBitLength
|
||||
}
|
||||
}
|
||||
|
||||
static class TestKeyAlgorithm implements KeyAlgorithm {
|
||||
|
||||
String id
|
||||
int keyBitLength = 256
|
||||
|
||||
@Override
|
||||
String getId() {
|
||||
return id
|
||||
}
|
||||
|
||||
@Override
|
||||
KeyResult getEncryptionKey(KeyRequest request) throws SecurityException {
|
||||
return null
|
||||
}
|
||||
|
||||
@Override
|
||||
SecretKey getDecryptionKey(DecryptionKeyRequest request) throws SecurityException {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
static class TestMacAlgorithm implements MacAlgorithm {
|
||||
|
||||
String id
|
||||
|
||||
@Override
|
||||
String getId() {
|
||||
return id
|
||||
}
|
||||
|
||||
@Override
|
||||
byte[] digest(SecureRequest<byte[], SecretKey> request) throws SecurityException {
|
||||
return new byte[0]
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean verify(VerifySecureDigestRequest<SecretKey> request) throws SecurityException {
|
||||
return false
|
||||
}
|
||||
|
||||
@Override
|
||||
SecretKeyBuilder key() {
|
||||
return null
|
||||
}
|
||||
|
||||
@Override
|
||||
int getKeyBitLength() {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ class DefaultJwtParserTest {
|
|||
|
||||
@Test(expected = MalformedJwtException)
|
||||
void testBase64UrlDecodeWithInvalidInput() {
|
||||
newParser().base64UrlDecode('20:SLDKJF;3993;----', 'test')
|
||||
newParser().decode('20:SLDKJF;3993;----', 'test')
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -66,7 +66,7 @@ class DefaultJwtParserTest {
|
|||
assertTrue("Expected wrapping deserializer to be instance of JwtDeserializer", p.deserializer instanceof JwtDeserializer )
|
||||
assertSame deserializer, p.deserializer.deserializer
|
||||
|
||||
def key = Jwts.SIG.HS256.keyBuilder().build()
|
||||
def key = Jwts.SIG.HS256.key().build()
|
||||
|
||||
String jws = Jwts.builder().claim('foo', 'bar').signWith(key, Jwts.SIG.HS256).compact()
|
||||
|
||||
|
|
|
@ -29,8 +29,8 @@ class DefaultJwtTest {
|
|||
|
||||
@Test
|
||||
void testToString() {
|
||||
String compact = Jwts.builder().setHeaderParam('foo', 'bar').setAudience('jsmith').compact()
|
||||
Jwt jwt = Jwts.parser().enableUnsecuredJws().build().parseClaimsJwt(compact)
|
||||
String compact = Jwts.builder().header().add('foo', 'bar').and().audience('jsmith').compact()
|
||||
Jwt jwt = Jwts.parser().enableUnsecured().build().parseClaimsJwt(compact)
|
||||
assertEquals 'header={foo=bar, alg=none},payload={aud=jsmith}', jwt.toString()
|
||||
}
|
||||
|
||||
|
@ -38,15 +38,15 @@ class DefaultJwtTest {
|
|||
void testByteArrayPayloadToString() {
|
||||
byte[] bytes = 'hello JJWT'.getBytes(StandardCharsets.UTF_8)
|
||||
String encoded = Encoders.BASE64URL.encode(bytes)
|
||||
String compact = Jwts.builder().setHeaderParam('foo', 'bar').setContent(bytes).compact()
|
||||
Jwt jwt = Jwts.parser().enableUnsecuredJws().build().parseContentJwt(compact)
|
||||
String compact = Jwts.builder().header().add('foo', 'bar').and().content(bytes).compact()
|
||||
Jwt jwt = Jwts.parser().enableUnsecured().build().parseContentJwt(compact)
|
||||
assertEquals "header={foo=bar, alg=none},payload=$encoded" as String, jwt.toString()
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEqualsAndHashCode() {
|
||||
String compact = Jwts.builder().claim('foo', 'bar').compact()
|
||||
def parser = Jwts.parser().enableUnsecuredJws().build()
|
||||
def parser = Jwts.parser().enableUnsecured().build()
|
||||
def jwt1 = parser.parseClaimsJwt(compact)
|
||||
def jwt2 = parser.parseClaimsJwt(compact)
|
||||
assertNotEquals jwt1, 'hello' as String
|
||||
|
@ -60,7 +60,7 @@ class DefaultJwtTest {
|
|||
@Test
|
||||
void testBodyAndPayloadSame() {
|
||||
String compact = Jwts.builder().claim('foo', 'bar').compact()
|
||||
def parser = Jwts.parser().enableUnsecuredJws().build()
|
||||
def parser = Jwts.parser().enableUnsecured().build()
|
||||
def jwt1 = parser.parseClaimsJwt(compact)
|
||||
def jwt2 = parser.parseClaimsJwt(compact)
|
||||
assertEquals jwt1.getBody(), jwt1.getPayload()
|
||||
|
|
|
@ -43,7 +43,11 @@ class DefaultMutableJweHeaderTest {
|
|||
@SuppressWarnings('GroovyAssignabilityCheck')
|
||||
private static void assertSymmetry(String propName, def val) {
|
||||
def name = Strings.capitalize(propName)
|
||||
header."set$name"(val)
|
||||
switch (propName) {
|
||||
case 'algorithm': header.add('alg', val); break // no setter
|
||||
case 'compressionAlgorithm': header.add('zip', val); break // no setter
|
||||
default: header."$propName"(val)
|
||||
}
|
||||
|
||||
if (val instanceof byte[]) {
|
||||
assertArrayEquals val, header."get$name"()
|
||||
|
@ -214,7 +218,7 @@ class DefaultMutableJweHeaderTest {
|
|||
*/
|
||||
@Test
|
||||
void testJwk() {
|
||||
def jwk = Jwks.builder().forKey(TestKeys.RS256.pair.public as RSAPublicKey).build()
|
||||
def jwk = Jwks.builder().key(TestKeys.RS256.pair.public as RSAPublicKey).build()
|
||||
assertSymmetry('jwk', jwk)
|
||||
}
|
||||
|
||||
|
@ -269,7 +273,7 @@ class DefaultMutableJweHeaderTest {
|
|||
def x5t = DefaultHashAlgorithm.SHA1.digest(request)
|
||||
String encoded = Encoders.BASE64URL.encode(x5t)
|
||||
|
||||
header.setX509CertificateSha1Thumbprint(x5t)
|
||||
header.x509CertificateSha1Thumbprint(x5t)
|
||||
assertArrayEquals x5t, header.getX509CertificateSha1Thumbprint()
|
||||
assertEquals encoded, header.get('x5t')
|
||||
}
|
||||
|
@ -284,7 +288,7 @@ class DefaultMutableJweHeaderTest {
|
|||
def x5tS256 = Jwks.HASH.@SHA256.digest(request)
|
||||
String encoded = Encoders.BASE64URL.encode(x5tS256)
|
||||
|
||||
header.setX509CertificateSha256Thumbprint(x5tS256)
|
||||
header.x509CertificateSha256Thumbprint(x5tS256)
|
||||
assertArrayEquals x5tS256, header.getX509CertificateSha256Thumbprint()
|
||||
assertEquals encoded, header.get('x5t#S256')
|
||||
}
|
||||
|
@ -301,7 +305,7 @@ class DefaultMutableJweHeaderTest {
|
|||
@Test
|
||||
void testEphemeralPublicKey() {
|
||||
def key = TestKeys.ES256.pair.public
|
||||
def jwk = Jwks.builder().forKey(key).build()
|
||||
def jwk = Jwks.builder().key(key).build()
|
||||
header.put('epk', jwk)
|
||||
assertEquals jwk, header.getEphemeralPublicKey()
|
||||
}
|
||||
|
@ -316,7 +320,7 @@ class DefaultMutableJweHeaderTest {
|
|||
void testAgreementPartyUInfoString() {
|
||||
def s = "UInfo"
|
||||
def info = Strings.utf8(s)
|
||||
header.setAgreementPartyVInfo(s)
|
||||
header.agreementPartyVInfo(s)
|
||||
assertArrayEquals info, header.getAgreementPartyVInfo()
|
||||
}
|
||||
|
||||
|
@ -330,7 +334,7 @@ class DefaultMutableJweHeaderTest {
|
|||
void testAgreementPartyVInfoString() {
|
||||
def s = "VInfo"
|
||||
def info = Strings.utf8(s)
|
||||
header.setAgreementPartyVInfo(s)
|
||||
header.agreementPartyVInfo(s)
|
||||
assertArrayEquals info, header.getAgreementPartyVInfo()
|
||||
}
|
||||
|
||||
|
|
|
@ -1,74 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2015 jsonwebtoken.io
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.jsonwebtoken.impl
|
||||
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest
|
||||
import org.powermock.modules.junit4.PowerMockRunner
|
||||
|
||||
import static org.junit.Assert.*
|
||||
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PrepareForTest([System.class])
|
||||
class DefaultTextCodecFactoryTest {
|
||||
|
||||
@Test
|
||||
void testGetSystemProperty() {
|
||||
def factory = new DefaultTextCodecFactory()
|
||||
assertNotNull factory.getSystemProperty("java.version")
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIsAndroidByVmName() {
|
||||
|
||||
def factory = new DefaultTextCodecFactory() {
|
||||
@Override
|
||||
protected String getSystemProperty(String key) {
|
||||
return 'dalvik'
|
||||
}
|
||||
}
|
||||
|
||||
assertTrue factory.getTextCodec() instanceof AndroidBase64Codec
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIsAndroidByNullVmName() {
|
||||
|
||||
def factory = new DefaultTextCodecFactory() {
|
||||
@Override
|
||||
protected String getSystemProperty(String key) {
|
||||
if (key == 'java.vm.name') return null;
|
||||
return 'android'
|
||||
}
|
||||
}
|
||||
|
||||
assertTrue factory.getTextCodec() instanceof AndroidBase64Codec
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIsAndroidByNullVmNameAndNullVendorName() {
|
||||
|
||||
def factory = new DefaultTextCodecFactory() {
|
||||
@Override
|
||||
protected String getSystemProperty(String key) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
assertFalse factory.getTextCodec() instanceof AndroidBase64Codec
|
||||
}
|
||||
}
|
|
@ -46,7 +46,7 @@ class IdLocatorTest {
|
|||
@Test
|
||||
void unrequiredHeaderValueTest() {
|
||||
locator = new IdLocator(TEST_FIELD, registry, Collections.emptyList(), null)
|
||||
def header = Jwts.header().setAlgorithm('none').build()
|
||||
def header = Jwts.header().add('a', 'b').build()
|
||||
assertNull locator.apply(header)
|
||||
}
|
||||
|
||||
|
@ -63,7 +63,7 @@ class IdLocatorTest {
|
|||
|
||||
@Test
|
||||
void unlocatableJwtHeaderInstanceTest() {
|
||||
def header = Jwts.header().set('foo', 'foo').build()
|
||||
def header = Jwts.header().add('foo', 'foo').build()
|
||||
try {
|
||||
locator.apply(header)
|
||||
} catch (UnsupportedJwtException expected) {
|
||||
|
@ -74,7 +74,7 @@ class IdLocatorTest {
|
|||
|
||||
@Test
|
||||
void unlocatableJwsHeaderInstanceTest() {
|
||||
def header = Jwts.header().setAlgorithm('HS256').set('foo', 'foo').build()
|
||||
def header = Jwts.header().add('alg', 'HS256').add('foo', 'foo').build()
|
||||
try {
|
||||
locator.apply(header)
|
||||
} catch (UnsupportedJwtException expected) {
|
||||
|
@ -85,7 +85,7 @@ class IdLocatorTest {
|
|||
|
||||
@Test
|
||||
void unlocatableJweHeaderInstanceTest() {
|
||||
def header = Jwts.header().set('enc', 'A256GCM').set('foo', 'foo').build()
|
||||
def header = Jwts.header().add('enc', 'A256GCM').add('foo', 'foo').build()
|
||||
try {
|
||||
locator.apply(header)
|
||||
} catch (UnsupportedJwtException expected) {
|
||||
|
|
|
@ -65,7 +65,7 @@ class JwtTokenizerTest {
|
|||
assertEquals 'header', tjwe.getProtected()
|
||||
assertEquals 'encryptedKey', tjwe.getEncryptedKey()
|
||||
assertEquals 'initializationVector', tjwe.getIv()
|
||||
assertEquals 'body', tjwe.getBody()
|
||||
assertEquals 'body', tjwe.getPayload()
|
||||
assertEquals 'authenticationTag', tjwe.getDigest()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ class DeflateCompressionCodecTest {
|
|||
@Test
|
||||
void testBackwardsCompatibility_0_10_6() {
|
||||
final String jwtFrom0106 = 'eyJhbGciOiJub25lIiwiemlwIjoiREVGIn0.eNqqVsosLlayUspNVdJRKi5NAjJLi1OLgJzMxBIlK0sTMzMLEwsDAx2l1IoCJSsTQwMjExOQQC0AAAD__w.'
|
||||
Jwts.parser().enableUnsecuredJws().enableUnsecuredDecompression().build().parseClaimsJwt(jwtFrom0106) // no exception should be thrown
|
||||
Jwts.parser().enableUnsecured().enableUnsecuredDecompression().build().parseClaimsJwt(jwtFrom0106) // no exception should be thrown
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -34,19 +34,19 @@ class AbstractAsymmetricJwkBuilderTest {
|
|||
private static final RSAPublicKey PUB_KEY = CERT.getPublicKey() as RSAPublicKey
|
||||
|
||||
private static RsaPublicJwkBuilder builder() {
|
||||
return Jwks.builder().forKey(PUB_KEY)
|
||||
return Jwks.builder().key(PUB_KEY)
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUse() {
|
||||
def val = UUID.randomUUID().toString()
|
||||
def jwk = builder().setPublicKeyUse(val).build()
|
||||
def jwk = builder().publicKeyUse(val).build()
|
||||
assertEquals val, jwk.getPublicKeyUse()
|
||||
assertEquals val, jwk.use
|
||||
|
||||
RSAPrivateKey privateKey = TestKeys.RS256.pair.private as RSAPrivateKey
|
||||
|
||||
jwk = builder().setPublicKeyUse(val).setPrivateKey(privateKey).build()
|
||||
jwk = builder().publicKeyUse(val).privateKey(privateKey).build()
|
||||
assertEquals val, jwk.getPublicKeyUse()
|
||||
assertEquals val, jwk.use
|
||||
}
|
||||
|
@ -54,12 +54,12 @@ class AbstractAsymmetricJwkBuilderTest {
|
|||
@Test
|
||||
void testX509Url() {
|
||||
def val = new URI(UUID.randomUUID().toString())
|
||||
assertSame val, builder().setX509Url(val).build().getX509Url()
|
||||
assertSame val, builder().x509Url(val).build().getX509Url()
|
||||
}
|
||||
|
||||
@Test
|
||||
void testX509CertificateChain() {
|
||||
assertEquals CHAIN, builder().setX509CertificateChain(CHAIN).build().getX509CertificateChain()
|
||||
assertEquals CHAIN, builder().x509CertificateChain(CHAIN).build().getX509CertificateChain()
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -67,7 +67,7 @@ class AbstractAsymmetricJwkBuilderTest {
|
|||
Request<byte[]> request = new DefaultRequest(TestKeys.RS256.cert.getEncoded(), null, null)
|
||||
def x5t = DefaultHashAlgorithm.SHA1.digest(request)
|
||||
def encoded = Encoders.BASE64URL.encode(x5t)
|
||||
def jwk = builder().setX509CertificateSha1Thumbprint(x5t).build()
|
||||
def jwk = builder().x509CertificateSha1Thumbprint(x5t).build()
|
||||
assertArrayEquals x5t, jwk.getX509CertificateSha1Thumbprint()
|
||||
assertEquals encoded, jwk.get(AbstractAsymmetricJwk.X5T.getId())
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ class AbstractAsymmetricJwkBuilderTest {
|
|||
Request<byte[]> request = new DefaultRequest(TestKeys.RS256.cert.getEncoded(), null, null)
|
||||
def x5t = DefaultHashAlgorithm.SHA1.digest(request)
|
||||
def encoded = Encoders.BASE64URL.encode(x5t)
|
||||
def jwk = builder().setX509CertificateChain(CHAIN).withX509Sha1Thumbprint(true).build()
|
||||
def jwk = builder().x509CertificateChain(CHAIN).withX509Sha1Thumbprint(true).build()
|
||||
assertArrayEquals x5t, jwk.getX509CertificateSha1Thumbprint()
|
||||
assertEquals encoded, jwk.get(AbstractAsymmetricJwk.X5T.getId())
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ class AbstractAsymmetricJwkBuilderTest {
|
|||
Request<byte[]> request = new DefaultRequest(TestKeys.RS256.cert.getEncoded(), null, null)
|
||||
def x5tS256 = Jwks.HASH.SHA256.digest(request)
|
||||
def encoded = Encoders.BASE64URL.encode(x5tS256)
|
||||
def jwk = builder().setX509CertificateSha256Thumbprint(x5tS256).build()
|
||||
def jwk = builder().x509CertificateSha256Thumbprint(x5tS256).build()
|
||||
assertArrayEquals x5tS256, jwk.getX509CertificateSha256Thumbprint()
|
||||
assertEquals encoded, jwk.get(AbstractAsymmetricJwk.X5T_S256.getId())
|
||||
}
|
||||
|
@ -97,7 +97,7 @@ class AbstractAsymmetricJwkBuilderTest {
|
|||
Request<byte[]> request = new DefaultRequest(TestKeys.RS256.cert.getEncoded(), null, null)
|
||||
def x5tS256 = Jwks.HASH.SHA256.digest(request)
|
||||
def encoded = Encoders.BASE64URL.encode(x5tS256)
|
||||
def jwk = builder().setX509CertificateChain(CHAIN).withX509Sha256Thumbprint(true).build()
|
||||
def jwk = builder().x509CertificateChain(CHAIN).withX509Sha256Thumbprint(true).build()
|
||||
assertArrayEquals x5tS256, jwk.getX509CertificateSha256Thumbprint()
|
||||
assertEquals encoded, jwk.get(AbstractAsymmetricJwk.X5T_S256.getId())
|
||||
}
|
||||
|
@ -107,11 +107,11 @@ class AbstractAsymmetricJwkBuilderTest {
|
|||
def pair = TestKeys.ES256.pair
|
||||
|
||||
//start with a public key builder
|
||||
def builder = Jwks.builder().forKey(pair.public as ECPublicKey)
|
||||
def builder = Jwks.builder().key(pair.public as ECPublicKey)
|
||||
assertTrue builder instanceof AbstractAsymmetricJwkBuilder.DefaultEcPublicJwkBuilder
|
||||
|
||||
//applying the private key turns it into a private key builder
|
||||
builder = builder.setPrivateKey(pair.private as ECPrivateKey)
|
||||
builder = builder.privateKey(pair.private as ECPrivateKey)
|
||||
assertTrue builder instanceof AbstractAsymmetricJwkBuilder.DefaultEcPrivateJwkBuilder
|
||||
|
||||
//building creates a private jwk:
|
||||
|
|
|
@ -83,7 +83,7 @@ class AbstractEcJwkFactoryTest {
|
|||
|
||||
@Test
|
||||
void testAddSamePointDoublesIt() {
|
||||
def pair = Jwts.SIG.ES256.keyPairBuilder().build()
|
||||
def pair = Jwts.SIG.ES256.keyPair().build()
|
||||
def pub = pair.getPublic() as ECPublicKey
|
||||
|
||||
def spec = pub.getParams()
|
||||
|
@ -98,7 +98,7 @@ class AbstractEcJwkFactoryTest {
|
|||
@Test
|
||||
void testDerivePublicFails() {
|
||||
|
||||
def pair = Jwts.SIG.ES256.keyPairBuilder().build()
|
||||
def pair = Jwts.SIG.ES256.keyPair().build()
|
||||
def priv = pair.getPrivate() as ECPrivateKey
|
||||
|
||||
final def context = new DefaultJwkContext(DefaultEcPrivateJwk.FIELDS)
|
||||
|
|
|
@ -32,7 +32,7 @@ class AbstractJwkBuilderTest {
|
|||
private static final SecretKey SKEY = TestKeys.A256GCM
|
||||
|
||||
private static AbstractJwkBuilder<SecretKey, SecretJwk, AbstractJwkBuilder> builder() {
|
||||
return (AbstractJwkBuilder) Jwks.builder().forKey(SKEY)
|
||||
return (AbstractJwkBuilder) Jwks.builder().key(SKEY)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -55,20 +55,20 @@ class AbstractJwkBuilderTest {
|
|||
def foo = UUID.randomUUID()
|
||||
def bar = UUID.randomUUID().toString() //different type
|
||||
def m = [foo: foo, bar: bar]
|
||||
def jwk = builder().set(m).build()
|
||||
def jwk = builder().add(m).build()
|
||||
assertEquals foo, jwk.foo
|
||||
assertEquals bar, jwk.bar
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRemove() {
|
||||
def jwk = builder().set('foo', 'bar').delete('foo').build() as Jwk
|
||||
def jwk = builder().add('foo', 'bar').delete('foo').build() as Jwk
|
||||
assertNull jwk.get('foo')
|
||||
}
|
||||
|
||||
@Test
|
||||
void testClear() {
|
||||
def builder = builder().set('foo', 'bar')
|
||||
def builder = builder().add('foo', 'bar')
|
||||
builder.clear()
|
||||
def jwk = builder.build()
|
||||
assertNull jwk.get('foo')
|
||||
|
@ -76,14 +76,14 @@ class AbstractJwkBuilderTest {
|
|||
|
||||
@Test
|
||||
void testEmpty() {
|
||||
def jwk = builder().set('foo', 'bar').empty().build() as Jwk
|
||||
def jwk = builder().add('foo', 'bar').empty().build() as Jwk
|
||||
assertNull jwk.get('foo')
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAlgorithm() {
|
||||
def alg = 'someAlgorithm'
|
||||
def jwk = builder().setAlgorithm(alg).build()
|
||||
def jwk = builder().algorithm(alg).build()
|
||||
assertEquals alg, jwk.getAlgorithm()
|
||||
assertEquals alg, jwk.alg //test raw get via JWA member id
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ class AbstractJwkBuilderTest {
|
|||
@Test
|
||||
void testAlgorithmByPut() {
|
||||
def alg = 'someAlgorithm'
|
||||
def jwk = builder().set('alg', alg).build() //ensure direct put still is handled properly
|
||||
def jwk = builder().add('alg', alg).build() //ensure direct put still is handled properly
|
||||
assertEquals alg, jwk.getAlgorithm()
|
||||
assertEquals alg, jwk.alg //test raw get via JWA member id
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ class AbstractJwkBuilderTest {
|
|||
@Test
|
||||
void testId() {
|
||||
def kid = UUID.randomUUID().toString()
|
||||
def jwk = builder().setId(kid).build()
|
||||
def jwk = builder().id(kid).build()
|
||||
assertEquals kid, jwk.getId()
|
||||
assertEquals kid, jwk.kid //test raw get via JWA member id
|
||||
}
|
||||
|
@ -107,7 +107,7 @@ class AbstractJwkBuilderTest {
|
|||
@Test
|
||||
void testIdByPut() {
|
||||
def kid = UUID.randomUUID().toString()
|
||||
def jwk = builder().set('kid', kid).build()
|
||||
def jwk = builder().add('kid', kid).build()
|
||||
assertEquals kid, jwk.getId()
|
||||
assertEquals kid, jwk.kid //test raw get via JWA member id
|
||||
}
|
||||
|
@ -117,7 +117,7 @@ class AbstractJwkBuilderTest {
|
|||
def a = UUID.randomUUID().toString()
|
||||
def b = UUID.randomUUID().toString()
|
||||
def set = [a, b] as Set<String>
|
||||
def jwk = builder().setOperations(set).build()
|
||||
def jwk = builder().operations(set).build()
|
||||
assertEquals set, jwk.getOperations()
|
||||
assertEquals set, jwk.key_ops
|
||||
}
|
||||
|
@ -127,7 +127,7 @@ class AbstractJwkBuilderTest {
|
|||
def a = UUID.randomUUID().toString()
|
||||
def b = UUID.randomUUID().toString()
|
||||
def set = [a, b] as Set<String>
|
||||
def jwk = builder().set('key_ops', set).build()
|
||||
def jwk = builder().add('key_ops', set).build()
|
||||
assertEquals set, jwk.getOperations()
|
||||
assertEquals set, jwk.key_ops
|
||||
}
|
||||
|
@ -137,7 +137,7 @@ class AbstractJwkBuilderTest {
|
|||
void testOperationsByPutSingleValue() {
|
||||
def a = UUID.randomUUID().toString()
|
||||
def set = [a] as Set<String>
|
||||
def jwk = builder().set('key_ops', a).build() // <-- put uses single raw value, not a set
|
||||
def jwk = builder().add('key_ops', a).build() // <-- put uses single raw value, not a set
|
||||
assertEquals set, jwk.getOperations() // <-- still get a set
|
||||
assertEquals set, jwk.key_ops // <-- still get a set
|
||||
}
|
||||
|
@ -145,7 +145,7 @@ class AbstractJwkBuilderTest {
|
|||
@Test
|
||||
void testProvider() {
|
||||
def provider = Providers.findBouncyCastle(Conditions.TRUE)
|
||||
def jwk = builder().setProvider(provider).build()
|
||||
def jwk = builder().provider(provider).build()
|
||||
assertEquals 'oct', jwk.getType()
|
||||
}
|
||||
|
||||
|
|
|
@ -131,13 +131,13 @@ class AbstractJwkTest {
|
|||
|
||||
@Test
|
||||
void testPrivateJwkToStringHasRedactedValues() {
|
||||
def secretJwk = Jwks.builder().forKey(TestKeys.HS256).build()
|
||||
def secretJwk = Jwks.builder().key(TestKeys.HS256).build()
|
||||
assertTrue secretJwk.toString().contains('k=<redacted>')
|
||||
|
||||
def ecPrivJwk = Jwks.builder().forKey(TestKeys.ES256.pair.private).build()
|
||||
def ecPrivJwk = Jwks.builder().key(TestKeys.ES256.pair.private).build()
|
||||
assertTrue ecPrivJwk.toString().contains('d=<redacted>')
|
||||
|
||||
def rsaPrivJwk = Jwks.builder().forKey(TestKeys.RS256.pair.private).build()
|
||||
def rsaPrivJwk = Jwks.builder().key(TestKeys.RS256.pair.private).build()
|
||||
String s = 'd=<redacted>, p=<redacted>, q=<redacted>, dp=<redacted>, dq=<redacted>, qi=<redacted>'
|
||||
assertTrue rsaPrivJwk.toString().contains(s)
|
||||
}
|
||||
|
@ -146,20 +146,20 @@ class AbstractJwkTest {
|
|||
void testPrivateJwkHashCode() {
|
||||
assertEquals jwk.hashCode(), jwk.@context.hashCode()
|
||||
|
||||
def secretJwk1 = Jwks.builder().forKey(TestKeys.HS256).set('hello', 'world').build()
|
||||
def secretJwk2 = Jwks.builder().forKey(TestKeys.HS256).set('hello', 'world').build()
|
||||
def secretJwk1 = Jwks.builder().key(TestKeys.HS256).add('hello', 'world').build()
|
||||
def secretJwk2 = Jwks.builder().key(TestKeys.HS256).add('hello', 'world').build()
|
||||
assertEquals secretJwk1.hashCode(), secretJwk1.@context.hashCode()
|
||||
assertEquals secretJwk2.hashCode(), secretJwk2.@context.hashCode()
|
||||
assertEquals secretJwk1.hashCode(), secretJwk2.hashCode()
|
||||
|
||||
def ecPrivJwk1 = Jwks.builder().forKey(TestKeys.ES256.pair.private).set('hello', 'ecworld').build()
|
||||
def ecPrivJwk2 = Jwks.builder().forKey(TestKeys.ES256.pair.private).set('hello', 'ecworld').build()
|
||||
def ecPrivJwk1 = Jwks.builder().key(TestKeys.ES256.pair.private).add('hello', 'ecworld').build()
|
||||
def ecPrivJwk2 = Jwks.builder().key(TestKeys.ES256.pair.private).add('hello', 'ecworld').build()
|
||||
assertEquals ecPrivJwk1.hashCode(), ecPrivJwk2.hashCode()
|
||||
assertEquals ecPrivJwk1.hashCode(), ecPrivJwk1.@context.hashCode()
|
||||
assertEquals ecPrivJwk2.hashCode(), ecPrivJwk2.@context.hashCode()
|
||||
|
||||
def rsaPrivJwk1 = Jwks.builder().forKey(TestKeys.RS256.pair.private).set('hello', 'rsaworld').build()
|
||||
def rsaPrivJwk2 = Jwks.builder().forKey(TestKeys.RS256.pair.private).set('hello', 'rsaworld').build()
|
||||
def rsaPrivJwk1 = Jwks.builder().key(TestKeys.RS256.pair.private).add('hello', 'rsaworld').build()
|
||||
def rsaPrivJwk2 = Jwks.builder().key(TestKeys.RS256.pair.private).add('hello', 'rsaworld').build()
|
||||
assertEquals rsaPrivJwk1.hashCode(), rsaPrivJwk2.hashCode()
|
||||
assertEquals rsaPrivJwk1.hashCode(), rsaPrivJwk1.@context.hashCode()
|
||||
assertEquals rsaPrivJwk2.hashCode(), rsaPrivJwk2.@context.hashCode()
|
||||
|
|
|
@ -32,7 +32,7 @@ class AbstractSecureDigestAlgorithmTest {
|
|||
@Test
|
||||
void testSignAndVerifyWithExplicitProvider() {
|
||||
Provider provider = Security.getProvider('BC')
|
||||
def pair = Jwts.SIG.RS256.keyPairBuilder().build()
|
||||
def pair = Jwts.SIG.RS256.keyPair().build()
|
||||
byte[] data = 'foo'.getBytes(StandardCharsets.UTF_8)
|
||||
byte[] signature = Jwts.SIG.RS256.digest(new DefaultSecureRequest<byte[], PrivateKey>(data, provider, null, pair.getPrivate()))
|
||||
assertTrue Jwts.SIG.RS256.verify(new DefaultVerifySecureDigestRequest<PublicKey>(data, provider, null, pair.getPublic(), signature))
|
||||
|
@ -40,7 +40,7 @@ class AbstractSecureDigestAlgorithmTest {
|
|||
|
||||
@Test
|
||||
void testSignFailsWithAnExternalException() {
|
||||
def pair = Jwts.SIG.RS256.keyPairBuilder().build()
|
||||
def pair = Jwts.SIG.RS256.keyPair().build()
|
||||
def ise = new IllegalStateException('foo')
|
||||
def alg = new TestAbstractSecureDigestAlgorithm() {
|
||||
@Override
|
||||
|
@ -59,7 +59,7 @@ class AbstractSecureDigestAlgorithmTest {
|
|||
|
||||
@Test
|
||||
void testVerifyFailsWithExternalException() {
|
||||
def pair = Jwts.SIG.RS256.keyPairBuilder().build()
|
||||
def pair = Jwts.SIG.RS256.keyPair().build()
|
||||
def ise = new IllegalStateException('foo')
|
||||
def alg = new TestAbstractSecureDigestAlgorithm() {
|
||||
@Override
|
||||
|
|
|
@ -108,7 +108,7 @@ class AesAlgorithmTest {
|
|||
|
||||
def secureRandom = new SecureRandom()
|
||||
|
||||
def req = new DefaultAeadRequest('data'.getBytes(), null, secureRandom, alg.keyBuilder().build(), 'aad'.getBytes())
|
||||
def req = new DefaultAeadRequest('data'.getBytes(), null, secureRandom, alg.key().build(), 'aad'.getBytes())
|
||||
|
||||
def returnedSecureRandom = alg.ensureSecureRandom(req)
|
||||
|
||||
|
|
|
@ -49,8 +49,8 @@ class AesGcmKeyAlgorithmTest {
|
|||
def iv = new byte[12]
|
||||
Randoms.secureRandom().nextBytes(iv)
|
||||
|
||||
def kek = alg.keyBuilder().build()
|
||||
def cek = alg.keyBuilder().build()
|
||||
def kek = alg.key().build()
|
||||
def cek = alg.key().build()
|
||||
|
||||
final String jcaName = "AES/GCM/NoPadding"
|
||||
|
||||
|
@ -102,7 +102,7 @@ class AesGcmKeyAlgorithmTest {
|
|||
def cek = template.generateSecretKey(keyLength)
|
||||
def enc = new GcmAesAeadAlgorithm(keyLength) {
|
||||
@Override
|
||||
SecretKeyBuilder keyBuilder() {
|
||||
SecretKeyBuilder key() {
|
||||
return new FixedSecretKeyBuilder(cek)
|
||||
}
|
||||
}
|
||||
|
@ -140,7 +140,7 @@ class AesGcmKeyAlgorithmTest {
|
|||
def cek = template.generateSecretKey(keyLength)
|
||||
def enc = new GcmAesAeadAlgorithm(keyLength) {
|
||||
@Override
|
||||
SecretKeyBuilder keyBuilder() {
|
||||
SecretKeyBuilder key() {
|
||||
return new FixedSecretKeyBuilder(cek)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ class CurvesTest {
|
|||
@Test
|
||||
void testKeyPairBuilders() {
|
||||
Curves.VALUES.each {
|
||||
def pair = it.keyPairBuilder().build()
|
||||
def pair = it.keyPair().build()
|
||||
if (it instanceof ECCurve) {
|
||||
assertEquals ECCurve.KEY_PAIR_GENERATOR_JCA_NAME, pair.getPublic().getAlgorithm()
|
||||
assertEquals ECCurve.KEY_PAIR_GENERATOR_JCA_NAME, pair.getPrivate().getAlgorithm()
|
||||
|
|
|
@ -78,7 +78,7 @@ class DefaultCurveTest {
|
|||
|
||||
@Test
|
||||
void testKeyPairBuilder() {
|
||||
def builder = curve.keyPairBuilder()
|
||||
def builder = curve.keyPair()
|
||||
assertEquals 'bar', builder.jcaName //builder is an instanceof DefaultKeyPairBuilder
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ class DefaultJwkContextTest {
|
|||
void testX509Url() {
|
||||
def uri = URI.create('https://github.com/jwtk/jjwt')
|
||||
def ctx = new DefaultJwkContext()
|
||||
ctx.setX509Url(uri)
|
||||
ctx.x509Url(uri)
|
||||
assertEquals uri, ctx.getX509Url()
|
||||
assertEquals uri.toString(), ctx.get('x5u')
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ class DefaultJwkContextTest {
|
|||
void testX509CertificateChain() {
|
||||
def chain = TestKeys.RS256.chain
|
||||
def ctx = new DefaultJwkContext()
|
||||
ctx.setX509CertificateChain(chain)
|
||||
ctx.x509CertificateChain(chain)
|
||||
assertEquals chain, ctx.getX509CertificateChain()
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@ class DefaultJwkContextTest {
|
|||
void testX509CertificateSha1Thumbprint() {
|
||||
def thumbprint = Bytes.randomBits(128)
|
||||
def ctx = new DefaultJwkContext()
|
||||
ctx.setX509CertificateSha1Thumbprint(thumbprint)
|
||||
ctx.x509CertificateSha1Thumbprint(thumbprint)
|
||||
assertArrayEquals thumbprint, ctx.getX509CertificateSha1Thumbprint()
|
||||
assertEquals Encoders.BASE64URL.encode(thumbprint), ctx.get('x5t')
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ class DefaultJwkContextTest {
|
|||
void testX509CertificateSha256Thumbprint() {
|
||||
def thumbprint = Bytes.randomBits(256)
|
||||
def ctx = new DefaultJwkContext()
|
||||
ctx.setX509CertificateSha256Thumbprint(thumbprint)
|
||||
ctx.x509CertificateSha256Thumbprint(thumbprint)
|
||||
assertArrayEquals thumbprint, ctx.getX509CertificateSha256Thumbprint()
|
||||
assertEquals Encoders.BASE64URL.encode(thumbprint), ctx.get('x5t#S256')
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ class DefaultJwkParserBuilderTest {
|
|||
@Test
|
||||
void testProvider() {
|
||||
def provider = createMock(Provider)
|
||||
def parser = Jwks.parser().setProvider(provider).build() as DefaultJwkParser
|
||||
def parser = Jwks.parser().provider(provider).build() as DefaultJwkParser
|
||||
assertSame provider, parser.provider
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ class DefaultJwkParserTest {
|
|||
def serializer = Services.loadFirst(Serializer)
|
||||
for (Key key : keys) {
|
||||
//noinspection GroovyAssignabilityCheck
|
||||
def jwk = Jwks.builder().forKey(key).build()
|
||||
def jwk = Jwks.builder().key(key).build()
|
||||
def data = serializer.serialize(jwk)
|
||||
String json = new String(data, StandardCharsets.UTF_8)
|
||||
def parsed = Jwks.parser().build().parse(json)
|
||||
|
@ -75,10 +75,10 @@ class DefaultJwkParserTest {
|
|||
|
||||
for (Key key : keys) {
|
||||
//noinspection GroovyAssignabilityCheck
|
||||
def jwk = Jwks.builder().forKey(key).build()
|
||||
def jwk = Jwks.builder().key(key).build()
|
||||
def data = serializer.serialize(jwk)
|
||||
String json = new String(data, StandardCharsets.UTF_8)
|
||||
def parsed = Jwks.parser().setProvider(provider).build().parse(json)
|
||||
def parsed = Jwks.parser().provider(provider).build().parse(json)
|
||||
assertEquals jwk, parsed
|
||||
assertSame provider, parsed.@context.@provider
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ class DefaultMacAlgorithmTest {
|
|||
*/
|
||||
@Test
|
||||
void testWithPasswordSpec() {
|
||||
def password = Keys.forPassword(passwordChars)
|
||||
def password = Keys.password(passwordChars)
|
||||
try {
|
||||
newAlg().digest(request(password))
|
||||
} catch (InvalidKeyException expected) {
|
||||
|
@ -98,16 +98,16 @@ class DefaultMacAlgorithmTest {
|
|||
@Test(expected = SecurityException)
|
||||
void testKeyGeneratorNoSuchAlgorithm() {
|
||||
DefaultMacAlgorithm alg = new DefaultMacAlgorithm('HS256', 'foo', 256)
|
||||
alg.keyBuilder().build()
|
||||
alg.key().build()
|
||||
}
|
||||
|
||||
@Test
|
||||
void testKeyGeneratorKeyLength() {
|
||||
DefaultMacAlgorithm alg = new DefaultMacAlgorithm('HS256', 'HmacSHA256', 256)
|
||||
assertEquals 256, alg.keyBuilder().build().getEncoded().length * Byte.SIZE
|
||||
assertEquals 256, alg.key().build().getEncoded().length * Byte.SIZE
|
||||
|
||||
alg = new DefaultMacAlgorithm('A128CBC-HS256', 'HmacSHA256', 128)
|
||||
assertEquals 128, alg.keyBuilder().build().getEncoded().length * Byte.SIZE
|
||||
assertEquals 128, alg.key().build().getEncoded().length * Byte.SIZE
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException)
|
||||
|
@ -146,7 +146,7 @@ class DefaultMacAlgorithmTest {
|
|||
String msg = 'The signing key\'s size is 192 bits which is not secure enough for the HS256 algorithm. ' +
|
||||
'The JWT JWA Specification (RFC 7518, Section 3.2) states that keys used with HS256 MUST have a ' +
|
||||
'size >= 256 bits (the key size must be greater than or equal to the hash output size). ' +
|
||||
'Consider using the Jwts.SIG.HS256.keyBuilder() method to create a key guaranteed ' +
|
||||
'Consider using the Jwts.SIG.HS256.key() builder to create a key guaranteed ' +
|
||||
'to be secure enough for HS256. See https://tools.ietf.org/html/rfc7518#section-3.2 for more ' +
|
||||
'information.'
|
||||
assertEquals msg, expected.getMessage()
|
||||
|
|
|
@ -32,7 +32,7 @@ class DefaultRsaKeyAlgorithmTest {
|
|||
|
||||
@Test
|
||||
void testValidateNonRSAKey() {
|
||||
SecretKey key = Jwts.KEY.A128KW.keyBuilder().build()
|
||||
SecretKey key = Jwts.KEY.A128KW.key().build()
|
||||
for (DefaultRsaKeyAlgorithm alg : algs) {
|
||||
// if RSAKey interface isn't exposed (e.g. PKCS11 or HSM), don't error:
|
||||
alg.validate(key, true)
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue